I'm brand new in the Vim game, and I'm looking for the best tips and shorcuts to manage multiple files projects.
I saw people on the internet having a window with all the directory they have in there projects, and I'm really interested to find how they do that.
So feel free to put all your tips here.
Thanks
One tip I can give you on making changes in a bunch of files is (based on vimcasts):
Let' say you have many markdown files and want to substitute the word ISSUE for SOLVED...
vim *.md
At this point you have all markdown files as arguments...
:args
So you have the argdo command, but in order to use it you have to set the hidden option (it allows you to go to the next file without saving the current one)
:set hidden
Now
:argdo %s/ISSUE/SOLVED/ge
The g flag makes the substitution in all occurrences at each line
the e flag makes vim ignore files where the pattern does not appear
Another good thing is avoiding messeges during substitution of each file, we can add silent at the beggining
:silent argdo %s/ISSUE/SOLVED/ge
If you realize you made a mistake
:silent argdo edit!
Because the command edit! with exclamation makes the file get back to its original state
If you are sure you made it all correct
:argdo update
There are tons of good tips about dealing with many files on vim, you can visit the vimcasts original tip here.
More about the arglist here.
Another great tool to combine with vim is FZF, you can see a good video about it here.
When you have a couple of files opened you can also use the buffer list easily with this mapping (on your ~/.vimrc or ~/.cofig/nvim/init.vim)
" list buffers and jump to a chosen one
nnoremap <Leader>b :buffers<CR>:b<Space>
A shortcut you can use to get back to the last edited file is Ctrl-6.
In order to open you vim on the last edited file add this alias to your ~/.bashrc or ~/.zshrc
alias lvim='vim -c "normal '\''0"'
Open a new terminal and run
lvim
This is a total newbie vim question. Apologies for the basic-ness involved.
I need to open a lot of files. The :edit <file-name> command seems to open a file and I also see a filename auto-complete feature, which searches for all similar file names in the path. But I don't know how to choose one of those suggestions quickly without writing the whole file name.
set wildmenu
enables the "wildmenu" where you navigate with <Tab> and <S-Tab>, enter a subdirectory with <Down> and select a file with <CR>.
See :help 'wildmenu' and :help 'wildmode'.
Note that :edit can only open one file. If you want to open multiple files at once, use :args models/*.php.
Another, more familiar, way to open files is to use the built-in netrw:
:Explore
See :help netrw for more info.
Sounds like you might enjoy the conveniences of the rather smashing CTRL-P plugin. https://github.com/kien/ctrlp.vim
It will allow you to type any substring of the filename to narrow the available files down. You can mark multiple files for opening.
For instance, how do I open a file I am going to use as the template for a file, but open it up as an unsaved buffer maybe? I don't know what methods I should use but I want to be able to save it right after as the file it's supposed to be.
My situation is for a jekyll blog where I have a basic post template and want to open that in vim from the command line so I can begin the post and then :w *filename.md*
Use the saveas command. Assuming you have a template for posts named template.md, open template.md, make some edits, then instead of using :w, do :sav newPost.md.
No need to switch buffers: now your buffer will contain the file newPost.md, and template.md will remain unchanged on the filesystem.
One method is to use the :read command or :r for short. e.g. :r template.md to read in the contents of template.md into the current buffer.
Pros:
Can read in multiple templates
Any buffer can be used, including unsaved or even a scratch buffer
Do not have to worry about saving over the template.md file on accident
Can be combined with the :! method to read in the output of a shell command. e.g. :r!ls
Use a range with :r to read in a template at a specific point in the buffer. e.g. :10r template.md will read in template.md after line number 10.
Cons:
May have an extra blank line. This can be easily deleted via :0d_ or whatever your favorite method to delete a line.
Example workflow:
create buffer and read in template
:new
:r template.md|0d_
edit buffer
save buffer
:w a-great-new-file.md
For more help see:
:h :r
:h :r!
:h :range
$ vim template.md
(edit)
:saveas filename.md
or
$ cp template.md filename.md && vim filename.md
or… I'm not sure I understand your problem.
The normal workflow is to open a template and "Save As…". In Vim and every other editor. What's wrong with that?
Or are you looking for a templating or snippet-expansion plugin?
I would like to access recent files that I had opened and then closed in GVim. I open and close GVim frequently. I would like to access recent files from previous sessions as well.
Does GVim store recent files somewhere as Word and many other desktop apps store? How to access them?
At least terminal vim stores the previous ten files into ~/.viminfo in the filemarks section. You can use '0, '1, '2, ... '9 to jump among them.
(Probably only useful for '0 to get back to the last file you were editing, unless your memory is stronger than mine.)
You can also use the :browse oldfiles command to get a menu with numbers.
The best way that I use is
:browse oldfiles
Easiest way on vim.
There is mru.vim, which adds the :MRU command.
Very late answer here ... expounding on #sarnolds answer - You can view the file history with the oldfiles command #see :h oldfiles or :h viminfo
:oldfiles
Furthermore, you can have fine-grained file management with views and sessions ... #see :h mkview and :h mksession for specifics ...
Use :bro ol then press the number that corresponds to the file you want to open.
There is an Swiss knife of file switching CtrlP plugin, which is also part of janus distributive. It has :CtrlPMRU command with smart lookup among recently used files.
Note:
CtrlP maintains its own list of most recent used files in g:ctrlp_cache_dir."mru/cache.txt". It is not reusing viminfo (set viminfo?) which contains a list of file marks. This is useful if you want to clear this list.
Adding my 2 cents here because fzf was was not mentioned in earlier answers, which is such a wonderful tool:
fzf.vim has a :History command that lets you search the most recent used files in a fuzzy and search while you type manner.
I customize the (default) behavior of this command by not letting fzf reorder the search results list to the best match: I want the order of all matching filenames to keep being the order in which these files were last used.
To accomplish this customization, I added the following in my .vimrc to override the default History command defined by the fzf.vim plugin:
command! -bang -nargs=* History
\ call fzf#vim#history({'options': '--no-sort'})
EDIT:
Currently I'm using a neovim only plugin telescope.nvim which is very similar to fzf.vim, it has the command :Telescope old_files. And it can use the fzf algorithm as a sorting algorithm in the backend (which is currently recommended over the default sorter).
It looks a bit nicer, but can be a bit slower depending on the context. It is not as mature as fzf, but to me easier to customize, it is all lua script.
If you are a neovim only user, definitely worth checking out imho.
MRU has lot of features as explained here: http://www.thegeekstuff.com/2009/08/vim-editor-how-to-setup-most-recently-used-documents-features-using-mru-plugin/
The CtrlP plugin lets you search through your recently used files as well as files in the current directory with this command:
nnoremap <c-p> :CtrlPMixed<cr>
This saves you the hassle of having to deal with built in Vim commands and the MRU plugin, neither of which let you do fuzzy file searching, which is critical when working on larger projects.
You might be able to access the list from the command line with:
grep '^>' ~/.viminfo|cut -c3-|sed 's,~,'"$HOME"','
Explanation:
grep '^>' ~/.viminfo #find the list of recent files
cut -c3- #remove the first 2 characters
sed 's,~,'"$HOME"',' #replace ~ with absolute path
You could have a bash alias if you use this regularly
alias vim_mru="grep '^>' ~/.viminfo|cut -c3-|sed 's,~,'\"$HOME\"','"
As seen in the comments here (http://stackoverflow.com/questions/571955/undo-close-tab-in-vim), your file is probably still open in a buffer:
:ls " get the buffer number
:tabnew +Nbuf " where N is the buffer number
For example you can reopen the third buffer in a new tab (use :e instead if you don't use tabs):
:tabnew +3buf
:ls to list recent files with buffer number on left-hand column.
Then do :b{buffer-number} to jump there.
Example:
:ls shows list of files. I want to jump to third-last file I visited.
:b3 will take me there.
For faster searching, map :ls to something, e.g. <Leader>. in your .vimrc file.
One more plugin that let's you choose file from the list of last modified ones is staritfy. It replaces your start screen with a list of most recently modified files. You can always open this page later using :Startify command.
Also you can go back with ctrl+O.
I have two search/replace commands that I find myself running in vim fairly often to clean up html code so I can copy/paste it online. The commands are:
:%s!<!\<!g
:%s!>!\>!g
I wanted a way I could map both of these commands to be run together ... I did some searching for how to use the :map commands in vimrc, however, I can't see how to combine the two lines into a single command that is run with a single keystroke (or a single sequence of strokes).
Thanks!
You can put the commands on a single line separated with a bar.
:%s!<!\<!g|%s!>!\>!g
But you'll have to escape it in the map command
:map <F3> :%s!<!\<!g\|:%s!>!\>!g<CR>
:TOhtml
will create a new buffer containing your previous buffer HTML-ized, including entity escaping (and syntax highlighting, if you had that enabled). See :h TOhtml for more information.
If you are using this search/replace pattern to HTML encode entities, you might want to check out the unimpaired plugin. Amongst other things, this provides shortcuts for encoding and decoding XML, URL and C strings.
:map <F3> :%s!<!\<!<cr>:%s!>!\>!<cr>
of course can be replaced with whatever key you wish
I've not tried it, but can you not put them on the same line separated by "<CR>"?