Barbarian Meets Codingbarbarianmeetscoding

WebDev, UX & a Pinch of Fantasy

13 minutes readvim

Wiki: Vim Plugins - Enhancing Your Vim Editor with Awesome Plugins

Plugins

FZF

FZF is a great fuzzy search plugin that you can use to navigate directly to files within vim. If you’ve used any modern editor you’ll recognize this feature as C-P or COMMAND-P. It consists on:

  • The fzf fuzzy search tool itself that comes with a thin wrapper for vim
  • The fzf.vim plugin that provides additional commands

Look at the repos above to find more information on how to install them with your favorite package manager and vim plugin manager.

Helpful config:

" FZF - bind file fuzzy search to C-p
nnoremap <C-p> :<C-u>FZF<CR>

Some helpful keybindings to remember:

" open fuzzy search
<C-P>

" after opening fuzzy search
<CR>  " open file in same window
<C-V> " open file in vertical split
<C-X> " open file in horizontal split
<C-t> " open file in new tab

Denite

Denite is an interesting plugin that provides a generic interface with fuzzy matching to interact with lists of things:

  • Files, Buffers, etc (in a very similar way to fzf)
  • Git
  • MRU (most recently used directories and files)
  • Help
  • Vim commands
  • Quickfix
  • etc…

The difference between fzf and denite is that denite is more integrated with Vim, offers a wider variety of sources (in the shape of other plugins that hook up to Denite) and you can associate actions to the items within these sources (jump to quickfix, execute command, load a session, create a file, etc).

Lightline

Lightline is a nice configurable status line for vim.

You configure it by setting a global variable g:lightline as shown below:

let g:lightline = {
      \ 'colorscheme': 'wombat',
      \ 'active': {
      \   'left': [ [ 'mode', 'paste' ],
      \             [ 'readonly', 'filename', 'modified', 'helloworld' ] ]
      \ },
      \ 'component': {
      \   'helloworld': 'Hello, world!'
      \ },
      \ }

This is another possible configuration:

let g:lightline = {
  \ 'active': {
  \ 'left': [['mode', 'paste' ], ['readonly', 'filename', 'modified']],
  \ 'right': [['lineinfo'], ['percent'], ['fileformat', 'fileencoding']]
  \     }
  \ }

ALE

ALE or Asynchronous Linting Engine is an amazing plugin that integrates vim with modern compiling, linting and formatting tools like eslint, tsserver or prettier. In addition to linting, in-editor messages and formatting, it provides autocompletion and smart navigation.

Nerd tree

Nerd tree is a file system plugin for vim

Emmet

Emmet

Vim Surround

Vim surround is a plugin that help you wrap (surround) words and sentences in wrapping characters like ", ', [, { and even HTML tags.

You can change the current surroundings of a word by using cs:

" change surroundings from " to '
cs"'

For instance, if you have

"Hello world"

Typing cs"' results in:

'Hello world'

You can wrap it in an HTML tag cs'<h1>:

<h1>Hello world</h1>

And back to double quotes cst" (where t stands for tag):

"Hello world"

You can delete surroundings with ds. For instance, if we type ds" we will remove the quotes:

Hello world

You can add surroundings with ys:

// type ysw"
"Hello" world
// type yss(
( "Hello" world )

If you want to wrap a full body of text with a HTML tag you can use V to change to visual mode and then use S to wrap whatever you select into a tag:

<section>
  <h1>Something important</h1>
  <p>lorem ipsum jara jara</p>
</section>

Try S<aside class="highlight">:

<aside class="highlight">
  <section>
    <h1>Something important</h1>
    <p>lorem ipsum jara jara</p>
  </section>
</aside>

Vim Tmux navigation

The vim tmux navigator lets you seamlessly navigate between vim and tmux panes. Basically, the way that it works is that it setups the same bindings to move between panes in vim and tmux, and, it detects whether you’re in vim or tmux to do the right thing. If you are using tmux with vim, this plugin is GOLD.

Follow the instructions on GitHub to install the vim and tmux plugins.

These are the default keybindings:

" Tmux navigator keybindings
" <ctrl-h> => Left
" <ctrl-j> => Down
" <ctrl-k> => Up
" <ctrl-l> => Right
" <ctrl-\> => Previous split

They can also be customized.

vim-devicons

The vim-devicons plugin adds icons to vim. This seems like something trivial but it really makes vim look much nicer. More like a modern editor. It’s the little details ya know! You need to combine it with a font for your terminal/editor which supports icons. There’s a repository with a ton of patched fonts.

targets.vim

