My Neovim Plugins (April 2023)

Table of Contents

  1. What is Neovim
  2. My Plugin List
    1. UI plugins
      1. tokyonight.nvim
      2. lualine.nvim, indent-blankline.nvim, todo-comments.nvim, and gitsigns.nvim
    2. nvim-treesitter
      1. Treesitter Playground
      2. nvim-treesitter-context
      3. nvim-ts-autotag
    3. telescope.nvim
      1. telescope-file-browser.nvim
    4. quick-scope
    5. nvim-autopairs
    6. Comment.nvim
    7. vim-easy-align
    8. vim-fugitive
    9. gv.vim
    10. repos.nvim
    11. vim-surround and vim-repeat
    12. vim-rsi
    13. vim-eunuch
    14. vim-abolish
    15. LSP
      1. nvim-lspconfig
      2. mason.nvim
      3. mason-lspconfig.nvim
      4. null-ls.nvim
      5. mason-null-ls.nvim
    16. nvim-cmp
      1. cmp-cmdline
    17. DAP
  3. Which Plugins Didn’t Make It
  4. Summary

Right now, I am moving from one Neovim plugin manager to another. While I am at it, I clean up plugins and their configurations. Sometimes, what a given plugin does is not apparent at first sight. Therefore, I decided to create a rundown of what I use. Then the idea to make a blog post out of it came. Maybe I will inspire you to introduce one of these plugins into your workflow!

What is Neovim

As an after-thought, I decided to give a quick explanation of what Neovim is. Not everyone has to know that!

Neovim is a modal text editor. Modal means several distinct modes, such as visual for selection, normal for navigation, or insert for typing input. Having different modes provides excellent configuration capabilities. You could have the same key do different things in different modes!

If you would like to learn more about Neovim and what it takes to make it an fantastic code editor, then I recommend:

My Plugin List

If you would like to explore what a given plugin has to offer, then click it’s name in a section header - that will take you straight to the plugin’s GitHub repository.

UI plugins

tokyonight.nvim

First goes the color scheme, or theme, if you will. Without one, you are going to be greeted by dull-looking colors when launching Neovim:

Neovim without colorscheme

The default colorscheme looks better than it used to, but I like Tokyo Night more:

Neovim with TokyoNight colorscheme

It could be even better, but there is one crucial piece of the puzzle that is missing - treesitter. Once we let treesitter handle syntax highlighting, it gets a whole lot nicer:

Neovim with TokyoNight colorscheme and treesitter enabled

lualine.nvim, indent-blankline.nvim, todo-comments.nvim, and gitsigns.nvim

There is not much to say about these plugins other than showing what they do. Each of them provides a different interface part for Neovim.

Neovim UI plugins showcase

nvim-treesitter

Treesitter is the backbone of many other plugins. By itself, it provides syntax highlights and parsers for numerous programming languages. Treesitter allows querying a file’s syntax tree using its query language.

I haven’t used treesitter itself much, only when I had to retrieve a treesitter node name to configure a different plugin. However, I use a couple of plugins that rely on treesitter. Read on!

Treesitter Playground

Treesitter Playground is a helpful tool for debugging and analyzing a treesitter representation of the currently opened file. :TSPlaygroundToggle provides a live preview of the structure in a split.

Treesitter Playground demo Treesitter Playground demo

nvim-treesitter-context

nvim-treesitter-context “pins” relevant lines to the top of the current buffer. For example, if a function is too long to fit on the screen, then the treesitter context will keep that line pinned.

nvim-treesitter-context demo nvim-treesitter-context demo

nvim-ts-autotag

This simple plugin will automatically close tags for you in JSX, HTML, etc.

nvim-ts-autotag demo nvim-ts-autotag demo

telescope.nvim

Telescope is definitely a more exciting thing than treesitter. Basically, telescope is as good as fuzzy searching can get.

You get the idea. There are even more pickers you can choose from! Telescope comes with a preview window for your convenience. Additionally, after narrowing down the results, you can send these to the quickfix list to navigate between them easily.

telescope.nvim demo telescope.nvim demo

telescope-file-browser.nvim

telescope-file-browser.nvim provides an additional picker that allows creating new files and navigating through directories.

I am not a fan of this one. Likely in the near future, I will try replacing it with an alternative or just make the default NetRW good enough for my use (creating files and directories).

telescope-file-browser.nvim demo telescope-file-browser.nvim demo

