vim craft

(How vim ruined me for "better" editors.)


Why is vim so difficult for new users?
vim is modal.
Most editors have one mode ...
vim has many modes:
  • Normal mode (aka "command" mode, for moving around, cutting, pasting, ...)
  • Insert mode (self-explanatory, until you press )
  • Replace mode (overwrite, except when you press )
  • Cmdline mode (for single ex commands and searching)
  • Ex mode (for multiple ex commands, i.e., line-oriented "ed-style" editing)
  • Visual mode (not to be confused with what :visual does)

    When in doubt, press .
vim commands are case sensitive.
Lowercase moves one line down.
Uppercase joins lines.

will be your undoing.

Lowercase (undo) is your friend.
Uppercase maybe not so much.

The same key might do very different things in different modes.
In insert or replace mode, starts a new line.

In normal mode, moves to the first non-blank character on the next line.

There are an overwhelming number of command keys to learn.
You do not have to learn them all,
but the more you master...

Many of the key assignments make no sense at first,
until you realize it might be about efficiency,
from a time before mice, screens, or arrow keys.

For example, having all the "arrow" keys ( )
on the home row means they are within easy reach.
You can always find them, no matter what keyboard ASR 33
happens to be under your fingertips.


But ... help is available!

CommandDescription
:helpLearn how to navigate vim's help system.
:help vim-modesLearn more about vim's modes.
Toggle between help and editor window.
:qQuit help.
:help windowsLearn how to use multiple windows.

vim's origin story
  1966  QED          (Quick EDitor)
        :
  1969  ed           (Pronounced "E D", not "ed".)
        :
  1975  em           (Editor for Mortals)
        :
  1976  ex           (EXtended)
        :
  1979  vi           (VIsual mode for ex)
        :
  1990  :.... elvis  
        :
  1991  vim          (Vi IMproved)  <--- WE ARE HERE
        :
  2015  neovim
  
A blast from the past ... ed
Use cases...
  1. A disgruntled co-worker deleted all the text editors (vim, nano, ...), and broke the package manager, on her way out the door.
  2. You've been assigned to disinfect a Unix box that was connected to the Internet before security patches were applied. It got compromised, and certain binaries (ls, ps, netstat, vi, ...) were replaced with lookalikes that hide the intruder's activities.
  3. You just need to script some repetitive editing operations.
Just dive right in ...
$ ed
Then read the documentation.
$ man ed

$ info ed


Start again, better informed.
$ ed
Fix the error, if needed.
$ ed roll
29
How about a random number between 1-6?
$ ed roll
33
How about several?
$ ed roll
46

How about sorted and on the same line?
$ ed roll
92

Finally, we make the code pretty!
$ ed roll
112

ed | ex | vim Rosetta stone
ed ex vim Description
,n set nu[mber]
%p
:set nu[mber] Display entire buffer with line numbers.
i i O Insert above current line.
a a o Append below current line.
. . Exit insert mode.
s/^/text/ s/^/text/ 0itext Insert text at beginning line.
s/$/text/ s/$/text/ Atext Append text to end of line.
d d dd Delete current line.
j j J Join current and next line.
/re /re /re Search for regular expression re.
?re ?re ?re Search backward for re.
g/re/p g/re/p :g/re/p Print every line matching re.
s/re/replacement/ s/re/replacement/ :s/re/replacement/ Replace first re match with replacement in current line.
s/re/replacement/g s/re/replacement/g :s/re/replacement/g Replace all re matches in current line.
%s/re/replacement/g %s/re/replacement/g :%s/re/replacement/g Replace all re matches in document.
u u u Undo last command.
w [filename] w [filename] :w [filename] Write buffer to filename.
q q :q Quit (exit) editor.
Q Q :q! Quit without writing buffer.
wq [filename] wq [filename] :wq [filename] Write and quit.

Fun facts
  • sed was based on the scripting features of ed.
  • grep was inspired by ed's g/re/p command.
.vimrc suggestions

