I think I know vim pretty well. I’m at the stage where I’m the crusty old man
complaining that most vim emulators (like the VSCode vim-plugin) don’t have
support for the expression
register or using
i_CTRL-X_CTRL-F
to
autocomplete file names.
I figured I’d write up some of the more esoteric vim/neovim features that I use
on a regular basis, since these have a high impact on my workflow but I don’t
see them on most “top vim commands” lists. If you don’t know vim, I’d recommend
typing vimtutor
into any terminal, going until you get bored, and then coming
back here.
NOTE: I’m going to make each trick a heading, so you/I can link to it
ctrl-z
and fg
This isn’t technically a vim command, it’s just a plain shell send-to-background keystroke. But I use it so, so, much. ctrl-z will send vim to the background. Faster than quitting and reopening vim, no lost context, handy for working in the terminal (it’s painful using :! for anything semi serious)
(f
or F
or t
or T
) then ;
then .
First jump to a letter (with f
or F
or t
or T
) and do some action. Then
repeat the jump with ;
and repeat the action with .
Now spam them like
;.;.;.;.
(the ;
and .
keys are close together on a QWERTY keyboard,
making this nice and fast) And now you’ve done your operation on the entire
line without thinking about vim-style regex. For example, If I’ve got this
line:
struct.member = struct.othermember + struct.foo - struct.bar;
And I want it to become
struct->member = struct->othermember + struct->foo - struct->bar;
I could use a regex on that line
'<,'>s/\./->/g
But I’ve got to remember to escape the .
and generally vim’s regex doesn’t
roll off the tongue. But I could also do this:
0f.s->^[;.;.;.
Which can be explained like:
0 go to the start of the line
f. go forward, until the cursor is over the first `.`
s delete the character under the cursor and enter insert mode (AKA substitute)
-> enter the literal characters `->`
^[ escape from insert mode to command mode
; repeat the last fFtT command (in this case, go to the next `.`)
. repeat the last "action" (in this case, substitute `.` with `->`
;.;. go to next `.`, substitute with `->`, repeat
And lets you stay “in vim mode” instead of having to recall vim’s regex, you
can just use regular vim commands to do what you want. Using fFtT;.
is like
baby’s first macro.
Capital-letter macros
Macros are obviously a big one, but “recording” to a capital letter macro (like
qQ
instead of qq
) will append whatever actions you perform to the macro (in
this case, the q
macro). Super nice for quickly adding something you forgot, or
monkey patching a badly recorded macro.
Special registers ""
and "%
Special registers are handy. Use CTRL-r
to insert the value of a register.
""
Contains your last yank"%
is the filename. SoCTRL-r%
in insert mode will fill out the name of whatever file you’re editing.
Expression register "=
The calculator/expression register ”= is also really good. Use CTRL-r
in insert mode to
get a simple calculator, but if you have an expression visually selected then
the following will evaluate the expression:
cCTRL-r=CTRL-r"CTRL-j
Insert mode commands
Insert mode command are very nice:
CTRL-h
to backspace (keeps your fingers on the home row)CTRL-j
orCTRL-m
for a newline (keeps your fingers on the home row)CTRL-w
to delete the word (faster than tapping backspace a bunch)CTRL-u
to delete the line (faster than tapping backspace a bunch)CTRL-k
for mnemonics of funky characters. For example,CTRL-k:e
gives you ë,CTRL-k12
gives you½
, and a lot more which are all very intuitive. Most times I just mash various two-character combinations to get what I want, like+-
for ± orp*
for π. See:digraphs
for a list of examplesCTRL-x CTRL-f
to autocomplete a filename in the current working directory
See :h ins-special-keys
for lots more
Remapping CAPS LOCK to CTRL
at the OS level
Remapping caps lock to control at the OS level makes a lot of sense, for all
shortcuts on your computer, and it means you can very easily exit out of insert
mode with caps lock + [
(keeping your fingers on the home row).
CTRL-a
and CTRL-x
Using CTRL-a and CTRL-x to increment/decrement a number is useful, but even
more so when paired with gCTRL-a
and gCTRL-x
, which (when used over a visual
selection) will increment the first line by 1, the second by 2, etc. Making it
really easy to get a numbered list.
Faster macro invocation
On macOS I’ve got alt+character nnoremap
’ed to the @
character. So typing
alt-r
is the same as @r
, with the difference being that alt-r
is slightly
more ergonomic:
" Remap the ALT key so that it is used to trigger macros. For example, ALT-q is
" equivalent to @q in normal mode. This requires some finagling because in
" MacOS, ALT-q sends the character "œ" and not a literal ALT and then a literal
" q.
" In iTerm2, you'll need to adjust the settings in profiles>keys>general>left
" option key so that iTerm2 sends a literal ALT.
"
" normal key: a b c d e f g h i j k l m n o p q r s t u v w x y z
" alt+key: å ∫ ç ∂ ´ ƒ © ˙ ˆ ∆ ˚ ¬ µ ˜ ø π œ ® ß † ¨ √ ∑ ≈ \ Ω
nnoremap å @a
nnoremap ∫ @b
nnoremap ç @c
nnoremap ∂ @d
nnoremap ´ @e
nnoremap ƒ @f
nnoremap © @g
nnoremap ˙ @h
nnoremap ˆ @i
nnoremap ∆ @j
nnoremap ˚ @k
nnoremap ¬ @l
nnoremap µ @m
nnoremap ˜ @n
nnoremap ø @o
nnoremap π @p
nnoremap œ @q
nnoremap ® @r
nnoremap ß @s
nnoremap † @t
nnoremap ¨ @u
nnoremap √ @v
nnoremap ∑ @w
nnoremap ≈ @x
nnoremap \ @y
nnoremap Ω @z
Various g
commands
gf
open file under your cursor in vim.gx
open URL under your cursor in browser.g&
repeat last:s
command for entire file.g*
/g#
like*
/#
but without\<
\>
.ge
opposite ofe
, go backwards through the last character of each word.gv
select whatever your previous selection was (useful after pasting something).gCTRL-g
get a word count for the current file, something like:Col 67 of 67; Line 182 of 195; Word 1120 of 1168; Char 6259 of 6611; Byte 6328 of 6680
See :help g
:cq
:cq is useful when writing a
commit message in git (ie after git commit
)
It will exit without saving and return a non-zero error code, causing git to abort the commit.
Using your terminal :!
You can also pipe commands between vim and the shell. So if you’ve got some text:
a,b,c,d
123,312,513,543
23,3121312,53,543
123,32,513,53
123,312,53,53
And you want to align all the values into a table, you can visually select the
lines and then type :!column -t -s,
(-t
will create a table, -s,
will use
,
as the separator):
a b c d
123 312 513 543
23 3121312 53 543
123 32 513 53
123 312 53 53