Vim stuff
My full (Neo)vim config is defined here. It is mostly commented, or otherwise self-explanatory, so I won’t touch on configuration options too much on this page.
Over the years, there have been certain learnings that have disproportionately improved my productivity in Vim. This page describes a few of them.
Grammar
The grammar of Vi is based on the composition of “parts of speech”–verbs, modifiers, and nouns–to form command “clauses” for virtually any operation, namely:
- Verbs, such as
v
(visual select),c
(change),y
(yank/copy),d
(delete), … - Modifiers, such as
a
(around),i
(inside),f
(up to and including),t
(up to but not including), … - Nouns, such as
w
(word),s
(sentence),p
(paragraph),^
and$
(start/end of line), …
Modifiers and nouns define cursor motions to which we optionally apply verbs (operators). For example, some clauses I use often are:
cf,
to change everything up to (and including) the next comma;dt)
to delete up to (but not including) the next closing bracket;viw
to visual-select a word.
Internalizing this stuff is obviously essential to get value out of Vim. The
definitive guide to cursor motions is at :help motion.txt
.
Repeating
Vim makes it easy to repeat previous actions.
;
or,
to move to the next or previous target of the last cursor motion;.
to repeat the last change;n
orN
to move to the next or previous search result.
Combinations of these are convenient for repetitive refactoring actions.
Using the changelist and jumplist
g;
andg,
move us backward and forward respectively on the changelist.C-o
andC-i
do the same for the jumplist.
As an example, this makes it less annoying to quickly add an import at the top of the file while deep within the context of a function definition a few hundred lines down.
References are :help changelist
and :help jumplist
.
Buffer switching with fzf
First of all, I have :set hidden
enabled by default, which is typically
unproblematic as long as I avoid q!
.
I spent some time with file browsers like netrw
and NERDTree
before
adjusting my workflow to use fzf.vim.
It’s a wrapper around the fzf tool, which is
a fuzzy selector on all kinds of lists: files, buffers, lines, marks, command
and search history, and even git commits.
It helps to customize the search command to ignore file patterns we don’t need
to read, e.g., via fd
which respects .gitignore
by default.
export FZF_DEFAULT_COMMAND='fd --type f'
We can define key mappings to make it effortless to open and switch between files and buffers (two keystrokes and a fuzzy match):
nnoremap <leader>b :Buffers<cr>
nnoremap <leader>f :FZF<cr>
One benefit offered by netrw
/NERDtree
is the visual view on file hierarchy,
but that hasn’t really been a big sticking point for me. (When I do want it,
!tree
serves the purpose.) On the other hand, fzf.vim
is fast and reduces
the cognitive load of file switching to almost zero.
Random thoughts
hjkl
vs. jkl;
Some people question the choice of hjkl
as the “arrow” keys in Vim since the
“left” key lies just off the home row. (The
historical reason for
this is quite interesting.)
While I find this criticism valid, I don’t mind it that much for a couple of
reasons. Ergonomically, I like having “down” and “up” on the dominant (index
and middle) fingers. Shifting the index finger one key left onto h
feels
comfortable. But more importantly, Vi(m) makes it easy to minimize, if not
eliminate, the use of arrow keys–so it doesn’t matter that much anyway.