Expert Level Vim

A talk by Sandy Maguire

reasonablypolymorphic.com

Vim and EMACS are the two most popular editors.

Of all time.

Why?

They introduced new ideas about what an editor should be.

EMACS

"An editor should be extensible."

This lesson has been learned and adopted.

Vim

"An editor should be composable."

Doing it wrong.

Atom's API provides the following

deleteToBeginningOfLine()
deleteToBeginningOfSubword()
deleteToBeginningOfWord()
deleteToEndOfLine()
deleteToEndOfSubword()
deleteToEndOfWord()
deleteToNextWordBoundary()
deleteToPreviousWordBoundary()

Vim is a language.

It has a small number of primitives that compose well together.

Motion.

A motion moves you from one place to another.

Right.

hello, my foxy friend
l
hello, my foxy friend

End of word.

hello, my foxy friend
e
hello, my foxy friend

Word.

hello, my foxy friend
w
hello, my foxy friend

WORD.

hello, my foxy friend
W
hello, my foxy friend

unTil.

hello, my foxy friend
tx
hello, my foxy friend

Find.

hello, my foxy friend
fx
hello, my foxy friend

End of line.

hello, my foxy friend
$
hello, my foxy friend

Sentence.

(This example is
  (a little more) complicated. See?)
)
(This example is
  (a little more) complicated. See?)

Closing paren.

(This example is
  (a little more) complicated. See?)
])
(This example is
  (a little more) complicated. See?)

Search.

(This example is
  (a little more) complicated. See?)
/ated
(This example is
  (a little more) complicated. See?)

Going backwards.

All motions have a "backwards" version.

Unless there is an obvious subtitute, the backwards version is usually capitalized.

Backwards word.

hello, my foxy friend
b
hello, my foxy friend

Counts.

Additionally, motions can also take a count.

there are lots of 'e's here
fe
there are lots of 'e's here
4fe
there are lots of 'e's here

Unsolicited motion advice.

You are doing it wrong if you ever:
Get in the habit of using the most parsimonious motion.

Parsi-motion-y.

Learning more.

:help motion

for so many more.

You can also write your own!

Motions ain't everything.

We also have operators.

Operators.

An operator is Vim's idea of a targeted side-effect.

It's a verb!

You already know some.

Delete.

d→

"Delete something."

Delete something?

What is "something?"

It's a motion!

there are lots of 'e's here
w
there are lots of 'e's here
dw
are lots of 'e's here
there are lots of 'e's here
4fe
there are lots of 'e's here
d4fe
's here
int x(bool foo, void* task) {
])
int x(bool foo, void* task) {
d])
int x(bool ) {

More operators.

There are several other operators.

Change.

Delete some text and leave you in insert mode.

c→

Use it to replace text.

Yank.

Copy some text into the clipboard.

y→

You can paste it later with

p
vim is very cool
ywP
vim is very very cool

Automatic Yanking.

Whenever you delete or change text, the text that disappeared is moved into your yank clipboard.

vim is very cool
dw4P
vim is very very very very cool

Surround text.

ys→⏣

Surround the text described by a motion with some character.

wulky wilkenson is a post-utopian
ys$"
wulky wilkenson is a "post-utopian"
10 - 6 - 4
ysf4)
10 - (6 - 4)
ysf4(
10 - ( 6 - 4 )

In general, the "open" character inserts spaces.

marvelous
ysw<span>
marve<span>lous</span>

Reindent code.

=⏣
int blah() {
return 0;
}
=G
int blah() {
    return 0;
}

Doesn't work super well for Haskell, unfortunately.

Learning more.

:help operators

for so many more.

You can also write your own!

Text Objects.

Text objects are somewhere between motions and filetype-specific syntax.

They let you describe things like:

A text object is always contiguous text.

Motions vs text objects.

You can't move by a text object, but you can operate on one.

"An argument" text object.

mconcat [a, b, c]
⨳aa
mconcat [a, b, c]
daa
mconcat [a, c]

Inside and around.

Most text objects target inside (excluding) or around (including) some structure.

mconcat ["hello", "goodbye"]
⨳i"
mconcat ["hello", "goodbye"]
⨳a"
mconcat ["hello", "goodbye"]
mconcat ["hello", "goodbye"]
⨳i]
mconcat ["hello", "goodbye"]
⨳a]
mconcat ["hello", "goodbye"]

Text objects can help if your cursor isn't in the right position for a motion.

I will bring doom cookies
dw
I will bring docookies
daw
I will bring cookies

Learning more.

:help text-obj

for so many more.

You can also write your own!

Using the best operation is valuable.

Why? Composition!

Repeat.

.

Perform the last operation again.

The wrong operation for the job.

fooBar fooBar
dtBiqux↑
quxBar fooBar
w.
quxBar quxfooBar

Doing it right.

fooBar fooBar
civqux↑
quxBar fooBar
w.
quxBar quxBar

Spend 0% of your time in insert mode.

Do exactly what you need in insert mode, and no more.

Develop the habit of pressing escape

every time you've finished a thought.

The do's and don'ts of Visual Mode.

Don't.

(with some caveats)

Visual block mode.

data Enum = Foo
          | Bar
          | Baz
⒱f=l2j
data Enum = Foo
          | Bar
          | Baz
x
Foo
Bar
Baz

Visual block mode (cont).

gv
Foo
Bar
Baz
I, ↑
, Foo
, Bar
, Baz

Visual line mode.

import Data.Map
import Data.List
import Control.Monad

-- don't touch me
Vip
import Data.Map
import Data.List
import Control.Monad

-- don't touch me
:sort↵
import Control.Monad
import Data.List
import Data.Map

-- don't touch me

Registers.

Registers are generalizations of the copy/paste clipboard.

They're "variables" you can stick text into.

Registers are named like this:

"a
"b
"c

There are lots of registers available!

They can be combined with operators:

"r⨳
three two one
"bdaw
three one
"adaw
three
0"aP"bp
 onetwo three

Use registers to keep track of lots of pieces of text simultaneously!

There is an implicit, default register used if you do not specify one.

""

This is where autoyanked text goes.

Insert mode?

You can work with registers in insert mode by pressing.

Learning more.

:help registers

for all of the magic registers (like automatic math evaluation!)

Record.

q⏣

Records your keystrokes and puts them into register ⏣.

Press q to exit again.

What use is this?

It's a code-to-data transformation.

Make the edits you want, and export/reuse them!

Moving keystrokes into the buffer.

 
qziHello world!↑ddq
 
"zp
iHello world!↑dd

This doesn't seem super useful.

(it's not, on its own)

Run macro.

@⏣

The inverse transformation! Run data as vim commands!

Better than alcoholism.

99 bottles of beer on the wall!
qbyyp⒳q
99 bottles of beer on the wall!
98 bottles of beer on the wall!
98@b
99 bottles of beer on the wall!
98 bottles of beer on the wall!
97 bottles of beer on the wall!
...
1 bottles of beer on the wall!
0 bottles of beer on the wall!

Keep macros in mind when you're doing repetitive, mechanical yet non-trivial edits.

Thanks for listening!

Questions?

SpaceForward
Right, Down, Page DownNext slide
Left, Up, Page UpPrevious slide
POpen presenter console
HToggle this help