Neovim Explained: How to Build a Plugin-Free Nvim Config That Unlocks Builtin Features

Last Updated on May 18, 2023 by David

Neovim (aka Nvim) is a radical refactor of Vim. It aims to take Vim, improve the code, and add more features. They are mostly compatible but have slightly different defaults. The settings in this Neovim tutorial should also work with the latest Vim.

Neovim is a text editor, but it can be configured with plugins to be closer to an IDE. Plugins are a big subject we are not going to cover in this tutorial, we are aiming to get a minimal working setup with zero bloat.

Getting the current stable version of Neovim

Everything in this tutorial is current for Neovim version v0.6.1, I am using the EPEL8 RPM on Rocky Linux 8.5 and Kitty Terminal.

You can see which versions are available for your distribution at pkgs.org. If v0.6.1 is not available you can download the Neovim Appimage directly from the Assets. It should also work on Windows Subsystem for Linux.

How to configure Neovim without using plugins

If you want a great text editor out of the box then you will find yourself banging your head against the wall with Neovim. Many of the factory default settings are weird, and many features are not enabled. In this article, I will show you how to make Neovim awesome without resorting to using any plugins.

All the settings I am going to suggest are built right into Neovim, you just need to create a config file at ~/.config/nvim/init.vim and paste them into it.

If you want to know what a current setting is you can type:

:set [name of variable]?

For example, :set linebreak? will show you the current line break setting, either linebreak or nolinebreak.

Change the escape key to jk

Maybe the most important key in Neovim is the escape key, you use it constantly to move from insert mode to normal mode. The physical position of the escape key in modern keyboards in not easy to reach, I strongly suggest you change escape to be jk, this is very easy to use for touch typing:

 inoremap jk <Esc>
 tnoremap jk <C-\><C-n>

The other popular choice is the Caps Lock key. I find this is best used for delete when you are a touch typist, but each to their own.

Give your document window a title

Neovim uses your terminal to run. By default, depending on what terminal you use, your Neovim terminal window may not be given a title. If you have different windows open with different documents then you have no way of knowing which to select in your windows’ manager. This is obvious nonsense we can put a stop to:

set title

Tabs vs spaces. Use spaces

It is 2022, and we have all collectively agreed to have the tab key create spaces, anything else would have been insane. How many spaces each tab key creates is a personal preference, but I am going for 2. Neovim also has an option that controls indentation, so we should use the same value for that:

 set expandtab
 set tabstop=2
 set shiftwidth=2

Soft wrapping, it’s complicated

Ideally, when we edit a document we want to view it with a line length of about 80-100 characters, anything more makes it hard to scan.

If hard line breaks are used the document can’t be wrapped flexibly by other software using screen size and resolution. Unfortunately, configurable soft wrapping is a problem for Neovim.

Neovim can only soft wrap to the width of the current window

Neovim soft wraps to the width of the screen, and unless you want to enter a nightmare of configuration then you are just going to have to live with that. To make matters worse, it cuts words as it wraps. To make the best of this bad situation we can do two things:

  1. Make our edit window take half the screen. This should make the line length fit within 80-100 characters depending on your screen size and resolution. In Gnome this is very easy, just hit the super key and the left or right arrow.
  2. Set Neovim to not split words when soft wrapping, but split on words:
set linebreak

I suggest you keep an open terminal to the right and Neovim to the left, then you should experience a deep zen-like feeling of minimalism. You never need to leave this sacred safe space again.

Use the system clipboard

On some systems, Neovim will not have support for the system clipboard available. It relies on using an external package to integrate.

To test your system, inside Neovim move to a line with some text on and press "+yy. The + sign means use the system clipboard. Try to ctrl-v it into some other text editor. If it doesn’t work you are most likely missing the external clipboard package that Neovim needs. If you are using xorg it is probably the xclip package. For example, in RHEL 8/Rocky Linux 8/Centos 8:

sudo dnf install xclip

If you have problems, consult the Neovim manual using :h clipboard, it lists all the external clipboard tools that can be used.

The idea of having a separate + register for the system clipboard is so you don’t constantly overwrite your system clipboard with every yank and deletion. For example, if you copy a link from the browser then delete a line to make room for it, the clipboard will be empty. I don’t find this a problem and don’t want to have to type "+ in front of commands, if you agree then you can have the system + register be used by default:

