Vim - Terminal Text Editor

Installation, Configuration & Usage

Terminal
Published

December 4, 2010

Modified

June 13, 2024

Text-editor …one of the most used applications

Vim philosophy …two main ideas to understand:

Installation

Fonts

Editors (and other shell tools) require fonts with a specific glyph set.

Install Nerd Fonts

#!/usr/bin/env bash
test -d ~/.fonts || mkdir ~/.fonts   # path to the user font cache
cd $(mktemp -d)                      # work in a temporary directory
version=${1:-v2.3.3}                 # version of Nerd Fonts
for zip in Inconsolata.zip Hack.zip
do
        curl -Lf https://github.com/ryanoasis/nerd-fonts/releases/download/$version/$zip -o $zip
        unzip $zip
done
cp -v *.{ttf,otf} ~/.fonts           # copy fonts to the user cache
fc-cache -f -v                       # update the font database

Configure nerd font in terminal emulator…

NeoVim

Install NeoVim 1 …unless a recent version is available as distro package:

# official AppImage
wget https://github.com/neovim/neovim/releases/download/v0.4.4/nvim.appimage -P ~/bin
chmod u+x ~/bin/nvim.appimage
ln -s ~/bin/nvim.appimage ~/bin/nvim

Configuration

It is recommended to keep your configuration files under version control

Configuration Description
vim.sh Script to set shell aliases and the EDITOR environment variable
vimrc Vim configuration …~/vimrc
vim-config Script to deploy the Vim configuration
init.vim NeoVim configuration …~/.config/nvim/init.vim
nvim-config Script to deploy the NeoVim configuration

The configuration script will install vim-plug 2

mkdir -p ~/.config/nvim/autoload
curl -fLo ~/.config/nvim/autoload/plug.vim --create-dirs \
  https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

…and link to the configuration files in a version control repository

Modeline

Enable modelines in your vimrc:

" enable modeline magic
set modeline
set modelines=5

Read :help modeline for more examples:

# vim: filetype=sh
/* vim: expandtap textwidth=80 tabstop=8 */

Map Leader

“prefix” key to create mappings on top of it …called “leader”

# show map leader
:echo mapleader

# remap
:let mapleader = ","

In the configuration <leader> is replaced by mapleader …example:

let mapleader = ','

" make it easy to edit the Vim configuration file
nmap <leader>s :source $HOME/.vimrc
nmap <leader>c :e $HOME/.vimrc "
Keys Description
<leader>/ clear highlighted search
<leader>c edit configuration file
<leader>d toggle German spelling
<leader>e toggle English spelling
<leader>n toggle relative line numbers
<leader>l toggle invisible characters
<leader>p toggle paste mode
<leader>s source configuration file

Usage

101

Open a terminal and run the nvim command. By default Vim starts in normal mode.

  1. Switch to insert mode pressing the i (insert) key
  2. Enter some text, arrow keys and backspace work as expected
  3. Press Esc to return to normal mode

Commands starts with a double point :.

  • The write command :w <filename> followed by a file name saves the text into file, i.e. :w test.txt.
  • Exit Vim with the quit command :q.
  • Open a file using the vim command followed by a filename, i.e. nvim test.txt
  • Use the edit command :e <filename> to open another file. Use insert mode to add some text, and save the file. Open the previous file with :e, note that you can use Tab to autocomplete the filename.
  • Exit the editor with :q. Vim prevents you from losing unsaved changes unless explicitly discarded with :q!. Save and exit with a combined command :wq.

Motions

Motions …positioning of a cursor …in normal mode

0  ^    B       b  ge  H l    ew   E W      $     motions
|  |    |       |  |   |↓|    ||   | |      |
   word example-word    Example-word example.
   |                    ↑|                   |
   I                    ia                   A    insert mode

Use the keys on the home row with your right hand for cursor navigation

  • h (left), j (down), k (up) ,and l (right)
  • index finger should be positioned above j, hence should press h and j
  • middle finger is positioned over k
  • ring finger is positioned over l.

WORD vs word:

