Modes

ESC        return to command mode
i, a, o    enter insert mode
:          enter ex mode

Movement

h / l      move left / right
j / k      move down / up
w / b      next / previous word
0          beginning of line
^          first non-blank character
$          end of line
1G         go to first line
G          go to last line
:n or nG   go to line number n

Information

Ctrl-G     show file info (current line, total lines, %)

Editing

x          delete character
dd         delete line
dw, d$     delete word / to end of line
u          undo last change
.          repeat last change

Joining Lines

J          join the next line to the current one
2J         join two lines
:g/^\s*$/d delete all blank lines

In nvi, joining lines follows the historical vi behavior and normalizes whitespace when lines are joined. Unlike Vim, gJ in nvi may still insert or normalize spaces.

For more precise control, Ex-mode join commands can be used:

:j
:j!
:2;+j
:g/pattern/.;+j

Backspace Limitations

Note: In nvi, the Backspace key works only within the same line in insert mode. It cannot delete across line boundaries. Use J in command mode to join lines instead.

Copy & Paste

yy         yank (copy) line
p / P      paste after / before
"ayy       yank into register 'a'
"ap        paste from register 'a'

Search & Replace

/pattern      search forward
?pattern      search backward
n / N         next / previous match
:%s/old/new/g replace all in file
:s/old/new/g  replace all on current line

Files & Buffers

:e file    open another file
:w         write (save) file
:q         quit
:q!        quit without saving
:wq        write and quit
ZZ         write and quit (same as :wq)

Configuration

:set nu           show line numbers
:set autoindent   enable auto-indent
:set ignorecase   case-insensitive search
:set list         show invisible chars

Running External Commands (Advanced)

nvi can execute external shell commands from Ex mode. Any Ex command normally entered after : can also be executed at startup using -c.

:!command
    Run a shell command and display its output.
    The buffer is not modified.

:%!command
    Replace the selected lines with the command’s output.

Canonical examples:

# Inspect state before editing (does not modify the buffer)
nvi -c '!test -f file.txt && echo "file exists"' file.txt

# Format the entire file to 62 columns
nvi -c '%!fmt -w 62' file.txt

Rule of thumb: Use !command to inspect, and %!command to transform.

Additional tested examples

# Apply a configuration option at startup (same as :set nu)
nvi -c 'set nu' file.txt

# Enable line numbers and jump to a specific line
nvi -c 'set nu | 42' file.txt

# Jump to the last line
nvi -c '$' file.txt

# Search for a pattern (may prompt with “Press Enter to continue”)
nvi -c '/Git' file.txt

# Sort the entire file
nvi -c '%!sort' file.txt

# Prefix each line with its line number (awk)
nvi -c '%!awk '\''{print NR ": " $0}'\''' file.txt

# Format only a range of lines to 62 columns
nvi -c '1,20!fmt -w 62' file.txt

Notes:

  • Only one -c option may be specified; multiple Ex commands can be chained using |

  • Commands that produce output may display “Press Enter to continue:” before interactive editing begins

  • %!command replaces text in the buffer; changes are not written to disk until :w is used

  • Shell quoting rules apply; complex commands may require escaping

Help

:viusage      show vi command reference
:exusage      show ex command reference
:q            exit help view

Important Notes

  • Undo: u undoes the last change (repeating u toggles undo/redo between two states). Use . immediately after u to step through the change log (multi-level undo/redo).

  • No visual mode: Use counts like d3w (delete 3 words) instead of text selection.

  • Set as default editor:

# Symlink (requires admin):
sudo ln -s /usr/bin/nvi /usr/bin/vi

# OR set per-user environment:
export EDITOR=nvi
export VISUAL=nvi

Project repository: https://repo.or.cz/nvi.git

This document is maintained using nvi.