Skip to content
Daniel Nachun edited this page Apr 9, 2024 · 9 revisions

Why use neovim?

There are many choices for development environments, including fancy integrated development environments (IDEs) like PyCharm, RStudio, Jupyter, VSCode and text editors with graphical user interface (GUI) such as Sublime Text. Why use such a minimal text editor instead? A few important motivations:

  • Resource usage: IDEs and GUI-based text editors can use a significant amount of resources (CPU usage and RAM). Even emacs, which can be run in a terminal, can have a significant resource footprint when plugins are used. Vim and neovim by contrast, use a very small amount of resources, and importantly, that resource usage does not increase much even with many plugins. Neovim plugins written in Lua are especially efficient because they use just-in-time compilation with LuaJIT, giving them near native performance in speed and resource usage. Minimizing resource usage is especially important in high performance computing environments where resources should be allocated to data processing rather than writing code.
  • Portability: connecting IDEs and GUI-based editors to remote computing sessions that must often be used for high performance computing can be very challenging. By contrast, neovim can be run inside the remote computing session, meaning you only need a terminal and SSH access to do you work. If you are already using neovim for remote computing, it is much easier to use the same environment for your local text editing and coding as well, and you can easily have the same neovim setup locally on Linux, macOS and Windows (with some limitations).
  • Scalability: When working with large amounts of data, IDEs are prone to crashing because they often try to inspect the data loaded into the workspace. Neovim and its plugins have minimal interaction with any workspaces they are running and are not affected by the size of the data loaded into the workspace.

Basic usage

Neovim is a fork of vim and inherits the many useful features that are built into vim. There are many resources on how to learn the basics of vim (LINKS), so this guide will only cover the most basic features.

Modes

Vim is a model editor, meaning that the same keys will have different effects depending on which mode you are in. Switching between modes is a critical part of using vim that must be understood to use it effectively. The most important modes to know are (key bindings in parentheses):

  • Normal mode (Esc) - this mode is where you issue most commands to vim.
  • Insert mode (i/a/o/I/A/O) - this mode is where you edit text like in other text editors. i enters insert mode before the current character, a enters it after, and o opens a new line in Insert mode below the current one. In parallel, I enters insert mode at the beginning of the line, A inserts at the end of the line, and O enters Insert mode in a new line above the current one
  • Visual model (v) - this mode allows you to select text character by character - all movement keys described below can be used to move the cursor.
  • Visual line mode (V) - this mode allows you select text line by line (useful for selecting lots of text quickly) - a limited set of movement keys can be used to movement cursor.
  • Terminal mode (same as Insert) - this mode is specific to neovim and only works in terminal buffers. It is equivalent to Insert mode for text buffers, but you cannot edit text already printed above.

The neovim command prompt

While neovim is not a shell, it has many commands that may not have a key binding assigned, or may be too complex to assign a binding. To enter the command prompt, press : while in Normal mode. Any shortcut you see here that begins with : means that you will be entering the command into the command prompt.

Saving and quitting

Neovim provides some safeguards to prevent you from quitting without saving. If your Neovim session is prematurely terminated without saving, the latest version of your file should be saved in a swap file. This file will automatically be opened the next time you edit the file, and you will be asked if you want to recover the file or edit anyway. You should recover if the modification time of the swap file is newer than the original file, and you should delete the swap file if its modification time is older than the original file. Some important keybindings for saving and quitting:

  • :w - save your changes.
  • :q - quit vim. You should instinctively use :wq in most cases to save your changes before quitting, but you may sometimes open a file without changing it, making w unnecessary. Even more rarely you may modify a file and not wish to save the changes. In this case, you can use :q! - use this with caution!

Swap files

Swap files are a safety measure for neovim to avoid the risk of losing changes to the file you are editing if the text editor is closed without saving changes. As you make changes to the file you are editing, it is cached to a swap file. When you save your file, the swap file replaces the original file. If neovim is closed normally with no unsaved changes, the swap file is deleted. If neovim finds a swap file corresponding to the file you are editing, it will ask you what you want to do:

