hasenj blog

Vim through examples

Posted in hacking, tutorial by hasen on 11/04/2009

I’ve seen several people in varios places (specially stackoverflow) claim that vim increases their productivity by ten folds or whatever.

Now, I remember trying vim once or twice, and it drove me nuts. See, the thing is, with typical text editors, you type text and it’s there. But not so with vim.

In vim, to start typing yo must first press ‘i’ to go to “insert mode”. What a dumb idea, (one is forced to think), who would ever think of making a text editor that works like that? And so you just dismiss vim as an idiotic backward tool that’s still left over from the old days of terminals and main-frame: dumb keyboard, no mouse, dumb terminal screen (no colors!), etc.

But all these people saying that vim is so good, I mean, there must be something to it. So I started investigating into vim, and found this excellent article:

Why, oh WHY do those #?@! nutheads use vim?

Please go and read it! I can’t stress enough how good it is. I mean, FINALLY vim makes (at least) some sense.

The killer in that article are the couple of examples that it presents. *That’s what bought me into vim*. Examples are also a great way of learning something complicated like vim.

I mean, sure, you can google “vim tutorials” and find tons of “manuals” that explain what each key does. But that’s the /booooring/way of learning.

What I like instead is an interactive learning by example. It gives you first hand experience, withot delays, and helps your brain absorb the different concepts step by step (incrementally) by actually applying it directly, as opposed to holding it in your brain (or on a piece of paper, if you like taking notes, which I sorta doubt).

I also found this tutorial where the author pasted his irc chat log where he teaches someone how to edit with vim by example. I also found his tutorial very good.

Since I’m myself starting to learn vim and try to work with it, I thought I’d share my experience and present what I learn as a “vim by example” tutorial (or series of tutorials).

For completeness’ sake, I’ll steal some key points from the “nutheads” article.

The foundational concepts:

The first thing you need to understand about vim is that it’s different from typical text editors. The default mode is not “inserting text”, but “managing the text with commands”. You only enter “insert mode” briefly to insert text, then go back to command mode right away. Notice that “command mode” is called “normal mode”.

The second thing you need to know, is that everything in vim is designed so that you edit text without having to move your hand too much. Moving your hand too much means moving too far away from the “home raw” (the middle raw of the keyboard, asdf .. jkl;). For example, reaching for the mouse is “too much movement”, even reaching for the arrow keys is too much movement. You can do most of the editing tasks in vim without ever moving your right hand too much. The only extra movement that’s un-avoidable is reaching for the ctrl and shift keys. You might also need to reach for Esc, but it’s not unavoidable. (to change from insert mode to normal command mode, you either press Esc or `ctrl-[`, so as yo can see, you /can/ avoid reaching out for the Esc key.

Finally, you need to be fast with the keyboard, and be able to type without looking. You don’t really have to be a touch-typist (I am not anyway), but just be good enough with typing without looking too much (I still look when I type numbers).

Before we start, I want you to edit your vim settings file. On unix, that’s ~/.vimrc, on windows, it’ll be a file called _vimrc in the vim installation directory.

Add this line to what’s already in the file:
set tabstop=4 softtabstop=4 shiftwidth=4 expandtab autoindent cindent number
What is does is use spaces for tabs and makes it 4 spaces. I won’t go into why it does that (I don’t even really know myself, I just kinda googled it!) Also this will set auto indentation on (if it’s not on by default for some reason).  And finally this will make vim show line numbers.

Of course, since you’re just starting with vim (as I assume), you’ll need to edit that file with a text editor that you’re comfortable with, such as notepad++ or whatever else you’re using. Don’t try to be a smartass and use vim to edit that file!

For the rest of this tutorial, we’ll use a file that already has text in it and explore various ways to edit it using vim. Meaning we’ll not start from scratch.

So, first, opening and exiting vim:

I’m personally using gvim 7.2, so if you’re using that, open it from the start menu or using launchy or from your desktop shortcut, what ever. If you’re using the command-line version (please make sure it’s v7.2, not some 5.x or 6.x) then simpy type vim at the command line.

To quit vim right away, type :q!

: is used to enter text commands (different from the typical commands in command mode, and the text commands are referred to as Ex commands).
q is the command for quitting.
! means ignore unsaved changes.

So, the easiest way to quit vim at any time is to type :q! when you’re in command mode. If for any reason you’re not in command mode, just press Esc before typing that.

So if you’re following along but want to stop for some reason and quit vim, you know what to do.

For the purpose of this tutorial, create a text file that has the following text (again, create this file from an editor other than vim, such as notepad++):

//vim example
void main()
{
    std::cout << "ihello vimEsc" << std::end;
    return 0
}

I know there are errors there. It’s on purpose so we can correct them with vim! Now, go ahead an open that file with vim. Just type vim at the terminal followed by the file’s name (assuming you’re in its directory). If you see an empty file instead, that means you didn’t open the file, so quit vim and try again.

Moving around:

You’ll start with the cursor at the top, in command mode (normal mode).

Now, make sure your hand is rested on the home row, with the index finger of the right hand on the ‘j’ key. That key is used to move the cursor down. It’s the down arrow key :)

It may seem weird at first, but don’t we spend most of the time moving the cursor up and down? well, it’s right at your finger tips (literally!) j is down, and k is up. So move the cursor up and down, get yourself used to that.

