Nico's lab

🔭 🎶 🕺

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 bufferAction
:find fileOpen file
:find directoryExplore directory
:find . for root directory
:findExplore current file’s directory
<C-6>Swap with previous buffer
<C-o>Jump back
<C-i>Jump next
:splitSplit horizontally
:vsplitSplit vertically
<C-w> directionFocus nearest window
:bwClose buffer
:qClose window
:help anythingOpens related help in a new window. Often more efficient than searching the internet!
In netrwAction
iChange layout
list > details > ls > tree
%New file
dNew directory
RRename file
DDelete file
With pluginsAction
<C-p>Open fzf
<C-direction>Focus nearest window or tmux pane
:Rg textOrRegexRecursive text search with ripgrep