How to simply use vim across multiple files
November 2, 2019
Vim provides its own unique way to edit code. Discerning what makes it really different helps a lot figuring out why so many developers love vim. This article attempts to summarize these core concepts and provides a reasonable set of tips for an efficient use of vim across multiple files.
Nowadays, developers that are invited to vim are being told to install all these cool plugins. Although most of these are very good, I believe plugins make vim’s actual learning curve steeper than it should be. Some plugins disguise vim into vscode, reminding features like file explorer toolbar or tabs.
Because vim is harder to grasp when beginning, limiting the number of plugins is crucial. With its core concepts only, vim already comes with great power and great responsibility. People probably don’t accept this well enough, at least I didn’t and my resulting experience of vim has been years of trying to stick to it and falling back to another editor (or IDE). It’s time to transform this vim hassle into vim power!
Buffers
First of all, it’s time to forget about tabs. In vim, tabs are a power-user feature that may be useful for those who already master buffers and in very specific scenario. Buffers alone are more than enough. Also, no plugin will put vscode’s tabs in vim.
Experienced vim users often refer to navigating through files as flowing through buffers. Indeed, when you need to access a piece of code, you just place your cursor in it to explore or edit it. There is no need to care about which buffer is open and where it is. We’ll see that with just a few commands we are able to keep as many buffers open as we like while still keep editing efficiently!
Opening files
:find path/file
opens path/file
. :find
supports quick file search if we enable it, so let’s run / add to .vimrc the following commands in order to get comfortable:
set path+=*
set wildmenu
" Optionally ignore bulky folders:
set wildignore+=*/node_modules/*
We’ve just set up quick file search! Tab completion now finds files deep in current working directory. For example, :find foobar<Tab>
or :find *.ht<Tab>
will both find some/nested/dir/foobarbaz.html
. If multiple files match, the wildmenu we just enabled appears on top on the command line and more <Tab>
presses rotate across matches.
Explore files
Running :find
on a folder opens netrw, a simple yet efficient file explorer. It provides a tree view if you hit l
a few times! You can also create a new file by hitting %
, delete with D
and rename with R
. Using :find
alone goes to current file’s directory and :find .
goes to current working directory.
Navigating across buffers
A developer’s workflow often involves going back and forth in a code base. Although :find
or fzf are great for quickly opening files, we can go faster once they have already been opened in buffers.
- Ctrl+6 swaps to last opened buffer
- Ctrl+o moves the cursor to the previous location it last jumped from
- Ctrl+i moves the cursor to the next jump
The two latter commands take advantage of the jumplist which contains all cursor jumps, including inside the same buffer. This is much more powerful than just "tab switching" in other editors as you can extremely quicky jump back and forth more precise contexts. Although they are precise, they might take you more time than a simple Ctrl-6
swap-back or than moving away with a quick :find
or fzf.
Closing buffers
It won’t cause any trouble to keep any number of buffers open and it is often recommended to keep them open. However, when we mainly rely on Ctrl-o
/Ctrl-i
to navigate, we want to keep the jumplist history clean. So if, for example, a file has been opened by mistake, all what is needed is :bw
.
Windows
Windows are viewports on a buffer. A single one takes all vim’s space when launching the editor. Some commands like :help anything
spawn a new window. :q
closes current window or the editor when no window remain.
Windows allow to split the editor, which can be done manually with :split
and :vsplit
. Window-controlling commands are prefixed by <C-w>
. For example, <C-w>
followed by a direction focuses the nearest window in that direction.
As I don’t need editor splits that much, I won’t get more into details. However I run vim from an instance of tmux which allows to seamlessly navigate across split terminals and vim windows, i.e. with the same shortcut: <C>
plus a direction. tmux allows much more and I will write a dedicated article about it.
That’s all for file navigation in vim, keeping it simple and mouse-free! I still recommend to look into fzf for fuzzy finding; I bound it to <C-p>
to speed up file jumps. I also recommend to install ripgrep on your system for recursive directory text searches. fzf.vim automatically picks up on ripgrep and you just need to run :Rg textOrRegex
to start using it.
Cheatsheet (tl;dr)
In buffer | Action |
---|---|
:find file | Open file |
:find directory | Explore directory :find . for root directory |
:find | Explore current file’s directory |
<C-6> | Swap with previous buffer |
<C-o> | Jump back |
<C-i> | Jump next |
:split | Split horizontally |
:vsplit | Split vertically |
<C-w> direction | Focus nearest window |
:bw | Close buffer |
:q | Close window |
:help anything | Opens related help in a new window. Often more efficient than searching the internet! |
In netrw | Action |
---|---|
i | Change layout list > details > ls > tree |
% | New file |
d | New directory |
R | Rename file |
D | Delete file |