w   w w   w   w
|   | |   |   |
word. are two words
|     |   |   |
W     W   W   W
  • WORDs in Vim jargon always delimited by whitespace.
  • A word is delimited by non-keyword characters (which are configurable).
word WORD Description
w W forward, start of next word
e E forward, end of current/next word
b B backward, start of current/previous word
ge - backward, end of previous word

Line

Navigate the cursor within a line…

       0         first char in current line
       ^         first non-blank char in current line
       $         last char in current line
       g_        last non-blank char in current line
[count]+         first non-blank char of lines downward
[count]-         first non-blank char of lines upward
[count]G         first non-blank of line (default last line)
       1G, gg    got to start of file, aka first line
       %         go to corresponding (,{,[

Move cursor to sentences & paragraphs…

[count](         sentences backward
[count])         sentences forward
[count]{         paragraphs forward
[count]}         paragraphs backward

Cursor line position…

zz        center cursor line
zt        cursor line to the top
zb        cursor line to the bottom

Insert/Replace & Undo/Redo

<Esc> end insert/replace mode …back to normal mode

i                 insert text before the cursor
a                 append text after the cursor
o                 begin a new line below the cursor and insert text
O                 begin a new line above the cursor and insert text
I                 insert text before first non-blank in line
A                 append text at the end of the line
R                 replace mode (chars you type replace existing chars)
u                 undo last edit
U                 undo line
<C-r>             redo last edit

Delete

       D             delete until end of line
       C             delete until end of line, and insert text
[count]J             join lines (delete line break)
[count]x             delete chars under and after cursor
[count]X             delete chars before cursor
[count]s             delete chars and insert text
[count]S             delete lines and insert text
[count]r{char}       replace chars under and after cursor
       c[count]w     delete words and insert text
[count]dd            delete lines
       d0            delete to beginning of line
       d[count]w     delete words
       d[count]b     delete words backward
   :1,.d             delete to beginning of file
   :.,$d             delete untile end of file
       dt{char}      delete forward until {char}
       dT{char}      delete backward until {char}

Copy & Paste

Yank (aka. copy):

y          yank letter (single character)
yy or Y    yank line
y$         yank until end of line
yaw        yank word (including leading/trailing white spaces)
yas        yank sentence
ytx        yank until character x
yfx        yank up to (including) character x

Paste

p                paste from "
"{register}p     paste from specific register, i.e. 0

Folding

Built-in method of folding to…

  • …hide parts of a file for visual clarity
  • …improve searching and structural overview
  • Useful to fold large… -…text paragraphs in documents
    • …structural code segments in program languages
    • …text segments in markup files

Keys:

za               toggle folding
zc               close fold at the cursor
zo               open fold at the cursor
zR               open all folds
zM               close all open folds
zj               move cursor to next fold
zk               move cursor to previous fold

Commands:

:set foldenable 
:set foldmethod = indent

Fold methods…

  • manual …choose which specific lines to fold
  • indent …lines at the same indentation level
  • syntax …syntax highlighting defines the folds
  • expr …define fold method with regular expressions
  • marker …use special marking characters

Registers

Commands to work on the registers:

:reg       show registers
:Wipe      empty registers (cf. vimrc)

Address a register with followed by a register name "{register}

Register Description
unnamed (or default), used by y/Y/d/D/x/X/c/C/s/S
_ black hole register (content discarded, not store to viminfo)
0 last yank from y/Y
1 to 9 historical record of delete/change from d/D/c/C
- small delete register
. last insert text register
a to z named registers for users
% file name register
: command register (most recently executed)

Spelling

z=               list alternatives if word is incorrect
zG               add the word to the spelling file
<leader> d       toggle german spelling
<leader> e       toggle english spelling

Digraphs

What is a digraph in Vim?

  • Used to enter non-ASCII characters using a combination of two characters
  • Useful for characters that are not available on your keyboard
  • Digraphs available for: accented letters, currency symbols, special characters…

In insert mode Ctrl-k followed by digraph (two-character lookup code)

  • Examples: <ctrl-k> =e will insert a
  • …a digraph is a pair of characters representing another character
  • …used to enter a characters not available on a normal keyboard

Add a digraph to the vim configuration…

dig  :)  9786    " ☺  smiling face

Non-breaking Spaces

Insert with digraph <ctrl-l> <space> <space>

  • …to preserve spaces in a markdown document for example
  • Enters a space character that prevents consecutive white-space characters…
    • …from collapsing into a single space
    • & …prevents an automatic line break at its position
  • Note that non-breaking spaces are changed to normal spaces in a copy-paste operation

Table of Digraphs

List digraphs with :dig! or :digraphs! …examples…

  • …each digraphs presented with three column
  • …first …characters (digraph) to type with Ctrl-k
  • …second …the resulting characters
  • …third …decimal Unicode number to type with Ctrl-v
  • Find decimal representation (codepoint) of the character…
    • …cursor over character
    • …normal mode ga
    • …insert mode :as
Digraph Character Codepoint Description
’! ` 96 backtick …backqoute …grave accent
A: Ä 196 A with diaeresis
ss ß 223 sharp s (german)
a: ä 228 a with diaeresis
0S 8304 superscript zero
0s 8320 subscript zero
=e 8364 euro
oC 8451 degree celsius
13 8531 fraction one third

Visual Mode

v                enter visual selection mode 
V                enter line selection mode 
y                copy selection into buffer

Column selection

<C-v>            enter column selection mode
I                insert in front of cursor (Esc to apply to all lines)
A                append after cursor
<C-r>"           paste from register
c                change selection (delete and switch to insert mode)
r                replace every character in selections
d                delete 
o                toggle cursor to opposite corner

Distributions

…NeoVim configuration beyond the default. Typically to improve the experience for software development, and/or to easy adaptation by new users.

LazyVim

LazyVim 3 4 installation:

rm -rf ~/.config/nvim
rm -rf ~/.local/share/nvim
rm -rf ~/.cache/nvim
sudo dnf install -y neovim ripgrep fd-find
git clone https://github.com/LazyVim/starter ~/.config/nvim
rm -rf +/.config/nvim/.git

…recommended to run :LazyHealth after installation…

  • …enable additional functionality with :LazyExtras menu
  • …select from the bullet points pressing x and restarting

Adjust the color schema:

echo 'opts = { style = "moon" }' > ~/.config/nvim/lua/plugins/tokyonight.nvim

Preconfigured which-key 5 plugin that displays key-maps 6

  • …starts in dashboard mode 7, s restore session …n new empty bufferline
  • Normal mode …s invoke flash 8 plugin that provides seek mode
  • <space> leader to enter space mode…
    • f file/find with Telescope 9

LunaVim

LunarVim

# dependencies...
sudo dnf install -y @development-tools gcc-c++ binutils \
      curl git python3 python3-pip nodejs npm fd-find ripgrep cargo tree-sitter neovim
sudo pip3 install -y pynvim

# install...
mkdir $HOME/.local/share/lunarvim
git clone https://github.com/lunarvim/lunarvim $HOME/.local/share/lunarvim/lvim
cat > $HOME/bin/lvim <<'EOF'
#!/usr/bin/env bash
export LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-$HOME/.local/share/lunarvim}"
export LUNARVIM_CONFIG_DIR="${LUNARVIM_CONFIG_DIR:-$HOME/.config/lvim}"
export LUNARVIM_CACHE_DIR="${LUNARVIM_CACHE_DIR:-$HOME/.cache/lvim}"
export LUNARVIM_BASE_DIR="${LUNARVIM_BASE_DIR:-$LUNARVIM_RUNTIME_DIR/lvim}"
exec -a lvim nvim -u "$LUNARVIM_BASE_DIR/init.lua" "$@"
EOF
chmod +x $HOME/bin/lvim
# install syntax highlighting plugin 
:TSInstall <TAB>
# install language server
:LspInstall <TAB>

Plugins

fzf.vim

fzf wrapper plugin for Vim 10 …using vim-plug:

Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'

Mappings in insert mode:

imap <c-x><c-k> <plug>(fzf-complete-word)
imap <c-x><c-f> <plug>(fzf-complete-path)
imap <c-x><c-l> <plug>(fzf-complete-line)

Markdown

Common plugins used with Markdown…