
Vim anti-patterns - mcrittenden
http://blog.sanctum.geek.nz/vim-anti-patterns/
======
babarock
Of all the "Vim tricks" article I came across, this one is my favorite so far.

I have been a vim power user for a little over 2 years now. I never bothered
installing plugins and spent all my time instead learning ... the exact same
commands described in the article. Now I type fast, I mean real fast.

A couple more tips I find useful:

\- 'gg' and 'G' in command mode will send you to the beginning and the ending
of the file.

\- 'Ctrl-N' and 'Ctrl-P' in insert mode will auto-complete (suggestions only
come from existing words in opened buffers, for more you'd probably need
plugins).

All the other tips are _spot on_! I especially like the first one about moving
vertically one line at a time. It takes some time getting used to, but the
fact that you can repeat the 'jump' or jump back to your previous position.
Believe me, you'll fly :)

My new set of advice for blazing fast typing:

1\. Learn to touch type. The rest is meaningless without this.

2\. Repeat 'vimtutor' religiously for 10-15 days.

3\. Read this post and apply every tip until it's hard-written in your
fingers' muscle memory.

4\. ... voila!

~~~
scott_s
_'gg' and 'G' in command mode will send you to the beginning and the ending of
the file._

I've always used ':1' for the beginning and ':$' for the end. To me, the
benefit of this is that I always use the same mechanism to go to a particular
line of a file. (I often do, say, ':45' if an error is reported at line 45.)

For moving up and down large distances, I also prefer ctrl+u for up and ctrl+d
for down. There is a minor difference: ctrl+f will put the last line at the
_top_ of the screen, filling the rest with the tilde-abyss. That always
bothers me.

~~~
jdludlow
_45G_ does the same thing as _:45_ , so the people using _gg_ and _G_ can also
remain consistent with their muscle memory.

~~~
dasil003
The beautiful thing about muscle memory is you can have two similar concepts
map to completely different keys and your muscles will handle it just fine. I
happily use gg/G/:# without mental overhead.

------
vectorpush
Ok, I'm going to get a little blasphemous here, but I retain functionality of
the arrow keys because they allow me to move the cursor while in INSERT mode.
I find that ESC + [hjkl] + I to be slower than just using the arrow keys since
the distance to escape vs arrows keys is about the same for the respective
fingers (minus the cost of exiting and re-entering INSERT mode). I am
sometimes told I should remap ESC to facilitate the use of hjkl, but the
benefits seem dubious since I rarely have a need to move one or two
spaces/lines outside of INSERT mode (instead, opting to traverse my code via
line number, [], g/G, w/b, A/I, or marks).

tl;dr - arrow keys vs hjkl makes little productivity difference to an
experienced vim user (unless of course, you've baked hjkl into your workflow,
but remember that the reverse is true as well)

edit: I also find it productive to have one mental model for cursor movement
as well as selecting splits or tmux panes.

~~~
gnosis
You really shouldn't be moving in insert mode. The only thing you should be
doing in insert mode is typing new text (or erasing a few characters
immediately before the cursor that you mistyped while still in insert mode).

Once you're outside of insert mode, you have a ton of options for moving
around very quickly and efficiently. You are crippling yourself by using the
arrow keys to move character by character or line by line instead of going out
of insert mode, not to mention the time you waste moving your entire hand to
the arrow keys and back.

That said, if you really feel you absolutely must move in insert mode, may I
suggest mapping:

    
    
      control-h
      control-j
      control-k
      control-l
    

to move while in insert mode, instead of using the arrow keys. That way your
hands can remain on the home row, and you'll continue to use the familiar keys
to move around. (As for hitting the control key itself, I like to do that with
the part of my palm that's right below my little finger, so I don't have to
move my fingers from the home row -- it also makes for virtually no finger
strain, compared to using your fingers to hit it).

But you should really try to wean yourself off the bad habit of moving in
insert mode.

~~~
roel_v
"But you should really try to wean yourself off the bad habit of moving in
insert mode."

That's just dogmatism for the sake of it. There are certainly cases where it
takes less finger movement to use arrow key movement (either by character or
by word) in insert mode than it would take with switching to normal mode and
doing hjkl movement.

~~~
gbog
I have seven years of professional avg personal daily use of vim and never
bothered to leave the arrows. I don't move so often in insert mode, I just
prefer my hands the be far from each other. Ijkl maniacs should stop repeating
the same refrain over and over...

My favorite tricks: o in select mode, ctrl-y in insert mode.

Still looking for a good commenter for python (NERD commenter don't work for
me)

~~~
gnosis
_"I have seven years of professional avg personal daily use of vim and never
bothered to leave the arrows."_

There are also two-finger, hunt-and-peck typists who've been typing for 30
years.

Just because you've been doing something one way for a long time doesn't mean
it's a good idea.

------
bsmith
I just started learning vim. It would be great if someone made a game for
learning that taught some simple commands—something along the lines of,
"Perform the needed operation(s) in the fewest number of keystrokes possible."
For instance, add an attribute to an html tag with your cursor at a certain
starting point on the line. Then have a leaderboard of the shortest key-combos
used, with comments.

I'll bet more experienced vimers could learn something from this, too.

~~~
chmielewski
It's called VIM Golf. <http://www.vimgolf.com>

You might also be interested in
[http://stackoverflow.com/questions/2588481/are-there-any-
kat...](http://stackoverflow.com/questions/2588481/are-there-any-kata-for-
practice-vim)

~~~
bsmith
Thanks! That's definitely getting there. It would be even better if I could do
it in the browser, with simpler challenges to start out. Maybe a few intro
tutorials or the like.

------
Davertron
One other major feature I would mention: text-objects

text-objects are basically things Vim knows about that you can operate on with
the "verbs" of vim (d/c/y etc). So, for example, if you're inside quotes, you
can yank everything inside the quotes with yi" (to include the quotes, you use
ya"), regardless of where the cursor is inside the quotes.

For more information see :h text-objects

~~~
erikcw
And to complement them, the surround.vim plugin:
<http://www.vim.org/scripts/script.php?script_id=1697>

------
fferen
L, M, and H are also very useful for vertical movement. My general procedure
for navigating (when I don't have anything particular to find), from general
to specific, is: Ctrl-f/Ctrl-b, L/M/H, j/k).

~~~
ilikepi
I like CTRL-U/CTRL-D for scroll up/down by half a screen, as opposed to a full
screen.

~~~
silasb
Thanks, I always get frustrated doing full screen hops.

------
oinksoft
_The Escape key on modern keyboards is a lot further from home row than it was
on Bill Joy’s keyboard back when he designed vi. Hitting Escape is usually
unnecessary; Ctrl+[ is a lot closer, and more comfortable._

That's not an "anti-pattern," that's an opinion. I think C-[ is uncomfortable
as hell.

~~~
andrewl
I have jj mapped to Esc in insert mode. If you type it quickly, the two j
characters vanish and you escape out of insert mode. If you type them slowly
you get two j characters in your text. I rarely need two j's in my text, of
course, so it's a good escape key sequence, but pick whatever you want. I
chose jj because it keeps me on home row.

~~~
tygorius
Sometimes my muscle memory winds up telling me it needs. That's how I wound up
mapping both jj and ;l to Esc. The first gets used when I've finished an
insertion and am about to pause to think (it feels more emphatic) while the
second gets used when I'm in flow and know exactly what I'm going to do next.

I once read a thread discussing the topic of Esc replacements and was
astounded to learn that some people had reinvented chording: they mapped all
the permutations of h,j, and k into Esc replacements and then simply banged
all three at the same time to exit!

~~~
gnosis
Speaking of chording, there's a pretty cool vim plugin called "arpeggio", that
will allow you to map chords:

<http://www.vim.org/scripts/script.php?script_id=2425>

------
jamesrcole
I've thought for a while that Vim could analyze how a user edits and spot
repeated use of inefficienct techniques like these -- and then suggest the
more efficient alternatives to the user. Implementing this could make a nice
project.

------
tomn
These kind of articles always have a few new things in them, even of most of
it is familiar -- I guess everyone just has a slightly slightly different set
of indispensable tricks.

The most most useful Vim trick I've seen recently is "set relativenumber".
This makes Vim show line numbers relative to the current line. This is
awesome, because it lets you easily jump to any line you can see. eg. you can
get to a line marked "9" above the cursor by pressing "9k".

It can be slightly tricky to get used to if you're used to absolute numbers
(have to use gg more), but for me it's worth it.

~~~
secoif
If you train yourself, you can get good at guessing the line numbers, plus is
makes you feel godly when you correctly dd the 17 lines you want.

~~~
tomn
That, or subtracting ;)

I swear the entire UI of Vim is made to make the user feel like a ninja.

~~~
literalusername
I'm fairly sure the GP meant "dd", not "add".

~~~
tomn
Ah, I meant subtracting the current line number from the target line number to
get the number of lines to jump, instead of just guessing.

~~~
literalusername
Got it. I think we ironically tend to underestimate our ability to estimate. I
normally :set nonumber, and like secoif, I've impressed myself on numerous
occasions with how well I'm able to estimate line counts and character counts.
Give it a try -- you're likely to impress yourself too.

------
alinajaf
After around 5 years of using vim, I'm at the point now where everything in
this article and comment thread is already in muscle memory. My only advice
would be similar to whats in other comments:

* Learn to touch-type

* Learn new features slowly, giving each of them time to find their place in your workflow.

My questions for other vim power users:

* What _epic_ custom mappings do you have? Steve Losh's <Leader>ev for editing .vimrc and <Leader>sv for sourcing completely changed how I use and customize vim... are the any others with that level of impact?

* How have you mapped control of buffers/windows/tabs? Command-T buffer mode takes care of open buffers, and the default window/tab control mappings seem good enough for me, but I'm wondering if there's a nicer way for this interaction to work. Currently I've got arrow keys mapped to moving tab focus, but it feels like their might be a better way here.

* Are there any fun and creative ways you've integrated with the shell/plugins? Here are some examples I've got:

<Leader>r :!rake

<Leader>rs :!rake spec

<Leader>rl :!rake spec (test near this line)

<Leader>gs :GStatus (fugitives 'git status')

<Leader>gb :GBlame (fugutives 'git blame')

* What's a nice way to do find in project? Both vimgrep and :Ggrep are OK, but I find it weird that I'm taken out of the editor for both of those... Ideally I'd like the results to open up in a buffer which I can then browse through in some nice way.

~~~
dasil003
I've only been using vim full-time for a year and a half, but I'm slowly
ramping up on things like window and buffer management. Probably my favorite
life-changing trick is the quick macro:

nnoremap <Space> @q

It dramatically lowers the mental barrier to macro use (at least when you're
starting out with macros). Where I use to use ragex search and replace I now
instinctively go for macros, and I'm getting good at choosing the most robust
commands for the situation. The pattern of qq => /foo => cwbar => Esc =>
Space-Space-Space is incredible. It's so infinitely superior to regex search
and replace, and the fact that you can paste the macro and modify it as text
is the cherry on top.

~~~
alinajaf
Nice! I think I might add that to my .vimrc. The only thing I'd add about
macros is that I generally use them for multi-line transformations (i.e. they
usually end with `j`). This means you can record your macro and the run `n@q`
where n=the number of lines you want to run it for and q=the register where
your macro lives. This is useful for annoying, repetitive syntax
transformation tasks.

~~~
dasil003
Ah, I never have done a count on a macro before, but I do much the same thing
with the @q bind. I have my key repeat rate set to maximum, so I can just hold
down space and it flies down the lines.

------
oacgnol
Here's a good tip I picked up recently when working with numbers:

Increment a number on or after the cursor with Ctrl-A and decrement with
Ctrl-X in normal mode. Saves a few keystrokes over having to replace or enter
insert mode.

~~~
ilikepi
I've been using those more and more recently and have noticed a couple
interesting things to be aware of. First, Vim interprets a dash character
immediately preceding the number as a negative sign. (In playing around a bit
I suspect this behavior is slightly influenced by the syntax rules for the
particular filetype you're working with.) The effect of this is to flip the
behavior of CTRL-A and CTRL-X. Secondly, if the first digit of the number is
'0', Vim will behave as if the number is octal, so incrementing "07" once will
result in "010". Similarly, a prefix of "0x" or "0X" will cause a number to be
treated as hex.

~~~
johncoltrane
To avoid the "07" -> "010" problem you can add

    
    
        set nrformats-=octal
    

to your .vimrc.

------
francoisdevlin
Okay, here's one that I've been stuck with. What does Ctrl-Z do in vim, and
how do I "undo" it? I always have to kill -9 the vim process, and it sucks
cleaning up where I was.

~~~
mvanveen
tl;dr: type `fg`.

One nice thing about this setup is you can "stack" processes in the shell.

Say you're working on file_x, but file_x depends on header_file_y and file_z.
file_x makes sense on its own, so you don't want to split a new pane; you just
want to leave your workspace as it is and come back to it later.

Hit ctrl-z, and fire up vim with the new stuff you want. When you're done,
quit the current vim session and come back to your old context with `fg`.

The key observation is this stacks inductively, so you cant tumble down the
dependency rabbit hole and always come back to the context you were at
originally. This feature alone has made it impossible to ever leave console
vi.

It really came in handy in my Operating Systems class where I could fly around
the codebase an order or magnitude faster than everyone else.

If you really need to go back to a particular context %[num] lets you go back
to the nth suspended process, but this will corrupt your stack of processes,
so `fg` won't be in a clean order.

~~~
jerf
That's an anti-pattern too. You should use one of the many ways of loading up
multiple files in one vim session. I don't know what the best is, because I'm
an emacs user, but I know there are many options.

Losing access all your editing state when you move to a new file is silly,
regardless of editor.

~~~
Jach
It goes beyond just editing multiple files. I'm a huge fan of tabs in vim so I
do a lot of :tabnew filename (which has autocompletion by the way) and mapped
\tp and \tn to :tabprevious and:tabnext. I sometimes just open in a new file
buffer like emacs does, no tabs and no window splits but when I'm done with
the file I go back to the other one.

But I also use ctrl+z frequently, even more when I'm editing over ssh. Usually
because I want to do something outside of the editor window not directly
related to editing. Or it might be related to editing, it depends, I just want
a shell. I may even have forgotten which file contains what I want to edit, so
I might back out to a shell and use a find|xargs grep or ack command.
Basically any time gedit users open the terminal for something in the middle
of editing, I just ctrl+z (or open a new shell tab, but as mentioned ctrl+z is
joy on ssh where a new tab means a new connection).

So I use ctrl+z. Also :!bash is stupid, but :r!cmd should be on the page. (It
pastes the output of cmd into the file.)

~~~
johncoltrane
Why not gt and gT? All the commiting/greping/chmoding/building stuff can be
done from within Vim. You don't really need to get out of it unless you want
to launch a curses program or an interactive SSH session. Eck, even in such
cases I think it's way better to have multiple terminal windows or panes.

~~~
Jach
It's mostly habit for me not using gt and gT. I only learned :tabnext and
:tabprev when I learned of tabs at some point, and the mappings followed
shortly after. I have a lot of other \whatever bindings too. (Such as \gt
that's mapped to :tab split<CR>:exec("tag ".expand("<cword>"))<CR>)

And yeah, you can do every shell action in vim with things like :make and so
on and :! when a nice wrapper isn't pre-made, but at that point it starts to
feels a little too emacs-y for me in a lot of places and again, frequently I
ctrl+z for things orthogonal to what I was working on. Sometimes I do use
those wrappers, of course, but it's unnatural in many cases and I think it's
of questionable utility compared to mastering the command line normally or
compared to other vim features. Linux is my IDE, vim is my editor. I like to
have them work together instead of one dominating the other.

------
xxdiamondxx
It's amazing how many articles like this there are, and how I always seem to
learn something new.

------
shadowmint
Mm... Agree with those.

I use vim a lot and I'd add these as things in vim I found to be major
productivity sinks too:

\- using tabs

Simply too finiky. Create windows using :split and :vsplit. Swap between them
using control-W h/j/k/l or :winc h/j/k/l Also:

CTRL-W =, CTRL-W N-, CTRL-W N+, CTRL-W N<, CTRL-W N>

Especially useful on large visual terminals where you can have multiple files
open all at once and swap between them without touching the mouse.

\- cwBLAH . . . . .

agh. Use :%s/blah/BLAH/g

:)

------
nfm
zt, zz and zb are great too. They redraw the screen so that the line the
cursor is currently on becomes the top, middle, or bottom line of the window.

~~~
Jach
Other "z" commands (these are the ones I always get mixed up):

    
    
        :setlocal spell spelllang=en_us - turn on spell check
        z= - bring up list of suggestions
        zg - add word to dict
        zug - undo add to word
        zw - mark as wrong
        zuw - undo wrong
        :help fold
        zf<motion> - create fold (common motions '%', 'a{', 'a(' )
        zo - open fold
        zA - open folds recursively
        zc - close fold
        zd - forget fold
        zj - move to next fold
        zk - move to prev fold (up)

~~~
Nick_C
Some simple mnemonics might help you out.

    
    
      zg   g = Good word, add to personal dict
      zug  Undo Good word.
      zw   obviously, Wrong word.
      ...
      zo   Open
      zA   open All
      zc   Close
      zj   uses the same movement as the j key
      zk   ditto
    

Once you have the mnemonics sorted, sometimes you find you can remember the
others because they are the ones "left out" of those with mnemonics, like zd
doesn't have a mnemonic, so the command left over is "forget fold", so zd is
that one. After a while, muscle memory takes over.

------
Nick_C
Re using the Caps key mapped to Esc. Many people are commenting they never use
the Caps Lock key. I'm puzzled since I use it all the time. Do you not
capitalise your constants or globals? Or maybe you don't write much C or C++;
I'm not sure what the standards are for ruby etc.

Autocomplete helps, but life without a CapsLock would be awkward for me.

~~~
xiaomai
I also find it strange that so few people use caps lock, but among all my
programmer associates, I am the only one that does. That said, I hit Esc way
more often than Caps Lock, so I've swapped those two keys.

------
nymacro
This article only touches on the "c" noun. There are quite a few handy things
which you can do with it, such as delete all the text between quotes and put
you insert mode (ci").

I recommend that anyone who doesn't use this give it a try, as it saves a few
keystrokes.

PS. I guess the "i" subject is useful too for operating "inside" specific
characters.

------
goatslacker
I'm guilty of some of these anti-patterns (like for example the arrow keys)
but honestly I feel incredibly fast and productive when using ViM. I'm afraid
to drastically tweak my workflow at this point because I don't think the
optimization will be worth it.

Overall it feels like good advice but it's just not my cup of tea.

~~~
secoif
Cars? I'd have to learn to drive? What's wrong with my horse I already know
how to ride?

~~~
goatslacker
haha, I see what you mean and it does sound like I have a bad attitude. But I
feel like the overall gain I'd get from this isn't worth the time I'll spend
retraining my muscle memory.

Or in other terms, I don't think I'm going from horse to car.

Perhaps I should experiment for a month and see if it does actually make a
difference.

------
eob
Wow, it's almost like you studied a video of me coding to write that post.

Thanks. This will improve my vim-fu tremendously.

------
rhdoenges
Question for wiser vim users than myself: If I delete (say, a line comment)
with `D`, how do I paste it as a line of its own without macro trickery
involving `o<esc>p`? Is that possible?

~~~
jdludlow
You mean that you deleted it with _dd_? Can you show a before and after of
what you're trying to accomplish, because it's very likely possible. I'm just
not sure what you're trying to do.

~~~
rhdoenges
say I have a line here ( | being my cursor)

    
    
        callFunction(); |// HEY THIS IS A REALLY LONG COMMENT
    

From there, I hit D, which is the same as d$. I want to then paste it so I
have something like

    
    
        // HEY THIS IS A REALLY LONG COMMENT
        callFunction();
    

But I want to do that without entering insert mode.

~~~
mct
To break a single line into two lines on a whitespace boundary, one pattern I
find myself using often is moving the cursor to the whitespace and hitting
'r<return>'.

(The 'r' command replaces the character under the cursor with the next key
typed, without going into insert mode.)

~~~
dasil003
Oh that's a nice trick, I'll remember that one. As an avid user of J I've been
wanting its inverse.

~~~
swah
Isn't J the inverse?

------
yabai
I like :sh and ctrl-d to bounce back and forth...

~~~
literalusername
Why not ^Z and ^D?

I just recently learned to use ^D to exit a shell. It's amazing how many times
in my life I've typed out exit^M -- or worse, exot^H^Hit^M -- when all I
needed was ^D.

Edit: I now realize that you can't pair ^Z and ^D. It's either ^Z and fg, or
:sh and ^D.

------
lutusp
> The benefits of getting to grips with Vim are immense ...

This may be true, but IMHO it can't compare to dumping Vim and choosing an
editor that more efficiently exploits modern computers and their interfaces.

Many people don't realize this, but Vim arose from vi, which in turn arose
from "ed". This family of editors contains a command infrastructure meant to
avoid the waste of paper on a teletype terminal (ed's original display
device).

And how do I know this? I used ed, and an early version of vi, years ago
during my NASA engineering days in the 1970s, while designing part of the
Space Shuttle. All those separate vi modes -- insert, delete, move the cursor,
and others -- originated in ed, at a time when it was a priority to assist the
operator while typing blind, before wasting another 11 inches of paper just to
see how it all turned out. The first version of vi was screen oriented, but it
carried over the original separate modes, and kept them separate.

When I wrote the first version of Apple Writer
(<http://en.wikipedia.org/wiki/Apple_Writer>) in 1979, people had a hard time
adjusting to an editor that allowed you to insert, delete and move the cursor
without changing modes. It seemed a rather simple idea to me, but at the time,
among vi users, it was met with shock and disbelief.

And here we are, over 30 years later, and people are still learning vi/Vim, as
though it represents cutting edge technology.

I think we should hold a wake for vi/Vim, and maybe we should invite Fortran
to the party.

~~~
cageface
I've never understood this obsession with editing efficiency among
programmers. When coding I spend about 90% of my time thinking about what to
type. A good IDE that really understands the _structure_ of my code without
twenty flaky plugins is worth much more to me than saving some keystrokes.

~~~
jerf
Typing efficiency I'm "meh" on; don't get in my way, but I'm not too worried
about it. I've tried tons of autocomplete of every kind and tend to just turn
it all off. Navigational efficiency is very important, though. If I want to
look at a bit of code, fractions of a second count if I'm going to stay in
flow.

This is very much personal opinion, but what I found with autocomplete is the
time I'm typing the code I'm also using to think about it. Even on those
surprisingly rare occasions where I manage to set up autocomplete that is both
fast and accurate, it still didn't speed me up much. If I'm thinking so far
ahead of my typing that I'm actually frustrated about the typing, that is
typically an absolutely enormous code smell that something is very wrong, and
I need to address the redundancy immediately.

~~~
cageface
I think it depends somewhat on the language. For Ruby I prefer Emacs and don't
see much benefit in autocomplete. But for Objective-C & Cocoa, which is
admittedly a somewhat extreme case, autocompletion is a godsend.

But autocomplete is only one feature among many I appreciate in a good IDE.
I'd also hate to give up a good visual debugger with integrated breakpoints,
direct links from compile errors, etc. I know you can hack a lot of this
together in Vim or Emacs but after 15 years of doing just that I don't miss it
when I'm using IntelliJ or XCode.

