I'm learning new commands in VIM all the time, but I'm sure everyone learns something new once in a while. I just recently learned about this:

zz, zt, zb - position cursor at middle, top, or bottom of screen

What are some other useful or elegant commands you wish you'd learned ages ago?

+9  A: 

ZZ (works like :wq)

About cursor position. I found that cursor which always stays in the middle of screen is cool

set scrolloff=9999

interesting. I'll try it out.
Stefano Borini
+7  A: 

^P and ^N

Complete previous (^P) or next (^N) text.

^O and ^I

Go to previous (^O - "O" for old) location or to the next (^I - "I" just near to "O"). When you perform searches, edit files etc., you can navigate through these "jumps" forward and back.


Press ma (m- mark, a - name of mark). Later to return to the position type `a

Wow, I didn't know about ^O and ^I: that is awesome. Might be worth including `:help jump-motions` etc in your answer in case anyone wants more information.
+16  A: 

^X-F completes using filenames from the current directory. No more copying/pasting from the terminal or painful double checking.

^X-P completes using words in the current file

:set scrollbind forces one buffer to scroll alongside another. e.g. split your window into two vertical panes. Load one file in each (perhaps different versions of the same file). Do :set scrollbind in each. Now when you scroll in one, both panes will scroll together. Ideal for comparing files.

Brian Agnew
How to disable the scrollbind once I've enabled it?
*jinxed_coder*: `:set noscb` to turn it off and use `:set scb` to turn it on (not `:scrollbind`). `:h scrollbind`
Whoops. Corrected for ':set scrollbind'.
Brian Agnew
**^X-P** completes with preference to previous words in the file, **^X-N** with preference to the next words in the file.
+3  A: 

:shell to launch a shell console from Vim. Useful when for example you want to test a script without quitting Vim. Simply hit ^d when you done with the shell console, and then you come back to Vim and your edited file.

+2  A: 

^y will copy the character above the cursor.

... and ^E will insert the character below the cursor
too much php
+1  A: 
move cursor down

This will take all text between where you set the a mark (ma) to the current line (.), run it through program, and replace the contents of the marked region with the results. You can even use it to see the contents of a directory (for example) by making a blank line, then with cursor sitting on that line,


Oh, and you can set marks like this for a-z (i.e. ma), and


will jump you to the position you marked as "a."

/ searches forward, and ? repeats search backwards without having to resupply search pattern.

Groovy stuff. vi is highly underrated. Once you get the hang of it, you won't ever want to use the IDE supplied editors.

+23  A: 

I created this reference of my most used command for a friend of mine. Hope people will find something useful:

| select                                  | v                                     |
| select row(s)                           | SHIFT + v                             |
| select blocks (columns)                 | CTRL  + q                             |
| indent selected text                    | >                                     |
| unindent selected text                  | <                                     |
| list buffers                            | :ls                                   |
| open buffer                             | :bN (N = buffer number)               |
| print                                   | :hardcopy                             |
| open a file                             | :e /path/to/file.txt                  |
|                                         | :e C:\Path\To\File.txt                |
| sort selected rows                      | :sort                                 |
| search for word under cursor            | *                                     |
| open file under cursor                  | gf                                    |
|   (absolute path or relative)           |                                       |
| format selected code                    | =                                     |
| select contents of entire file          | ggVG                                  |
| convert selected text to uppercase      | U                                     |
| convert selected text to lowercase      | u                                     |
| convert tabs to spaces                  | :retab                                |
| start recording a macro                 | qX (X = key to assign macro to)       |
| stop recording a macro                  | q                                     |  
| playback macro                          | @X (X = key macro was assigned to)    |
| replay previously played macro *        | @@                                    |
| auto-complete a word you are typing **  | CTRL + n                              |
| bookmark current place in file          | mX (X = key to assign bookmark to)    |
| jump to bookmark                        | `X (X = key bookmark was assigned to  |
|                                         |     ` = back tick/tilde key)          |
| show all bookmarks                      | :marks                                |
| delete a bookmark                       | delm X (X = key bookmark to delete)   |
| delete all bookmarks                    | delm!                                 |
| split screen horizontally               | :split                                |
| split screen vertically                 | :vsplit                               |
| navigating split screens                | CTRL + w + j = move down a screen     |
|                                         | CRTL + w + k = move up a screen       |
|                                         | CRTL + w + h = move left a screen     |
|                                         | CRTL + w + l = move right a screen    |
| close all other split screens           | :only                                 |

*  - As with other commands in vi, you can playback a macro any number of times.
     The following command would playback the macro assigned to the key `w' 100
     times: 100@w

** - Vim uses words that exist in your current buffer and any other buffer you may
     have open for auto-complete suggestions.
brian newman
You list "~X" to go to the mark with name X. That doesn't work for me - instead I use "'X" (single quote).
Steve Kemp
Wow. Your absolutely right. When I was typing out the guide I guess my eye only seen the tilde and glossed over the back tick. I will update accordingly. Thanks for the heads up.
brian newman
I saw you are using u and U to convert text case. You can use ~ to toggle the case instead.
this list is nice, but I really want to know how did you draw this table? with VIM? which plugin? I'm looking for one currently.
I used VIM, but no plugin. However; using the select block feature made it relatively easy. Glad you found the list useful! ~brian
brian newman
+41  A: 

I really wish I'd known that you can use Ctrl-C instead of ESC to switch out of insert mode. That's been a real productivity boost for me.

I logged in just to vote this up. That's an awesome tip!
I remapped my Caps-Lock to an Esc. That's both easier than the normal Esc and Ctrl-C
Holy crap. 15 years of vi and I never knew this...
Chris Kaminski
@kmm: I remap my capslock to control, that's much easier than your solution. And works outside vim.
Adriano Varoli Piazza
I do imap <C-c> <Esc>:w<cr>
Sam Saffron
another popular was is to use 'jj' for ESC. I like this approach so far.:map! jj <ESC>
You can also use CTRL-[ (which I like because it's both little fingers... just a little rotation of both hands).
Jason Down
+9  A: 
  1. Don't press escape ever. Look at the vi wikipedia page. As mentioned above, ctrl-c is a better alternative. I strongly suggest mapping your caps lock key to escape.

  2. If you're editing a ctags compatible language, using a tags file and :ta, ctrl-], etc is a great way to navigate the code, even across multiple files. Also, ctrl-n and ctrl-p completion using the tags file is a great way to cut down on keystrokes.

  3. If you're editing a line that is wrapped because it's wider than your buffer, you can move up/down using gk and gj.

  4. Try to focus on effective use of the motion commands before you learn bad habits. Things like using 'dt' or 'd3w' instead of pressing x a bunch of times. Basically any time that you find yourself presing the same key repeatedly, there's probably a better/faster/more concise way of accomplishing the same thing.

Don't use Escape? That's heresy. Escape is your best friend, both on and off the job.
if it's such a good friend, why is it so far away on the keyboard?
because 99% of the people never uses it.
Stefano Borini
Escape is separated from other keys by a few inches on my keyboard. You can't miss it.
Brian Carper
+3  A: 

^r^w to paste the word under cursor in the command mode. Really useful when using grep or replace commands

absolutely invaluable
If it's the only word you want, then * in normal mode will search for the word under the cursor.
+4  A: 

I often make functions for editing tasks, and store them in my .vimrc so I can find them again. For example reading .Net callstacks that have been converted into a single line:

function! FixCallStacks()
:x #(Save and Quit a File)

Same as :wq or ZZ

+3  A: 

Some of my latest additions to my VIm brainstore:

  • ^wi: Jump to the tag under the cursor by splitting the window.
  • cib/ciB: Change the text inside the current set of parenthesis () or braces {}, respectively.
  • :set listchars=tab:>-,trail:_ list : Show tabs/trailing spaces visually different from other spaces. Helps a lot with Python coding.
+5  A: 

The asterisk key '*' will search for the word under the cursor.

open-square-bracket-tab will take you to the definition of a C function that's under your cursor. (doesn't always work though.)

Try 'man ctags' if you're using *nix to learn how to generate a "tags" file that tells vim how to find the definition of any function or variable in many languages in addition to C. Use ctrl+] to find the definition of the token under your cursor, or use :tag tokenToFind to find any token it knows about. You can even start vim with "vim -t tokenToFind" to open the appropriate file and position the cursor at the function you need to edit.
Adam Liss
+5  A: 


vim -x filename.txt

You will be asked for a passphrase, edit and save. Now whenever you open the file in vi again you will have to enter the password to view.

+5  A: 

qx will start recording keystrokes. You can do pretty much any editing task and Vim remembers it. Hit q again when you're finished, and press @x to replay your keystrokes. This is great for repetitive edits which are too complex to write a mapping for. You can have many recordings by using a character other than x.

too much php
Also the same character 'x' is shared between the 'q' record macro command and the named clipboards ("x...). You can leave snippets of macros sitting around your file and copy them to a named clipboard (e.g. "xyy) and then play them back (@x).
Leonardo Constantino
+4  A: 

gv starts Visual mode and automatically selects what you previously had selected.

too much php

set confirm allows you to quit vim gracefully with :q. You don't need to use ZZ or other heavy-handed mechanisms which blindly save or discard all changes.

too much php
+2  A: 

:b [any portion of a buffer name] to switch buffers. So if you have two buffers "somefile1.txt", and "someotherfile2.txt", you can switch to the second with simply ":b 2.t<enter>". It also supports tab completion, although it's not required.

Speaking of tab completion, the setting :set wildmode=full wildmenu is also very helpful. It enables complete tab completion for command-mode, as well as a very helpful ncurses-style menu of all the possible matches when using it.

+2  A: 

Comment out a range of lines:

  1. First set a bookmark at the beginning of range: ma

  2. Go the the last line in range

  3. Command is :'a,.s/^/# / Assuming # is your comment character.
Also, select the first column in each line in the range using CTRL+V or CTRL+Q, then insert the # at the beginning of each column using I (to insert before the selection) and then #
Nathan Fellman
Or SHIFT+V, select a range, then:'<,'>normal I#
Leonardo Constantino
+3  A: 

You can use a whole set of commands to change text inside brackets / parentheses / quotation marks. It's super useful to avoid having to find the start and finish of the group. Try ci(, ci{, ci<, ci", ci' depending on what kind of object you want to change. And the ca(, ca{, ... variants delete the brackets / quotation marks as well.

Easy to remember: change inside a bracketed statement / change a bracketed statement.

this isn't only for `c`. You can do this with `d` to delete (e.g. di( or da(), `y` to yank, `v` to select etc.
Nathan Fellman
+2  A: 

Taking xcramps' suggestion one step further, I can't tell you how many times I've used:


to sort a list of items in a file.



will execute a shell command on the specified range of lines. A range is usually specified as start,end

1,3 specifies the first 3 lines
'a,'b selects the text between bookmarks a and b
.,$ selects the entire document (. = first line; $ = last line)
% is a shortcut for .,$ and also selets the entire document.

Feel free to mix and match numbers, bookmarks, ., and $.

Adam Liss
I prefer vim's built-in :%sort. :help sort lists the many delicious options.
Kris Jenkins
+3  A: 

Press % when the cursor is on a quote, paren, bracket, or brace to find its match.

Adam Liss
If the cursor is not over any of those it shifts to the right until it hits one of them.
Leonardo Constantino
@Léo: Thanks for the bonus tip!
Adam Liss
+1  A: 

I know this is not completely vim. But I find the cscope integration really good and it helps me a lot when hacking the linux kernel.

Ctrl-\ g to reach the definition of a function Ctrl-\ s to find all the usages of a function/macro/variable.

+25  A: 

The most recent "wow" trick that I learnt is a method of doing complicated search-and-replace. Quite often in the past, I've had a really complicated regexp to do substitutions on and it's not worked. There is a better way:

:set incsearch             " I have this in .vimrc
/my complicated regexp     " Highlighted as you enter characters
:%s//replace with this/    " You don't have to type it again

The "trick" here (for want of a better word) is the way that you can use the search to create the regexp (and 'incsearch' highlights it as you enter characters) and then use an empty pattern in the substitution: the empty pattern defaults to the last search pattern.



Equivalent to:



:help 'incsearch'
:help :substitute
wow... I've been looking for something like this
yeah, I wish that I knew abou this sooner. But then again, that's what I say about everything I learn that is new in vim.
Robert Massaioli
For anyone really loving this, try hitting `<Ctrl-R>/` to insert the last search query. (See `:help i_CTRL-R`) Really useful for similar to above, but you want to capture part of the search results. (like this: `%s:/\\([fF]rank\\) and mary/marie and \1/g`)
+4  A: 

I wish I'd known basic visual block mode stuff earlier. Even if you don't use VIM for anything else, it can be a big time saver to open up a file in VIM just for some block operations. I'm quite sure I wasted a ton of time doing this kind of thing manually.

Examples I've found particularly useful, when, say, refactoring lists of symbolic constant names consistently:

Enter Visual Block mode (Ctrl-Q for me on Windows instead of Ctrl-V)

Move cursor to highlight the desired block.

Then, I whatever text and press Esc to have the text inserted in front of the block on every line.

Use A instead of I to have the text inserted after the block on every line.

Also - simply toggling the case of a visual selection with ~ can be a big time saver.

And simply deleting columns, too, with d of course.

+1  A: 

:qall and :wqall to close all the split screens

Vijay Dev
+2  A: 

q<letter> - records a macro.


@<same-letter> - plays it back.

These are by far the most useful commands in vim since you can have the computer do a whole lot of work for you, and you don't even have to write a program or anything.

+2  A: 

Until [character] (t). Useful for any command which accepts a range. My favorite is ct; or ct) which deletes everything up to the trailing semicolon / closing parentheses and then places you in insert mode.

Also, G and gg are useful (Goto top and bottom respectively).

+1  A: 


Change word - deletes the word under the cursor and puts you in insert mode to type a new one. Of course this works with other movement keys, so you can do things like c$ to change to the end of the line.

f + character

Finds the next occurrence of the character on the current line. So you can do vft to select all the text up to the next "t" on the current line. It's another movement key, so it works with other commands too.

Adam Neal
+1  A: 

this always cheers me up

:help 42
+11  A: 

I wish i knew that before I started vi for the first time

Michał Piaskowski
+3  A: 

Build and debug your code from within vim!


Not much, really. You need a Makefile in the current directory.

To Compile

While you're in vim, type :make to invoke a shell, build your program. Don't worry when the output scrolls by; just press [Enter] when it's finished to return to vim.

The Magic

Back within vim, you have the following commands at your disposal:

  1. :cl lists the errors, warnings, and other messages.
  2. :cc displays the current error/warning message at the bottom of the screen and jumps to the offending line in your code.
  3. :cc n jumps to the nth message.
  4. :cn advances to the next message.
  5. :cp jumps to the previous message.

There are more; if you're interested, type :help :cc from within vim.

Adam Liss
+3  A: 

Typing a line number followed by gg will take you to that line.

: followed by line number does the same:42 goes to line number 42
Anti Veeranna
Typing a line number followed by G has the same effect.
Leonardo Constantino

In our software shop, variable declarations need to be sorted. In the language that we use, multiple variables can appear on the same line.

new var1,var2,var3,etc

It is a real pain to go through and visually attempt to sort each and every variable. The block highlighting, and sort command in Vim are my friends here:

  1. Move the cursor to the first variable to be sorted.
  2. Issue the v command to enter visual mode.
  3. Move the cursor to the end of the last variable to be sorted in my case I enter $ to go to the end of the line).
  4. Execute the !sort command to tell Vim to sort the highlighted text.

This will only work if their exists a 'sort' command on the underlying system.

+5  A: 

gi switches to insertion mode placing the cursor at the same location it was previously.

Leonardo Constantino

Tab & Explore (does a tabnew before generating the browser window)


For obsessive vim configuration have a look at http://github.com/jmcantrell/configs-vim

+3  A: 

I would have to say that one of my favorites is putting the help window in a new tab:

:tab help <help_topic>

This opens up help in a new tab and, as somebody that loves vim tabs, this is ridiculously useful.

Robert Massaioli
+1  A: 

I'm surprised no-one's mentioned Vim's windowing support. CTRL-W s is something I use nearly every time I open vim.

Kris Jenkins