Neovim 101 — Terminal and Shell

Understand how the terminal and Neovim work together.

6 min readSep 16, 2022


Neovim 101 — Terminal and Shell

We talked about terminal and shell in general previously. In this article, let’s understand how the terminal and Neovim work together. We will also configure the terminal emulators to work better with Neovim.

This article is part of the Neovim 101 series.

The Neovim configuration files are available in this repository.

Getting Started

Terminal UI

Neovim uses a list of terminal capabilities (:h tui) to display its user interface. If that information is wrong, the screen may be messed up or keys may not be recognized.

It guesses the terminal type when it starts (:h startup-terminal). The $TERM environment variable is the primary hint that determines the terminal type.

The $TERM environment variable (Neovim 101 — Terminal and Shell:h $TERM) must match the terminal we are using. Otherwise, Neovim cannot know what sequences the terminal expects, and weird or sub-optimal behavior will result (scrolling quirks, wrong colors, etc.).

Historically, terminal emulators could not distinguish between certain control key modifiers and other keys (:h tui-csiu). For example, <C-I> and <Tab> are represented the same way, as are <Esc> and <C-[>, <CR> and <C-M>, and <NL> and <C-J>. This meant that Neovim also could not map these keys separately.

Control Sequence Introducer (CSI)

CSI is designed to resolve precisely this issue. It encodes any possible key presses uniquely. Specifically, we use the CSI u (Unicode) encoding to help us differentiate the different key presses.

A CSI control sequence looks like the following

0x1B + "[" + <zero or more numbers, separated by ";"> + <a letter>

For more details on the format, check out this Wiki.

0x1B represents the ANSI escape code. ANSI escapes always start with either

  • \x1b, \0x1b — Hexadecimal
  • \033 — Octal
  • \e




Software engineer, Data Science and ML practitioner.