set clipboard=unnamedplus

Enable the spell checker

Neovim has a great spell checker built-in, but you would never know it unless you stumbled across it. To turn it on, set the language, and create a shortcut to toggle it on and off:

 set nospell spelllang=en_us
 nnoremap <silent> <F6> :set invspell<cr>
 inoremap <silent> <F6> <C-O>:set invspell<cr>

Check the spelling documentation on how to use it.

Markdown fenced language syntax highlighting

If you edit documents for programming, then you are probably using Markdown. Neovim has built-in syntax highlighting for most languages. A great feature of Markdown is the ability to embed code into your document using ‘code fencing’. To enable syntax highlighting for the code within those fences:

let g:markdown_fenced_languages = ['bash=sh', 'javascript', 'js=javascript', 'json=javascript', 'typescript', 'ts=typescript', 'php', 'html', 'css']

I have selected the languages I want included, but you can alter them. *note if you are using tree-sitter Markdown this setting is not needed.

Neovim can run as a service for other editors

One of the big features that Neovim has that Vim lacks is the ability to communicate with other software via an API. This means that you can use Neovim as the engine for other editors. The most interesting use for this that I have found is the vscode-neovim extension for Visual Studio Code.

vscode-neovim runs Neovim in the background and pipes all your keyboard commands through it. You get all the functionality of Neovim added to Visual Studio Code! Integrating Code can be a blessing or a curse depending on how easily you are distracted. The main benefit of just using Neovim is to stay focused and accept any limitations, otherwise, you can get sucked down the configuration and new feature rabbit hole and never return.

If you really want an IDE experience then using vscode-neovim is a far better option than spending weeks trying to turn Neovim into Code using extensions like coc.vim.

Bonus: Visual Studio Code dark color scheme

The default colors for syntax highlighting in Neovim are not to everyone’s taste. I think Visual Studio Code dark theme’s colors are a lot better. Luckily it has been converted for Vim/Neovim in the form of vim-code-dark and vscode.nvim.

As I am not getting into plugins in this article, using this colour scheme can just be a single configuration file codedark.vim that you can copy into ~/.config/nvim/colors

Add the following to activate it:

colorscheme codedark

It includes syntax highlighting for many languages and works great in conjunction with Markdown fenced language syntax highlighting. It looks best in Neovim if you install nvim-treesitter.

vim-code-dark vs vscode dark+ visual comparison

While not identical, it is close enough (select view image to see 1080p):

Conclusion

Neovim is an amazing text editor, but out of the box, it has many strange settings. It is a mistake to resort to 3rd party extensions until you know you can’t fix the problem using built-in features. Using the settings in this guide we have:

  • Changed the escape key to make it much easier to use
  • Given our document windows titles so we can easily find them using our windows manager
  • Changed to use spaces rather than tabs
  • Learned about soft wrapping and altered the settings for the best possible experience
  • Enabled the system clipboard and spell checker
  • Enabled syntax highlighting for code blocks inside markdown files
  • Swapped the default color scheme for an emulated Visual Studio Code dark theme.

If you have any more settings you find essential please add them in the comments.

Did you enjoy this article?


Donate Monero 48iK49iM8pEbeNm9FEHaLj2rt7XxqtukvZg2yv5UbCWCTFEsw7175Dt6DFMkZrxS3C6qSJTJKECHW2tBZKyTLa1cRPWRPLT


If you would like me to write similar articles for you or your company please don’t hesitate to get in contact.

6 Comments

  1. I have a zsh function called “Fancy-ctrl-z” that helps me to get me back to my file after a ctrl-z

    fancy-ctrl-z () { if [[ $#BUFFER -eq 0 ]]; then BUFFER="fg" zle accept-line else zle push-input zle clear-screen fi } zle -N fancy-ctrl-z bindkey '^Z' fancy-ctrl-z

    I can press Ctrl-z to jump to a terminal, run any command and get back easily

  2. It is 2022, and we have all collectively agreed to have the tab key create spaces, anything else would have been insane. How many spaces each tab key creates is a personal preference, but I am going for 2.

    You’re just saying yourself here why using spaces for indention is bad. My personal preference is a tab width of 4, yours is 2. Using tabs, we both can have our way. With spaces, bad luck…

    So: Tabs for indention, spaces for alignment!

Leave a Reply

Your email address will not be published. Required fields are marked *