How should I rename my current file in Vim?
For example:
person.html_erb_spec.rb
person
:w newname
- to create a copy.:e#
.:!rm oldname
.On Windows, the optional 3rd step changes a little:
:!del oldname
.There's a sightly larger plugin called vim-eunuch by Tim Pope that includes a rename function as well as some other goodies (delete, find, save all, chmod, sudo edit, ...).
To rename a file in vim-eunuch:
:Move filename.ext
Compared to rename.vim:
:rename[!] filename.ext
Saves a few keystrokes :)
:sav new_name
:!rm <C-R># // or !del <C-R># for windows
control + R, # will instantly expand to an alternate-file (previously edited path in current window) before pressing Enter. That allows us to review what exactly we're going to delete.
Using pipe |
in such a case is not secure, because if sav
fails for any reason, #
will still point to another place (or to nothing). That means !rm #
or delete(expand(#))
may delete completely different file!
So do it by hand carefully or use good script (they are mentioned in many answers here).
...or try build a function/command/script yourself. Start from sth simple like:
command! -nargs=1 Rename saveas <args> | call delete(expand('#')) | bd #
after vimrc reload, just type :Rename new_filename
.
What is the problem with this command?
Security test 1: What does:Rename
without argument?
Yes, it deletes file hidden in '#' !
Solution: you can use eg. conditions or try
statement like that:
command! -nargs=1 Rename try | saveas <args> | call delete(expand('#')) | bd # | endtry
Security test 1:
:Rename
(without argument) will throw an error:
E471: Argument required
Security test 2: What if the name will be the same like previous one?
Security test 3: What if the file will be in different location than your actual?
Fix it yourself. For readability you can write it in this manner:
function! s:localscript_name(name):
try
execute 'saveas ' . a:name
...
endtry
endfunction
command! -nargs=1 Rename call s:localscript_name(<f-args>)
notes
!rm #
is better than !rm old_name
-> you don't need remember the old name
!rm <C-R>#
is better than !rm #
when do it by hand -> you will see what you actually remove (safety reason)
!rm
is generally not very secure... mv
to a trash location is better
call delete(expand('#'))
is better than shell command (OS agnostic) but longer to type and impossible to use control + R
try | code1 | code2 | tryend
-> when error occurs while code1, don't run code2
:sav
(or :saveas
) is equivalent to :f new_name | w
- see file_f - and preserves undo history
expand('%:p')
gives whole path of your location (%
) or location of alternate file (#
)
I'm doing it with NERDTree plugin:
:NERDTreeFind
then press m
To rename you can choose (m)ove the current node
and change file name. Also there are options like delete, copy, move, etc...
I'd recommend :Rename
from tpope's eunuch for this.
It also includes a bunch of other handy commands.
The Rename command is defined as follows therein currently (check the repo for any updates!):
command! -bar -nargs=1 -bang -complete=file Rename :
\ let s:file = expand('%:p') |
\ setlocal modified |
\ keepalt saveas<bang> <args> |
\ if s:file !=# expand('%:p') |
\ call delete(s:file) |
\ endif |
\ unlet s:file
Vim does have a rename
function, but unfortunately it does not retain the history.
The easiest OS agnostic way to rename a file without losing the history would be:
:saveas new_file_name
:call delete(expand('#:p'))
expand('#:p')
returns the full path of the older file.
Use :bd #
if you also want to delete the older file from the buffer list.
If you want to use a quick command to rename the file, add a new file under ~/.vim/plugin with the following contents:
function! s:rename_file(new_file_path)
execute 'saveas ' . a:new_file_path
call delete(expand('#:p'))
bd #
endfunction
command! -nargs=1 -complete=file Rename call <SID>rename_file(<f-args>)
The command Rename
will help you to quickly rename a file.