CommandDescription
set nocompatible50 levels of undo/redo, ex command line recall, and more!
set showmodeShow when vim is in INSERT, REPLACE, or VISUAL mode.
set numberShow line numbers.
set rulerShow line and column where cursor is at all times.
set incsearchEnable incremental search.
set nohlsearchDisable search highlighting.
set ignorecase smartcaseIgnore case if search pattern is all lowercase.
set tabstop=8Place tabs at proper location.
set shiftwidth=4Set indent level to 4 spaces.
set expandtabInsert spaces, not actual characters.
set autoindentEnable autoindent.
set smartindentIndents correctly in code. Mostly...
set cindentStricter rules for C code.
set showmatchHighlight matching parentheses and braces.
syntax offTurn off syntax highlighting.

vim visual (selection) mode

Using visual mode is a three part process:
  1. In normal mode, begin selection with , , or .
  2. Move to end of selection (includes character or line under cursor).
  3. Finish selection with a visual mode command (see below).

Normal mode commandDescription
Lowercase Begin character-wise visual selection mode.
Uppercase Begin line-wise visual selection mode.
Begin block-wise visual selection mode.

Visual mode commandDescription
Lowercase Delete selection.
Lowercase Yank (copy) selection.
Lowercase Put (paste over) selection.
Uppercase Convert selection to uppercase.
Lowercase Convert selection to lowercase.
, Shift selection left, or right.
Exit visual mode.

Try it!
CommandDescription
:help visual-modeLearn about vim's visual mode.

vim keyboard macros

Syntax:
:[mode][nore]map  keys  commands
:[mode]unmap  keys

("nore" prevents recursion -- more on that soon.)

modemodes the macro is active for
 normal and visual
nnormal only
vvisual only
iinsert only
ccmdline only

Try it!
CommandDescription
:help QShow what uppercase should do in normal mode.
:map QShow normal and visual mode mappings for uppercase .
:unmap QRemove normal and visual mode mappings for uppercase .
:map <c-a> 0 Map to move to beginning of line (in normal mode),
or select to beginning of line (in visual mode).
:map <c-e> $ Map to move to end of line (in normal mode),
or select to end of line (in visual mode).
:nmap x ddMap to delete current line (in normal mode).
:nnoremap \ xNon-recursively map to delete current character (in normal mode).
:nmap # 0i# <esc>0jMap to comment out a line.
:mapShow key mappings for normal and visual modes.
:help map-modesLearn about vim's map commands and modes.
:help map-examplesGet some more inspiration!

vim registers
Obligatory vim command syntax review...
[register] [count] command

Fun fact: You're already using registers!
RegisterUsage
"" The "unnamed" register receives text from delete, change, and yank commands, even when another register was explicitly specified, and provides text for put commands where a register was not explicitly specified.
"0 Receives or provides text from the last yank command.
"1 .. "9 The "numbered" registers receive or provide text from the last 9 delete or change commands that did not explicitly specify a register.
(See :help quote9 for exceptions.)
"- The "small delete" register recevies or provides text from the last command that deleted less than one line and did not explicitly specify a register.
"/Provides the last search pattern. (It is used by the n and N commands.)
".Provides the last text inserted.
"%Provides the current filename.
"*Provides the last X11 selection.
"+Receives or provides the current X11 clipboard.
"a .. "z
"A .. "Z
The "named" registers receive or provide text only when explicitly specified.
The uppercase variants append to their previous contents.
"_The "black hole" register prevents delete and change commands from affecting other registers.
Try it!  
CommandDescription
"%PPut current file name.
"+3yyYank 3 lines to the X11 clipboard.
:reg[isters]Dispay contents of all registers.
:help registersLearn about vim's registers.

Continuing education...
  $ vimtutor     # Possibly the best half hour you could invest.
  
  $ gvim         # Pay particular attention to keyboard shortcuts in the  menu.
  
  $ man vimdiff  # Recommended tool.

  $ stat -c '%i %N' {/bin,/usr/bin,/etc/alternatives}/{ex,view,vi,vim*} 2>/dev/null | sort -n
  
  Learn Vimscript the Hard Way by Steve Losh