The targets plugin extends and improves the functionality of text-objects in vim in amazing ways:

  • It enables seeking for all text-objects. That is, you no longer need to be on top of a text-object to use the i or a commands. You can be anywhere within a line use ca( or ci{ and it will work as you’d expect, changing the inside of parens or brackets. Seeking works also over multiple lines with n (for next) and l (for last). For instance cin" changes the next quotes it finds, while cil" changes the previous quotes it finds.
  • It adds two new commands I and A that preserve whitespace
  • It adds text-objects for arbitrary separators and function arguments.

Check the targets cheatsheet for more information on what’s available and for diagrams of how the different commands work.

Deoplete

Deoplete is an autocompletion engine for neovim (something like intellisense in VsCode or Visual Studio). It allows you to connect advanced autocompletion sources like LSPs (language service providers), snippets, tags, etc.

TBH it is non trivial to set up and I’m still experimenting with it. The documentation via :h deoplete is a great help.

Neosnippets

Neosnippets is a snippets plugin that integrates very well with Deoplete. It allows to create snippets of your own devise and have them available to deoplete for autocompletion. It also comes with a bunch of built-in snippets via a separate plugin:

For more info like how to create your own snippets take a look at the plugin docs using :h neosnippets.

Zoomwintab.vim

Zoomwintab.vim lets you zoom in into buffers in a similar way to tmux! It remaps CTRL-W o from closing all other splits to just zooming in the current split. If you use the binding after having zoomed, the splits are restored to their original size.

Coc. Conquer of Completion

coc.nvim or Conquer of Completion provides the best support for IDE-like features in Vim that I’ve encountered, and strikes a great balance between ease of setup and number of features. In order to get coc.nvim set up for a given language you will need to follow these two steps:

  1. Install the coc.nvim plugin in Vim using your favorite plugin manager. You only need to do this once.
  2. Install and extension for that specific language (for example, you can run the :CocInstall coc-tsserver command to provide IDE-like support to JavaScript and TypeScript). There are a lot of extensions available for many popular programming languages. When installing an extension for a new language it is recommended to take a look at the documentation for that extension to see whether there’s some additional configuration required (e.g. coc-tsserver works out of the box but the docs provide additional information about how to configure it further).

Once installed coc.vim will be activated as soon as you open a file that matches one of your extensions. For instance, if you’ve installed coc-tsserver, any time that you open a TypeScript file coc.nvim will spring to life. It is useful to add the coc.nvim status information to your status line in Vim. That way you get immediate feedback that coc.nvim is working as expected whenever you open a file. Alternatively, you can use the :CocInfo command to get detailed information about the current status of coc.nvim:

## versions

vim version: NVIM v0.4.2
node version: v12.6.0
coc.nvim version: 0.0.74-3712edf331
term: iTerm.app
platform: darwin

## Messages

## Output channel: tsserver
[Info  - 12:55:23 PM] Started TSServer
{
  "path": ".../.config/coc/extensions/node_modules/coc-tsserver/node_modules/typescript/lib",
  "_pathLabel": "",
  "_api": {
    "versionString": "3.7.3",
    "version": "3.7.3"
  }
}

Each extension acts as a source of functionality and you can reach those sources using different coc.nvim commands. For example:

  • You can use :CocInstall {extension} to install extensions
  • :CocList lets you access lists from different sources. Some examples are:
    • :CocList extensions list your installed extensions
    • :CocList outline gives you an outline of your current file (like the one you’d get in an editor like VSCode or Visual Studio)
    • :CocList snippets gives you a list of available snippets
    • :CocList diagnostics gives you a list of errors and warnings
  • :CocCommand {command} lets you run a command provided by a source. For instance:
    • :CocCommand snippets.editSnippets sends you to the snippets file for the language of your current file
    • :CocCommand tsserver.executeAutoFix fixes all autofixable errors that exist currently (e.g. missing imports and incorrectly implemented interface)
  • :CocAction lets you perform actions to the code under you cursor or your current selection. Really useful actions like renaming, adding missing imports, refactorings like extract function or constant, extracting a snippet, etc.
  • :CocFix lets you apply fixes recommended by the language server

You can find a lot more information on how to setup coc.nvim, how to install extensions, how to configure it and how to provide a minimal configuration with sensible mappings on GitHub. The latter is super recommended with useful bindings such as these:

" Use `[g` and `]g` to navigate diagnostics
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)

" Remap keys for gotos
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)

coc.nvim also comes with a comprehensive documentation that you can find directly within vim using the always handy help command :h coc-nvim.

Other alternatives to coc.nvim that are very established are YouCompleteMe, Ale, Deoplete and vim-lsp. You can also find a comprehensive list of IDE-like plugins in vimawesome.org.

Regardless of which plugin you choose in the end, I hope that the next time you configure Vim to use a new language you’ll get an amazing development experience. Take care and have a wonderful day.

Using coc.nvim in large TypeScript projects

I’ve struggled to have coc.nvim run in the context of a huge monorepo at the scale of Google. I’ve found that for large projects it is easy for tsserver to reach the maximum of 2GB for node processes, and crash and burn. Under these conditions, you can use the following configuration you increase the memory limit to run tsserver:

{
  // Increase memory limit to run large TypeScript projets (in MB)
  "tsserver.maxTsServerMemory": 8192 
}

This configuration will be passed to node using the --max-old-space-size flag.

Utilsnips

Utilsnips is a vim plugin that allows to use and manage your snippets. It integrates with a lot of other Vim plugins (like Coc) and lets you manage and share a collection of snippets so you can reuse code and save you from typing. This is incredibly useful because it helps you be more productive and at the same time, if shared, can improve the productivity of your team mates and the consistency of a codebase.

animated gif that shows how utilsnips works. As the user writes a collection of available snippets appears in a dropdown, when the user selects the snippets it expand and is inserted in the buffer.

Escaping backticks in Utilsnips

In order to escape backticks when creating snippets in utilsnips you can follow the approach below:

snippet codeblock "A markdown code block" b
\`\`\`${1}

${0}

\`\`\`
endsnippet

Resources

To investigate


Jaime González García

Written by Jaime González García , Dad, Husband, Front-end software engineer, UX designer, amateur pixel artist, tinkerer and master of the arcane arts. You should follow him on Twitter where he shares useful stuff! (and is funny too).Jaime González García