Mastering Vim Quickly

Everything in this section taken from the “Mastering Vim Quickly” book by Jovica Ilic

Ch 8 Undo and Redo

Temporal undo/redo

ea[rlier]: go back in time (temporal undo)

lat[er]: go forward in time (temporal redo)

examples:

command description
earlier 2d undo changes in last 2 days
ea 3h
ea 1m
later 5m redo changes in last 5 minutes
lat 15s
earlier 3f undo last 3 file states (buffer writes)

Undo branches

Vim creates an undo branch on every u, representing state of the file before executing undo.

g-/g+: move between these branches

Persistent undo

Vim undo/redo work in current session but go away once the session ends.

We can create an undo directory where vim stores hidden files that stores undo/redo between sessions.

$ mkdir ~/.vim/undodir

Add to .vimrc:

set undodir=~/.vim/undodir

Ch 14 Macros

Macro workflow:

  • qa starts recording actions into register a
  • q stops recording
  • @a executes the macro
  • @@ executes last executed macro
  • 10@a executes the macro 10 times

Execute macro in multiple files

Argument list of files:

:args app/models/*.rb

Execute macro in register a using Normal mode:

:argdo normal @a

Save all buffers:

:argdo update

Editing a macro

  1. "<register>p to insert on an empty line
  2. edit
  3. ^"<register>y$ to move cursor to beginning and copy the macro into register

Recursive macros

Intuitive meaning.

Example recursive macro: qaI"<esc>A"<esc>j@aq

Explanation:

  1. qa record into register a
  2. I"<esc> insert " at beginning of line and go back to normal mode
  3. A"<esc> insert " at end of line and go back to normal mode
  4. j@a go to next line and recursively call macro
  5. q stop recording

Using the norm command

norm[al] in Execution mode (:) can be used to conditionally apply macros

Examples:

  • :6,16norm @v execute macro v on lines 6 to 16
  • :10,$norm @i execute macro i on all lines >= 10 (to end of file)
  • :%norm @m execute macro m on all lines
  • :g/pattern/norm @o execute macro o on all lines matching pattern
  • :norm @a when there are visually selected lines executes macro a on those lines

Ch 18 Effective multiple file editing

Vim has built in commands to access different lists so we can execute commands in bulk

  • :argdo argument list
  • :bufdo buffer list
  • :windo window list

The execute and normal commands

exe[cute] evaluates a string as a Vim command.

norm[al] takes a sequence of keys and treats them as a Vim command in Normal mode.

norm[al]! ignores personal key mappings.

bufdo examples

Paste to the end of each buffer
:bufdo exe ":norm Gp" | update
  • :bufdo over all active buffers
  • exe executes the following string as a command
  • ":norm Gp" use normal mode to go to end of file and paste
  • | update use | to execute another command update, which writes the changes (can also use w)

Note: difference between :w and :up[date] is that :up[date] only updates the file mtime if required, whereas :w always updates the mtime

Execute macro over each buffer
:bufdo exe ":norm! @a" | w

argdo examples

All :bufdo examples apply to :argdo as well

Useful commands:

  • :args show args
  • :args /path/to/files/*/* replace old arglist with new one
  • :arga[dd] /path/to/file.txt add to arglist
  • :argd[elete] /path/to/file.txt remove from arglist
  • :argdo update save changes
  • :argdo undo undo last operation
Find and replace across files with external commands

Get all files with the string Bad (can also use git grep -l instead of ag -l)

:args `ag -l Bad`

Replace Bad with Good across those files, asking to c[onfirm] each match

:argdo %s/Bad/Good/gc | w
Find and replace across files without external commands

After adding files to the arglist

:argdo %s/Bad/Good/ge | w

The e flag tells vim not to issue an error if the pattern is not found.

windo

:windo only affects currently visible buffers.