How should I rename my current file in Vim?
For example:
- I am editing
person.html_erb_spec.rb - I would like it renamed to
person.haml_spec.rb - I would like to continue editing
person.haml_spec.rb
How would I go about doing this, elegantly?
The command is called :saveas, but unfortunately it will not delete your old file, you'll have to do that manually. see :help saveas for more info.
EDIT:
Most vim installations have an integrated file explorer, which you can use for such operations. Try :Explore in command mode (I would actually map that to a function key, it's very handy). You can rename files with R or delete them with D, for example. But pressing <F1> in the explorer will give you a better overview.
If you use git and already have the tpope's plugin fugitive.vim then simply:
:GRename newname This will:
If your file was not yet added to a git repo then first add it:
:Gwrite If you'd like to move the file to a new location, use :GMove
:GMove path/to/newfile :Gmove requires the relative path for the new filename. A nice way to do this is to type :Gmove <ctrl-r>% which appends the current path/filename.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...
There's a little plugin that lets you do this.
Program Files (x86). Any time this directory needs to be worked with it needs to be wrapped in quotes. Which is uh, a lot.:w newname - to create a copy.:e#.:!rm oldname.On Windows, the optional 3rd step changes a little:
:!del oldname.:f newname 2) save it :w 3) (optionally) !rm oldname. The advantage is that your undo history is preserved.:saveas is better in that regard, @rampion -- and does what @kynan wrote.# represent in :e#?: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 (#)
You can also do it using netrw
The explore command opens up netrw in the directory of the open file
:E Move the cursor over the file you want to rename:
R Type in the new name, press enter, press y.
If the file is already saved:
:!mv {file location} {new file location} :e {new file location} Example:
:!mv src/test/scala/myFile.scala src/test/scala/myNewFile.scala :e src/test/scala/myNewFile.scala Permission Requirements:
:!sudo mv src/test/scala/myFile.scala src/test/scala/myNewFile.scala Save As:
:!mv {file location} {save_as file location} :w :e {save_as file location}
For Windows Unverified
:!move {file location} {new file location} :e {new file location} 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 sav person.haml_spec.rb | call delete(expand('#')) call delete(expand('#'))There’s a function in Gary Bernhardt’s .vimrc that handles this.
function! RenameFile() let old_name = expand('%') let new_name = input('New file name: ', expand('%'), 'file') if new_name != '' && new_name != old_name exec ':saveas ' . new_name exec ':silent !rm ' . old_name redraw! endif endfunction map <leader>n :call RenameFile()<cr> 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.
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 :)
How about this (improved by Jake's suggestion):
:exe "!mv % newfilename" | e newfilename :exe "!mv % newfilename" | e newfilenameYou can also use :f followed by :w
I don't know if this is the "easiest" method, but assuming you've already saved your file (:w) I would invoke the shell (:sh) and do a simple cp foo foo.bak To go back to editor use Ctrl-D/Exit. Useful list of vi editor commands on this link
This little script isn't perfect (the extra carriage-return you have to press) but it get's the job done.
function Rename() let new_file_name = input('New filename: ') let full_path_current_file = expand("%:p") let new_full_path = expand("%:p:h")."/".new_file_name bd execute "!mv ".full_path_current_file." ".new_full_path execute "e ".new_full_path endfunction command! Rename :call Rename() nmap RN :Rename<CR>