Vim, a text editor

I did not always like Vim.

I have dabbled in it for a long time until I started to really like it. Even when I started to overcome the hurdle of the arcane commands, Vim still lacked some handy functionality of the popular IDEs, so I always ended up going back to Atom, Brackets or PyCharm. These editors are powerful tools and are great in their own way, but they hog resources - their memory usage can be really frustrating on a lightweight machine.

Then one day I found this awesome configuration: https://github.com/amix/vimrc, which made me make the switch completely. It minimizes the learning curve and includes everything that is needed to use Vim as a full-fledged IDE. It is great as it is, but you can adjust things to your preferences easily.

Since then I have modified a lot of things and I removed some plugins - but I stayed hooked.

In this post I will share some of the features that I use most frequently. It won’t be a methodical tutorial, more like a collection of bits and pieces to encourage the usage of Vim, potentially with the above mentioned setup. Some of these features are built-in in the standard Vim, some of them are coming from plugins.

Note: if you are completely new to Vim, I suggest reading some of the articles listed on the bottom - there are very cool tutorials out there which will get you started quickly.

# Contents

# Searching files

  • Ctrl+F invokes a blazing fast fuzzy file finder (Ctrl+F is a custom mapping from Amix’s vimrc. It is CtrlP by default). This relies on the awesome CtrlP plugin. Type part of a filename and hit Return to open the selected file in the current tab, or hit Ctrl+t to open the file in a new tab. Use g+t to move between tabs. To speed up CtrPs loading time, you can set files and folders to ignore. For instance, you might want to ignore node_modules by putting this into your .vimrc:

    let g:ctrlp_custom_ignore = 'node_modules'.

    .pyc files and __pycache__ folders are also worth skipping. Further improvements can be achieved with this method.

    There is a promising alternative to CtrlP, which is fzf. I have yet to try it out - but it is supposed to be even faster than Ctrlp!

  • Ctrl+o jumps to the last item on the jumplist - places where your cursor have been. Ctrl+i or Tab jumps forward. (In insert mode, Ctrl+o does something totally different but useful: it lets you enter a command as you would in normal mode, then immediately takes you back to insert mode. Useful for saving the file and continuing typing, for instance.)
  • g+i in normal mode takes you to the place where you last inserted text.
  • `. (backtick then period) does the same, goes to the last place of insertion.

  • Ctrl+B lists your most recently used files so you don’t even have to look for them with Ctrl+F. This is a feature of the CtrlP plugin too. This is the one I use constanty, it saves a lot of effor and it also makes it easier to work on mulitple files at once without splitting the screen.

# Moving around in the current file

  • 45G goes to line 45.
  • GG goes to the end of the file, gg goes to the beginning of the file.
  • w goes to the end of the current word.
  • b goes to the beginning of the current word.
  • I goes to the beginning of the current line and enters INSERT mode.
  • A goes to the end of the current line and enters INSERT mode.
  • { goes to the beginning of the previous paragraph
  • } goes to the end of the next paragraph

# Searching for code

  • /foo then pressing Return searches for foo in the current file. Skip to the next search result with n, go back to the previous one with N. ?foo searches backwards.
  • ,Enter clears the search highlights.
  • * searches for the word currently under the cursor. # does the same but searches backwards.
  • g* (and g#) searches for the word, but includes substring results.
  • Vim has a search history, so you can press / and browse the search history with the up/down cursors.
  • :%s/foo/bar/g will replace foo with bar in the current file.
  • :%s/foo/bar/gc will search for foo and replace it with bar, but asks for confirmation before each action. Some colorschemes use the same background color for Search and IncSearch highlight, so it may be difficult to tell which search result is currently selected and is to be confirmed. To avoid this, you can specify to use different colors for incremental search results. I use these two lines in my .vimrc:

hi IncSearch term=reverse ctermfg=231 ctermbg=1 guifg=White guibg=DarkRed
hi Search term=reverse ctermfg=231 ctermbg=2 guifg=White guibg=DarkRed

  • :wa if I want to save changes made to all files (I have put command W w to my .vimrc to map W to w and save the current file even with capital w. This is because I often press W instead of w when saving, and I make Vim cry.
  • :Ack (mapped to ,g in this setup) if I want to find a piece of code. This relies on Ack, aka beyondgrep.
  • you can customise your Ack in your ~/.ackrc. You might want to put some directories and files in there to exclude from Ack search. For example:
--ignore-file=is:tags
--ignore-dir=__pycache__
--ignore-dir=node_modules
  • an alternative to Ack is ripgrep. It’s considerably faster than ack and has Vim support: see https://github.com/BurntSushi/ripgrep and https://github.com/jremmen/vim-ripgrep

It is likely that you want to reload the current file at some point - for instance, if you have changed git branches and the file you are working on has changed. You can reload the current file with :e.

If you want Vim to auto-reload files on change from a third party (for instance after having cheked out a different branch in Git), paste this into your .vimrc:

au CursorHold,CursorHoldI * checktime - if the cursor stops moving, vim checks if the current file has been edited and reloads it if needed (courtesy of Tom Hale from Stackexchange)

  • :vsplit or :vsp to split the screen vertically, if you want to work on multiple files on the screen.
  • :hsplit or :sp if you want to split the screen horizontally as well.
  • to move between panes, press Ctrl+w then the direction you want to move to.

# Code completion

You have read that right - code completion is totally possible in Vim! It doesn’t require any plugin. Just press Ctrl+n or Ctrl+p in insert mode to see a list of suggestions.

# Go to definition

One of the most powerful features, and one that I did not think Vim will have while I was using memory hoggers: jumping to the definition of a method or a class. It requires you to generate tags for your project - don’t worry, it won’t take long. The ctags tool is our friend who generates these tags (exhaustive info is at ctags wikipedia, and a great quick tutorial to ctags can be found here).

The ~/.ctags file can alter the behaviour of the ctags command. You can exclude file types and tag types as well. For instance, if you don’t want to treat python imports as tags (i.e. you want to see only the definition instead of imports):

$ echo --python-kinds=-i >> ~/.ctags - this excludes Python imports.

I have added these to be excluded:

--exclude=*.html
--exclude=*.js 
--exclude=*.pyc
--exclude=*site-packages*

The very last one excludes the site-packages directory which is present if you use virtual environments (don’t exclude them if you want to read the source code of the Python packages you use). To generate the tags file, run the following command in the project root:

$ ctags -R .

I recommend mapping ,l to go to the definition of the current selection. For this, add the following line to your .vimrc:

map <leader>l :exe "tag ". expand("<cword>")<CR>

That’s it - you should now be able to jump to the definition of a method or class by pressing , + l in NORMAL mode. It’s pretty mind-blowing! If you have any issues, make sure that Vim knows where to look for the tags file. It should work out of the box, but adding

set tags=./tags,tags;$HOME

to your .vimrc will ensure that Vim will look for the tags file in the current project directory, then every parent directory until it finds it, up until your home (courtesy of StackOveflow).

# Copy and paste

  • set mouse=a and your mouse highlights can be copied with y (d cuts) and pasted with p.
  • dd to cut a line, p to paste it.
  • in visual mode, select any text and yank it, cut it paste it as usual (y, d and p, respectively).

# Git

Vim and Git are good friends, partly thanks to the fugitive plugin.

  • :Gblame opens a pane with commit information (aka git blame). Switch to the git pane with Ctrl+w then the direction. There, you can select a commit and hit Return to see more details. As usual, use :q to exit or Ctrl+B to use the MRU buffer to go to the last file.
  • :GitGutterEnable (mapped to ,d in this setup) shows the changes made to the current file (aka gitgutter). Notice the green and red annotations next to the line numbers here:

# Distraction free mode

:Goyo (mapped to ,z) takes you to distraction-free mode thanks to the Goyo plugin. Useful for writing READMEs and blog posts.

# Appearance

The visuals are extremely configurable and there are tons of beautiful colorschemes to use. You can try out a colorscheme by :colorscheme <name-of-scheme>, the editor colors will instantly change.

If you are nostalgic about your ex-editor, you can have a similar theme set up. For instance, OneDark is a theme from Atom. I use the Peaksea theme.

I also find it useful to have a status line with a distinctive color based on the mode you are in. This saves some frustration because you always know which mode you are in, you always see the current color in the corner of your eye. The Lightline provides a great solution. Of course you can customise it to your needs.

For me, NORMAL mode is represented by bright green visual cues in the corners of the screen:

Visual mode is a bright orange bar:

And insert mode is a turquoise colored bar:

# Resources

There are plenty of resources online and the Vim community is very helpful. If you encounter an issue, most probably someone has already asked about it on forums and some pro user posted a useful answer on Vim fandom.

Even if a 4-week-plan can sound a bit much to learn the editor (though it’s a great approach if you have the persistence!), you should probably be comfortable using basic plugin-less Vim before you install anything - for this, type

$ vimtutor

in your command prompt and follow the instructions.

These commands can be helpful too:

  • :help - general help section. If you give it an argument, it will provide help about that topic.

  • :map - get information about the custom mappings that you or some plugin defined.

  • :hi - display the details of the current colorscheme. It may be useful if you want to customize a specific color.

A few articles that I found interesting:

Written on September 23, 2018

If you notice anything wrong with this post (factual error, rude tone, bad grammar, typo, etc.), and you feel like giving feedback, please do so by contacting me at samubalogh@gmail.com. Thank you!