quick-scope

quick-scope highlights unique letters within words on cursor’s line. The highlights are helpful for f/F and t/T movements in Vim.

By default, quick-scope uses two different highlights for letters available for f and 2f motions. Personally, I have only the former enabled to make it less confusing. Additionally, I have the highlights enabled at all times instead of displaying them after hitting f/F/t/T - this way, I don’t have to wait to see the second key I need to press.

quick-scope demo quick-scope demo

nvim-autopairs

The name of this plugin speaks for itself. It autocompletes pairs of brackets, quotes, etc. This plugin has some additional settings you can tweak. However, I didn’t need it so far - it is good out of the box.

nvim-autopairs demo nvim-autopairs demo

Comment.nvim

This plugin is simply amazing. If you have never used any comment plugin for Vim, then you definitely should give one a go! This plugin lets you stop thinking about the correct comment string for the file you are editing, e.g., # for YAML, -- for Lua. Additionally, this plugin can comment on multiple lines, and the comment strings are always neatly aligned. Finally, there are mappings to start writing a comment at the end of the current line and above or below the current line; however, I never remember to use these.

Comment.nvim demo Comment.nvim demo

vim-easy-align

vim-easy-align is irreplaceable if you need to format some text. You can provide an arbitrary expression or a specific number of characters that have to be aligned. Formatting a markdown table takes less than 5 seconds.

vim-easy-align demo vim-easy-align demo

vim-fugitive

tpope is a Vim plugin artist. His plugins have an outstanding user experience that fits Vim ecosystem really well. vim-fugitive is one of these plugins, perhaps the most known one.

vim-fugitive integrates an interface for managing git into a separate Vim split and a wrapper for git CLI to use it seamlessly from Vim. Personally, I need to make it a habit to utilize fugitive more because it literally has it all! One of the nicer features I would like to highlight is modifying (staging, restoring, etc.) a small subset of lines based on visual selection within the fugitive interface.

Another nice thing I appreciated while committing part of this blog post was having everything within a single window. I had the blog post, fugitive buffer providing a preview of current git state, and a buffer to write the commit message. This way, I could freely move between the three to check whatever I wanted before finalizing the commit message.

vim-fugitive demo vim-fugitive demo

gv.vim

Continuing with git, gv.vim is a simple git history graph viewer. As simple as that. A nice touch is navigation from commit preview into specific files.

gv.vim demo gv.vim demo

repos.nvim

repos.nvim is my very own plugin! Its premise is simple. Run a given callback function if a git remote matches provided pattern.

I have created repos.nvim, because I needed to override some settings for a specific repository. Existing solutions for per-project settings required an additional file in the project’s directory, and I didn’t want to maintain it. That’s how repos.nvim came to be, allowing me to configure overrides within my dotfiles.

vim-surround and vim-repeat

vim-surround is yet another masterpiece from tpope. As its name suggests, it is used for surrounding. Surrounding text objects (see :h text-objects) with… things. This plugin has its functionality very composable. Pick ys for adding, cs for changing, and ds for deleting the surrounding. Then provide a text object (e.g., iw for word, iW for continuous characters). Finally, pick the surrounding, be it quotes, brackets, or anything else supported by the plugin.

vim-surround demo vim-surround demo

vim-rsi

vim-rsi is a straightforward plugin. It comes with multiple mappings that will make your life easier. Thanks to vim-rsi, I have discovered that these mappings work in some shells in the first place! I suggest reading through :h rsi to see the mappings. To give a glimpse: <C-a>/<C-e> for moving the cursor to the beginning or end of the current line when in insert mode or command mode (!). Other mappings include moving by or deleting a letter or a word in either direction.

vim-eunuch

This plugin provides a bunch of useful unix helpers. Personally, I have only used :Remove, :Move, and :Rename, but there are others!

vim-abolish

vim-abolish is one of these plugins you won’t use for ages, but then there is that one use case where it makes things so much easier. It has three main pillars (abbreviation, substitution, and coercion), but I have only used one - substitution. It provides :S command that works similarly to :s with the difference that it handles various cases of the word. Additionally, it allows positional renames. I recommend reading through vim-abolish README to get the gist of it.

Other than substitution, vim-abolish can handle switching between different word cases and setting abbreviations for numerous variants at once.

vim-abolish demo vim-abolish demo

LSP