Now, we want to include iostream library, which we “forgot”! So we need to open a new line below the “vim example” comment.

There are two ways to do that, let’s start with the dumb way:

go up to the first line, press `i` to enter insert mode, press End, then Enter, and start typing the include statement. When done, press Esc to go back to normal mode.

Now, press `u` to undo that, because we’ll do it again but differently.

Pressing End then Enter is the typical way to open new lines in typical text editors. In vim though, there’s a shortcut: press `o` to open a new line and enter insert mode. Now, type the include statement again and press Esc or ctrl-[ to go back to normal mode (command mode).

Or, you can also open a line “above” where the cursor is, using `O` (capital o). You’ll find this pattern repeated through out other commands, where the capital letter does something similar but in reverse or something.

Now, to move left and right, you can use `l` and `h`, but that’s boring and stupid. better use `w` and `b` which move by words.

w moves a word forward
b moves a word back

Try it now, move arond with w and b. Get used to it for a bit.

now, we want to change that void main to int main. so go to that line (with k and j ), move the cursor to the beginning of the line with 0 (zero), and type (in command mode) cw

cw means “change word”. It will delete the word under the cursor and put you in insert mode.

Now, type `int` and press Esc or ctrl-[ to go back to normal mode.

Commands and motions:

What you saw just now is an example of motions and commands that act on motions.

j, k, l, h, w, b are motions. They move the cursor to a new place.

c is a command (change) that acts on motions. When you press c, vim waits for you to tell it which motion to use for it.

The change command, like I said, deletes the text that you moved over with the motion, and puts you in insert mode.

See, if you are standing at the beginning of the phrase “void main”, and press w, the cursor would move to the location of “m”. The cursor moved over the word “void “. So, cw changes that block of text that the cursor moved over.

This is somewhat of a simplification, as it doesn’t always work like this. For instance, cj will delete the current line and the line below it *entirely*, not just from where the cursor was to where it would’ve been by pressing j alone.

Going in insert mode:

As you already saw, `i` is not the only way of entering insert mode. We saw that c{motion} also enters insert mode, after deleting a segment of text. and `o` also enters insert mode, after opening a new line.

Another way is `a`, which enters insert mode after moving the cursor one step forward. You can think of it as inserting “after” the cursor position.

`A` (capital a) moves the cursor to the end of the line and enters insert mode from there. We’ll use this to add the missing semicolon from “return 0”. So, go to the line that says return 0. For fun, move the cursor to the beginning or middle of the line (using h or w) just in case it already was at the end of it.

Now, press `A`, then `;`, then ctrl-[

I hope you’re following along, because it’s pointless to just read this without doing it.

Repeating commands and motions:

Motions can be repeated. For instance, 3w will move the cursor 3 words forward. Also, c2w will change two words.

I’ll list a coupe of extra commands (we won’t be using them right away, but just so you know them):

d is like c, but it doesn’t enter insert mode; it just deletes the segment.

cc will change the entire line, and dd deletes the entire line.

Actually, cc and dd don’t just “delete” the stuff, they also copy it.

You can copy stuff without deleting it, using y. (y stands for yank, which is vim-jargon for copy).
y works just like c and d, but it doesn’t delete the text; just copies it. You can paste it using p. (more on that later inshallah)

2dd will delete 2 lines
5yy will copy five lines
y5w will copy five words

Another command that can be “repeated”: {number}G will go to the line number

3G will go to line 3

:3 also goes t line 3 (in this case it’s not a repeat, it’s an Ex command .. I think so anyway)

pasting can also be repeated:
3p will paste the copied text three times

Going directly to where you want:

Suppose you’re looking at the hello vim string “ihello vimEsc”, and you want to capetalize the h in hello so it becomes Hello

simple, go to the line that contains it (I have it as line 6) by pressing 6G,or :6, or just with j and k,  then go the start of the line, using 0

Now, press `fh`, which means “find h”. This will find the first occurance of the letter h and move the cursor to it. If you happened to have another h before where you want to go, you can repeat this “find” using the semicolon ; which repeats the last `f` motion.

Now, your cursor is on h in ihello, to capetalize it, press the tilde ~ button. This will toggle the case of the letter under the cursor and move the cursor forward. (notice that you didn’t even need to enter insert mode!). This is also repeatable, so 3~ will toggle the case of the next three letters.

F will do the same as f but backwards. Meaning search backward to the first occurance of character c.
t is similar to f but it stops right before the character. T is the same but backwards.
`;` will repeat the last such motion like I already said
`,` will repeat the motion in reverse. So if you did `fh`, then `,` will search backward for h

Saving:

So maybe you know feel like you want to save this file, sure, just type :w in command mode. w is the Ex command for saving, it stands for “write”.

Summary so far:

jkhl — basic navigation
wbe — word level navigation
d/c/y{motion} — delete/change/copy text
p — paste text
u — undo
ctrl-r — redo (I forgot to mention this! oh well)
~ — toggle case
0 — go to line beginning
$ — go to line end
{number}G — go to line number

This is the end of the first part of this tutorial, I hope (inshalla) that other parts will follow soon.

Advertisements
Tagged with: , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: