---
title: vim
date: 2010-11-17
techne: :done
episteme: :deprecated
---

~~~
#!sh
alias evil="for s in {1..3}; do 
  echo -n 'VI! '; 
  sleep .666; 
  done; echo; vi"
~~~

A GNU Dawn
==========

Below is a little write-up of the vim features I used often enough to
value them, but still rarely enough to constantly forget them. However, during
the fall of 2010, I eventually overcame my hatred of Lisp and converted to
emacs. Maybe I'll write a similar list for it one day. Or I'll just wait until
emacs ships with "M-x write-article-based-on-todo-list".

Enjoy the (untouched) article nonetheless.

Ye Olde Vim confige
===================

Hello, my name is muflax, and I am a vim addict. My ~/.vim directory is about
6MB large and contains 20,000 lines of code[^0]. I use so many features, that I
often forget about some of them. Heck, I implemented tab completion for code 3
times because I forgot that I already did it each time and only noticed it
months later during a cleanup!

[^0]: To be fair, I store every plugin there and never install anything
    system-wide so that my setup is mostly independent from the current machine.

It couldn't go on like this. My memory couldn't keep up with this. I probably
only knew half the hotkeys I have mapped myself. I dream of vim; have terrible
nightmares because I can't remember how to automatically create a list of
ascending numbers. I have spent more time this year implementing or tweaking
something in vim than programming in general. (Ok, this is slightly exaggerated.
But only slightly.) 

Now, if I were sane, I would cut down my config a lot, or switch to a GUI editor
(TextMate is very nice) that remembers my features for me, or just switch to
emacs[^emacs] already, because I'm at least halfway there anyway.

[^emacs]: But why not emacs? To be honest, emacs is great. It is easily the
    second-best editor and some parts of it outshine vim easily, like process
    integration or the higher level of semantic awareness. I only have two problems
    with it. 

    The first is I-know-what's-best-for-you syndrome, i.e. emacs often
    enforces a specific behaviour that it thinks is right. Well, most of the time,
    emacs _is_ right, but occasionally it just stands in my way. The most annoying
    thing was the lack of a permanent visual mode as in vim aka the ability to move
    my cursor freely to any position on the screen. 

    The second problem is LISP. I hate LISP. I refuse to learn it. I refuse to
    deal with people that like it. (But afaik there may be some ports to a sane
    language, so maybe this point is moot nowadays.)

Luckily, I am not sane. So instead, I just made another SRS deck, and put in
all those features, using a card each, and then just learned them like
everything else. Hey, I have fully outsourced my long-term memory, I might as
well use it for stuff that matters!

And to cultivate this deck, I needed a complete list of all vim features I
currently (should) know. All of them! So here it is, in no particular order,
including all relevant plugins. You can just google them or check my [Config][] on
github. 

I'm gonna leave out all the very elementary features everyone knows, like / or
dd, and some of the hotkeys are mine, obviously, not standard. I'll also skip
over config-only features because you don't need to remember those. See the
awesome help for what they do.

The List
========

1.  **ci(** aka change inside, deletes everything the current set of () and puts
    you into insert mode. Works the same way for all closures, like **ci"** or
    **ci{**, or use **cib** for the current block.  Apart from **c** for change,
    this also works with **d** and **y**.  **d%** deletes everything until it
    hits a (matched) parenthesis.
    
2.  **yankring** plugin, implements a yankring like the killring in emacs.
    Automagically manages your buffers when copying or deleting something,
    allowing you to cycle through it when yanking it back into the text. Very
    useful when cut-and-pasting multiple parts. Use just like normal yanking,
    C-p to cycle, :YRShow for a list. Also shares yank buffer among all
    instances (omg its heavan).

3.  **C-x** and **C-a**, in CM, de/increments the currently
    selected value. See my config for an enhancement to make it work
    with boolean values, too (using **gy**).

4.  **gq**, re-formats the selection, breaking lines and so on.

5.  **\>**, **<** and **=**, on a selection, indent
    right/left/automagically. Great for pasting or reworking loops.

8.  Some **ctags** features. **[i** shows the first line contain
    the word under the cursor (good to look up a declaration),
    **C-w i** opens it in a new window, **C-]** (and for me,
    **C-Space**) jumps to the definition of the current keyword,
    **:tag [keyword]** dito.

9.  **folding**, to show/hide code levels. I put fold in and out
    both on **Space** and fold according to syntax. Useful for complex
    source code.

10. **:bprev** and **:bnext** to switch buffers (I put them on
    **F1** and **F2**), also **:tabprev** and **:tabnext** (**gT** and
    **gt**), like in vimperator, for tabs.

11. **NERDtree** plugin, **:NERDtree**, as a nice integrated file
    manager. Occasionally useful.

12. **:jesus**, because Jesus saves. Your file. (Uses **cmdalias**
    plugin, dito the next one.)

13. **:pd** or **:perldo**, for a more powerful regex engine.

14. **WW**, to just save a file. Faster than **:w<CR\>**.

15. **pastetoggle**, on **F3**, to toggle paste mode, i.e. yanking
    text with or without formating it.

16. **F11** and **F12** to automagically **underline** the current
    line, used in my notes for headers. See my config.

17. **Align** and **AutoAlign** plugin, to align multiple lines in
    intelligent ways. I mostly use it to align multiple variable
    declarations around the = sign, which Align even does automagically
    for some languages. Use on a selection with **:Align=** or any
    other sign.

18. **BufExplorer**, to get a nice list of open buffers, use with
    **\\be**. Builtin, of course, is **:ls**, which is also nice.

19. **a.vim**, alternate between source/header files via **:A**.
    Also, **\\ih** and **\\is** jumps to header/source file under the
    cursor.

20. **matchit** plugin, extends the **%** command, which jumps (in
    order) to the innermost parentheses on the left, then its match on
    the right. **matchit** enables it for tags and so on, too.

21. **taglist** plugin, a nice sidebar for method names and shit,
    like in IDEs. Use with **:Tlist**. Occasionally useful.

22. **template** plugin, uses file templates instead of blank files
    for certain file types.

23. **"\*y** and all related yank operations. Yank into the X11
    clipboard, so that you can share among vim instances. **yankring**
    already covers this, but still useful sometimes for other apps.
    Requires vim to be compiled with X11 bindings.

24. **\*** in CM, searches for the word under the cursor.

25. **gU** + motion, **gUU** for whole line, turns it uppercase.
    **gu** for lowercase, **g\~** to toggle it.

26. **J** and **gJ**, to join lines, removing (or not) spaces as
    necessary.

27. **R** to enter replace mode, nice for changing constants. I
    can't believe how late I learned that one.

28. **!cmd**, filter text through cmd. Very useful with selecting
    some text in visual mode and then doing a **!sort** on them.

29. **:&** repeats a search, allowing you to change its flags (add
    a **/g**, for example). Also, **:%s///** for the whole file, btw.

30. **:sm/foo/bar/** or **:s/\\vfoo/bar/**, to activate regex
    magic, like () and so on. Far nicer than vim's standard, but
    **:pd** is even nicer.

31. **:retab**, replace tabs with proper whitespace.

32. **vimdiff $file1 $file2**, use vim as a diff tool. Hopefully
    you know this one already, use **do** and **dp** to move chunk
    here/away (obtain / push).

33. **:vimgrep**, grep inside vim. D'uh.

34. **C-v** enters visual block mode. I always forget this one when
    I need it.

35. **{**and **}** move backwards/forwards through paragraphs, dito
    **(** and **)** for sentences. (I really use the cursor too much
    instead of vim's better syntactic movements.)

36. Speaking of movement, **b** and **w** move to the next word on
    the left/right, **e** moves to the end of the word. Use those,
    like, a lot.

37. **daw** deletes the current word (from anywhere in it), **das**
    the current sentence.

38. **g;** and **g,** cycle backwards/forwards through your
    changelist, putting your cursor there. So you can go somewhere
    else, look something up, then jump right back to where you where.
    Dito **C-o**, **C-i** and **:jumps** for jumps instead of changes.
    Awesomesauce.

39. **m[register]** saves the current location in a register,
    **\`[register]** jumps back to it, **\`\`** jumps to the last
    location.

40. **u** and **C-r** are undo/redo, **U** undoes all changes on
    the current line. So far, so good. But vim also has a powerful undo
    tree. **:undol** shows the undo list, and **g-** and **g+** move
    you along it. You can also use **:earlier** and **:later**, in
    combination with either a count or [n]s, [n]m or [n]h for a time.
    No if only vim could merge branches like Photoshop can...

41. **f[char]** and **t[char]** move you on/before the next
    occurrence of [char] on the right, **F**and **T** on the left.
    **;** and **,** repeats this movement in the same/opposite
    direction. Of course, can be combined with deletion and so on.

42. **:make** executes make and jumps to the first compile error,
    if any. (But I normally prefer to have a second terminal open for
    that.)

43. **surround** plugin, mostly provides keys to change or remove
    surroundings (blocks, quotes or tags). Use like **ds"** to remove "
    quotes, **dst** to remove text block, **cs"(** to replace "" with
    () and **ys[motion]{** to wrap something in {}. Works in visual
    mode, too, of course.****(Also install the **repeat** plugin, to be
    able to repeat the surround commands. Works like normal repeating.)

44. **FuzzyFinder** plugin, plus the **FuzzyFinderTextMate**
    plugin, to have far nice fuzzy matching of buffers, files and so
    on. I have **\\b**, **\\f** and **\\o** mapped to buffers, files
    and everything (as in TextMate). Incredibly useful. (See
    [here][fuzzyfinder] for installation instructions.)

45. **NERDcommenter** plugin for more intelligent commenting. Most
    importantly, **\\cSpace** to toggle commenting, **\\cc** to comment
    out, **\\cu** to remove comments.

46. window movement, most importantly:**C-W w** (and**\\\_**) to
    jump to the next window, **C-W s** to split horizontally, **C-W v**
    to split vertically, **C-W <** / **\>** / **=** to increase /
    decrease /equalize window sizes.

47. **:set spell** for spell checking, **]s** and **[s**to move to
    the next/last misspelled word, **zg** to add to the dictionary,
    **zug** to undo it, **z=** for suggestions.

48.  **SuperTab** plugin, to tab-complete *everything*. Yes,
    everything. It's pretty smart and works well with omnicomplete.
    Using my options, it works just like them cool IDEs.

49.  **UltiSnips** plugin, steals the snippet function from TextMate and greatly
     enhances it, so you can tab-complete code fragments into common structures. Great
     speedup! Use tab to expand snippets and Shift-Left / Shift-Right to jump to
     the next part of the snippet. 
     (I also tried **XPtemplate**, which is too ugly and hard to use, and
     **snipMate**, which I used previously, but doesn't have recursive snippets.)