[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort

Quitting will close neovim immediately, and aborting will leave you in an empty file. Opening read only will let you view the file without being able to change it, while editing it anyway will let you make changes. Recovering from the swap file will load the swap file instead of the original file, while deleting the swap file will get rid of it immediately.

What you should do depends on the several circumstances.

  • If neovim says the swap file is newer than the original file, you should usually recover it so you can its state. Once you have recovered it, you can save the changes to the original file. Or you can quit without saving if you don't want to override the original file.
  • If neovim says the swap file is older than the original file, you should usually delete the swap file.

You should avoid editing anyway as this will neither delete the swap file nor recover it. Opening read only is useful to inspect the original file - it also will not resolve the swap file either way.

Movement

Neovim uses a set of keybindings for moving the cursor that are designed to maximize efficiency and minimize finger travel. An important concept is that your fingers should return to the homekeys (IMAGE) after every movement. This helps to explain the seeming arbitrary set of movement keys.

  • h,j,k,l - These keys move left, down, up, and right, respectively. They are also the home keys for the right hand!
  • ^, $ - Move to the beginning and end of a line, respectively. Remember to use I or A instead if you want to enter Insert mode directly!
  • Ctrl+f,Ctrl+b - These keys move down and up one half page, respectively. They are essentially equivalent to the Page Down and Page Up keys on full sized keyboards.
  • w,W - These move one word to the right, putting the cursor at the beginning of the next word. W skips some characters that w does not, making movement faster but less precise.
  • e,E - These move one word to the right, putting the cursor at the end of the next word. E skips some characters that e does not, making movement faster but less precise.
  • b,B - These move one word to the left, putting the cursor at the beginning of the previous word. B skips some characters that b does not, making movement faster but less precise.
  • {,} - These move to the beginning and end of a code block. Code blocks are language specific but often follow function/class definitions or white space.
  • f,F - These move the cursor to the next and previous instance, respectively of the character typed after them - i.e. fa will move to the next instance of a, and Fa will move to the previous instance of a.
  • t,T - These move the cursor to the character adjacent to the next and previous instance, respectively of the character typed after them - i.e. ta will move to the character before next instance of a, and Ta will move to the character after the previous instance of a.
  • gg, G - These move to the beginning and end of the file.

Deleting and replacing text

Vim provides several keybindings for removing or replacing text. Several of these keybindings are compositional, meaning that you combine the keybinding with a movement key.

  • d + movement key - delete from the cursor position to wherever the movement key sends the cursor and stay in Normal mode. For example, to delete to the end of a word, use de. Use this when you still want to move your cursor after deleting instead of going into insert mode.
  • c + movement key - delete from the cursor position to wherever the movement key sends the cursor and stay in Normal mode. For example, to delete to the end of a word, use ce. Use this when you want start editing text immediately after deleting.
  • x - delete the current character under the cursor.
  • dd - delete an entire line and stay in Normal mode
  • r - replace the character under the cursor with a new one, and return to Normal mode
  • You can also select text with Visual or Visual Line mode, and then use x, d or c to delete it with the same effects as described for those keys above.

Search and replace

Vim provides a very sophisticated system for searching for and replacing text. The main key bindings are:

  • / - Open the search prompt
  • n,N - Search for the next and previous match, respectively. Vim uses a syntax similar to sed for replacements. A simple replacement will take the form of s/text/replacement/. Adding a g to the end will replace all instances of the search query within, and the search query can include regular expressions (LINK). You can either select the text over which to do the replacement with Visual or Visual Line mode, or append a % to the beginning of the replacement to apply the replacement to the whole file (use this with caution!)

Copy/cut and paste

Vim use a series of buffers to store text for copying and cutting text. This guide will only describe basic operations with the local buffer - see the plugins section for more details on how to copy from the system buffer. Important key bindings:

  • y - copy text selected by Visual or Visual Line mode
  • yy - copy the current line under the cursor while in Normal mode - this saves you from selecting with Visual or Visual Line mode if you only want to copy one line
  • Deleting text with d, c, or x as described in the deletion and replacement will automatically place it into the local buffer, making these equivalent to the "cut" commands used in other text editors
  • p/P - paste the contents of the buffer after or before the cursor, respectively.

Splitting panes

Panes are a useful way to split your neovim session, either to view a one large file in more than location simultaneously, or to view different files side by side.

  • :sp/:vsp (from Normal mode) - Split your screen horizontally and vertically, respectively. Vertical is usually most useful on wide screen monitors.
  • Ctrl+h,j,k,l - Move the cursor between panes (see section on Panes below) in the same directions as h/j/k/l move the cursor in text.

Plugins

Neovim supports many incredibly powerful plugins that give it the features of a full integrated development environment (IDE) without the complexity and resource usage those tools usually need (see the first section for more on this). The setup in this repository uses many plugins, some of which do not have many keybindings and are more or less invisible to the user. This guide will describe only the most important key bindings for select plugins for the sake of brevity.

This plugin gives neovim most of the features of RStudio. The full documentation can be found here. An important concept for Nvim-R is the "leader" key, which is prepended to most commands so as to avoid conflicts with keybindings in the base neovim or other plugins. This configuration uses , as the leader, as suggested in the plugin documentation. The most important keybindings for Nvim-R include:

  • Space - pressing this key in Normal mode when an R console is open in a terminal buffer will send whatever line is under the cursor to R console. Pressing it in Visual or Visual Line mode will send whatever code has been selected to the R console.
  • ,rf - launch an R console in a terminal buffer below the current text buffer
  • ,rw - quit the R console and save the workspace
  • ,rq - quit the R console and do not save the workspace - use with caution!
  • ,rh - look up the help entry for the word the cursor is currently on and open it in a new buffer to the right - this will produce an error if the word under the cursor is for a function in a library you have not loaded or which is not a function at all.
  • ,ro - launch the object browser to view all objects in the workspace - this browser does not show memory usage per object and has more limited previewing capability than the one in RStudio. Do not attempt to preview large objects - it will crash!
  • ,fe - send an entire function to the R console so that it will be loaded in the workspace. Your function must be defined properly and this will fail if there are syntax errors within the function.

Installing R packages with micromamba:

This setup is designed to work closely with micromamba to manage R libraries. This is achieved by creating a micromamba environment called r into which all R packages are installed. That environment is automatically created by the setup here. To install additional packages use:

micromamba install -n r PACKAGE1 PACKAGE2 ...

More than one package can be installed at once, and if some of the packages you specify are dependencies of others in the same list, they will simply be ignored. Similarly, if some of the packages you already specified are already installed, they will simply be skipped. Package names for R packages in Conda depend on where the package is from. CRAN packages are provided by conda-forge and start with r- (i.e. r-tidyverse) while Bioconductor packages are provided by bioconda and start with bioconductor-. Packages from GitHub or other non-standard sources will usually start with r- and may be on custom channels or occasionally bioconda (they are not usually allowed on conda-forge). You will need to search on anaconda.org if you are unsure whether your package is in CRAN or Bioconductor.

To remove a package use:

micromamba remove -n r PACKAGE1

and to upgrade a package:

micromamba upgrade -n r PACKAGE1

You can also upgrade all packages in the environment:

micromamba upgrade -n r --all

Other things to note when using Nvim-R:

  • Nvim-R saves your workspace into a file within the same folder as the R script you are editing. This is extremely helpful for keeping different projects separate - so long as you save the R scripts for each project in a different folder (which you should already be doing anyway), their workspaces will be separate.
  • If a saved workspace already exists in the same folder as the script your are editing, it will be loaded automatically when you use ,rf. If the saved workspace is very large and takes a long time to load, you may get an error that the server is not ready when you try to send lines with Space. To circumvent this, move down to the R console with Ctrl+j, type q() to quit the R console, and do not save your workspace. You can then try to launch the R console again with ,rf and it should load this time.
  • Similarly, if an R script has a lot of libraries imported, the automatic syntax highlighting provided by Nvim-R may be slow the first time you edit the script while it builds a cache of the imported functions. If you get an error when that the server is not ready when sending lines with Space, use the same process described in the previous point to restart your session and it should load the second time.
  • If want to terminate a command in the R console, use ctrl+c. If this does not work, then you will have to use :q in Normal mode while in the terminal buffer to kill the whole buffer. You will lose any unsaved changes to your R workspace, but your R code in your text will still be fine! You can save it :w before doing this just to be safe.
  • Since the object buffer does not show memory usage, use this line in R to see the sizes of all objects in your workspace (LINE), and use the rm() function in R to delete objects which are too large.

The iron.nvim plugin provides an IDE-like interface to any language capable of having a read-eval-print-loop, meaning that code can be sent to some type of interpreter which can evaluate it and print the results, and that this can be done indefinitely. REPL is the most powerful and efficient way to write code, because it allow the developer to "fail quickly" until the code works as desired. The iron.nvim plugin supports many languages, although the current focus of the configuration is on supporting Bash/Zsh and Python. Future efforts will try to add support for more languages, although the default configurations may work already for many. Important keybindings for iron.nvim are:

  • ,s - Launch an interpreter in a terminal buffer for the language neovim identifies based on the extension of the file being edited. An error will occur if the file has no extension or iron.nvim doesn't know what interpreter to use for the extension.
  • ,q - Quit the interpreter running in the terminal buffer. Note that unlike in R, most other languages have no notion of a "workspace" and the state of the variable in the interpreter will not be saved. This is largely irrelevant for shell scripting, and for Python "pickling" is usually used to save the most important variables to objects on the disk.

Note: This will be replaced by a Lua-based plugin in the near future Commenting and uncommenting code is an extremely common action taken when editing code. NerdCommenter provides several simple keybindings to make this simpler:

  • ,cc - Comment out the current line under the cursor in Normal mode. In Visual and Visual Line mode, comment out all the selected lines.
  • ,cu - Uncomment out the current line under the cursor in Normal mode. In Visual and Visual Line mode, uncomment out all the selected lines.

Although the advanced find and replace features of base neovim are usually fast and very flexible, sometimes for simple replacements, the multiple cursors approach pioneered by Sublime Text is sometimes more convenient. vim-visual-multi brings this feature to vim.

  • In normal mode, pressing Ctrl+n will select the current word under the cursor. Pressing it again will select the next occurrence of the same word, and it can be repeated indefinitely until all occurrences are selected.
  • In Visual or Visual Line mode, pressing Ctrl+n will select all the text already selected in Visual mode, and pressing it subsequently will select additional occurrences.
  • Once the instances you want to modify have been selected, you can use x or d to delete them, or c to delete them and simultaneously enter insert mode for all of them. Think of this as an "interactive" find and replace.

Neovim has several buffers for local use, but interacting with the system copy buffer for copying between Neovim and other applications is more complex. vim-system-copy provides a consistent interface to the system copy buffer in Linux and macOS. It provides several keybindings:

  • cp - in Visual or Visual mode, copy the selected text to the system copy buffer
  • cv - paste text from the system copy buffer into neovim. Note that you can also use the default paste command for your system copy buffer (Commmand-v on macOS, Ctrl+v on Linux and Windows) in most cases

Please note that copying text from neovim over SSH currently requires both that xclip is installed on the SSH remote host and that an X server is running on the local host. In the future this will hopefully be replaced with a simpler Wayland-based system!

Telescope is a powerful fuzzy finder and selection tool. Currently the only key binding configured with Telescope is Ctrl+P, which brings up the most recently edited files. You can start typing a file name and will return all fuzzy hits, with fewer hits as you type more characters

Trouble is an extra buffer that can be opened to show any issues identified by language servers and linters. It can be toggled on with ,tt and hidden again by pressing ,tt. If you move your cursor to the Trouble pane with Ctrl+j, as you move your cursor over each line, it will move the text buffer above to that line, so that when you press Ctrl+k, you will be right on the offending line.

vim-markdown-composer provides an easy to preview Markdown files in a web browser as they are being edited. Upon opening a .md file (currently restricted to macOS, but it also supports Linux), a new tab or new window in your default browser will be opened with a preview of the file. Whenever changes are saved to the file, the preview is updated.

VimTex is a very powerful plugin for editing LaTeX in vim/neovim. The full documentation can be found here. The most important keybinding is ,ll for starting continuous compilation and ,lk to stop it. The continuous compilation will compile the LaTeX file you are editing into a PDF and automatically open it in a PDF viewer. Currently this is configured to Skim on macOS in this repository, but you can override it to a different editor as needed.