Last but not least, there are plugins that I use for Language Server Protocol (LSP), commonly known as autocomplete et al. There are quite a few plugins that I use this in Neovim language server communication, language server installation, and completion based on LSP communication are three separate things. I started off by watching [Neovim Builtin LSP Setup Guide by TJ and Bash][].

nvim-lspconfig

This plugin is the backbone of the language server. It provides a ready-to-go config for numerous languages as outlined in its documentation (or in :h lspconfig-server-configurations).

mason.nvim

Since the actual server providing completions and other things is a separate program. These have to be installed manually… or you could use mason.nvim, that provides a nice interface for doing that:

mason.nvim interface

With mason.nvim you still have to install these one by one, but there is a remedy to that…

mason-lspconfig.nvim

mason-lspconfig.nvim is what glues nvim-lspconfig and mason.nvim. This plugin automatically picks up what language server you have configured and, based on that, installs the required programs. It is really convenient if you use different languages and, therefore would have to install many tools across different stacks.

null-ls.nvim

null-ls.nvim is a nice addition to LSP. Basically, what it does is inject some goodies into already running LSP. These include formatters, linters, etc. It provides a convenient way to hook whatever you’d like in. For example, I have prettier with modified defaults so that it is disabled in markdown and yaml, but enabled in astro files.

mason-null-ls.nvim

The same concept as mason-lspconfig.nvim, but for null-ls.nvim.

nvim-cmp

As I mentioned, the language server is responsible for providing completions, but once we get a response, we need to provide a selection back to the editor. That’s where the completion plugin comes in. I use nvim-cmp for that. It allows having the completion suggestions from different sources such as LSP, buffer, or path.

I won’t go into details on this one as this plugin has quite a lot of boilerplate going around. If you want to set it up for yourself, you could check out my dotfiles!

I will, however, drop a list of plugins providing sources for completions:

nvim-cmp demo nvim-cmp demo

cmp-cmdline

This source for nvim-cmp can be configured separately from the ones listed above. It provides completions for command mode (:-stuff).

DAP

Last but not least are DAP (Debugger Adapter Protocol) plugins. Similarly to LSP, DAP is a standard that some programs implement. In other words, DAP is the thing that allows you to set breakpoints and debug within your editor.

I have followed Debugging in Neovim video by TJ and Bash to configure DAP in Neovim. After watching the video, I haven’t tinkered with the setup too much, to the point where I haven’t settled for mappings yet, and on an occasion where I need to debug, I run things manually.

The list of plugins that do the job for me for Go is:

Which Plugins Didn’t Make It

During the switch from packer.nvim to lazy.nvim I reviewed whether I use these plugins. Some didn’t make it, mostly because I wasn’t using them enough. Here is a list of these:

Summary

That’s it - all the plugins I use (at the moment). Of course, there is more to Neovim than plugins - mappings, autocommands, and commands come to my mind.

Moving to lazy.nvim has been an opportunity to clean up my dotfiles. I moved the configuration for every plugin next to its definition in lazy.nvim making Neovim config much more readable. Additionally, along the way, I simplified configs of many plugins and reduced the number of files:

~/.config/nvim changes
  .
  ├── after
  │   ├── ftplugin
- │   │   ├── GV.lua
  │   │   ├── fugitive.lua
  │   │   ├── gitcommit.lua
  │   │   ├── go.lua
  │   │   ├── mail.lua
  │   │   ├── markdown.lua
- │   │   └── norg.lua
  │   └── plugin
  │       ├── autocmds.lua
- │       ├── colorscheme.lua
  │       ├── commands.lua
- │       ├── dap.lua
! │       ├── mappings.lua
- │       ├── repos.lua
- │       └── treesitter.lua
  ├── lua
  │   └── tymek
- │       ├── lsp
- │       │   ├── cmp.lua
- │       │   ├── init.lua
- │       │   ├── lspconfig.lua
- │       │   └── null-ls.lua
  │       ├── git.lua
- │       ├── init.lua
  │       ├── keymap.lua
- │       ├── packer.lua
+ │       ├── plugins.lua
- │       └── with.lua
  ├── plugin
! │   ├── mappings.lua
  │   └── options.lua
+ ├── queries
+ │   └── go
+ │       └── context.scm
  └── init.lua

- 8 directories, 25 files
+ 9 directories, 15 files

The next stop: cleaning up my mappings.