Vim has a deserved reputation for being difficult to learn. The included
program will teach you the absolute basics, enough to allow you to edit a file, but what if you want to achieve the extreme proficiency you’ve heard vim users are capable of?
There are many good articles about learning vim a quick google search away, and vimcasts has some great screencasts, but those resources are not explicitly geared towards helping you achieve mastery through practice. You might learn some interesting tricks, but how do you ensure you will be able to remember them long enough to use them? What you need is a vim study lab!
A vim study lab consists of a large set of the textual equivalent of study cards with some vim commands to make navigating the cards easier. As an added bonus, since the lab is within vim, you can try out any commands on the cards easily.
Here’s an example of a vim-study-lab-in-a-file. The file, when sourced, turns the vim buffer into the vim study lab. The file consists of two parts. The first part is a hunk of vimscript that is executed when you source the file. It creates keyboard commands that make it easy to move the cards in the queues.
The second part is the queues themselves, Study, and Known. (The idea is that once you know something so well that you don’t need to study it anymore, you can move it into the Known queue, just to keep it around for posterity.) The queues simply consist of a command and some information about it.
" source the file by typing :so %
" Now the vim buffer acts like a specialized application for mastering vim
" There are two queues, Study and Known. Depending how confident you feel
" about the item you are currently learning, you can move it down several
" positions, all the way to the end of the Study queue, or to the Known
" type ,, (that's comma comma)
" You know the command pretty well, but not enough to move it to 'Known'.
" ,, moves the current command to the bottom of the 'Study' queue.
nmap ,, ^v/^$<cr>dma/^= Known</cr><cr>P'azt<c -y></c><c -l>
" type ,c (that's comma c)
" You don't really know the command at all and want to see it again soon.
" ,c moves the current command down a several positions in the 'Study' queue
" so you'll see it again soon.
nmap ,c ^v/^$<cr>dma/^$</cr><cr>/^$</cr><cr>/^$</cr><cr>/^$</cr><cr>jP'azt<c -y></c><c -l>:noh<cr>
" type ,k (that's comma k)
" You have the command down cold. Move it to the 'Known' queue.
" ,k moves the current command into the 'Known' queue.
nmap ,k ^v/^$</cr><cr>dma/^= Known</cr><cr>jjP'azt<c -y></c><c -l>
" Ok, it's time to get this party started. Move to the top of the study queue
" and go for it!
" This line keeps the rest of the file from being treated as vimscript
in normal mode, how do you move to the first non-whitespace character of the previous line
in normal mode, how do you move to the first non-whitespace character of the next line
how do you nondestructively move back to the last position when the buffer was closed
how can you see what *all* the commands starting with 'shell' when considering getting help
:!mkdir -p %:h
if you have a file that you can't save because its directory doesn't exist, how can you create that directory from the path component of the file?
how do you make vim hard wrap at 78 chars?
turn camelCase into snake_case
turn camelCase into snake_case (in only the visually selected part of the line)
turn snake_case into camelCase
turn snake_case into camelCase (in only the visually selected part of line)
:'< ,'>normal @q
run the macro recorded into the q register on all selected lines (the '< ,'> is automatically added)
easily fill the q register with a macro that deletes two words
what's a good shorthand for "normal" on the #vim_command_line
:argdo norm @q
run your last macro against all files in the args
:.,. w !sh
execute the contents of the current line in the current file in sh
if you have ctags working correctly, how do you jump to the definition of a function?
if you've made a ctag jump, how can you jump back other than </c><c -o>?
if you left insert mode to go look at something elsewhere in the file, how can you get back to where you were and also back into insert mode?
if you want to look up the definition of save using ctags
run the visually selected lines in the shell (not run as a filter)
rot13 the text selected by some movement
open in window for each file in the arguments list
display the argument list
show the contents of all registers
jump to tag on top of tag stack
show the contents of register a
filter lines 10-30 through an external command (in this case wc)
insert the character represented by the ASCII value 8
delete lines 43-45 (can specify any range before the d)
go to the top of the screen
add the next 20 lines to the 'a' register
switch case for movement command
in visual mode, exchange cursor position with the start/end of highlighting
filter the next 10 lines through an external command (in this case wc)
filter the next 20 lines through an external command (in this case wc)
go to the line that is 20 lines below the line that is currently the top of the window
go to the middle of the window
go to the bottom of the window
go to the tenth line from the bottom of the window
go to the line that is 20% of the way down in the file
go to the exact position of mark a (not just the beginning of the line like 'a)
Go down half a screen
Go up half a screen
move to the start of the line (before whitespace)
see location in file and file status
:set ignorecase (or :set ic)
ignore case when searching
enter replace mode to repeatedly replace the character under the cursor
write the visually selected text to a file
Go to end of (next) word
Go to end of previous word
restore last changed line
show the line numbers relative to the current cursor position
Forward find word under cursor (fuzzy)
Backward find word under cursor (fuzzy)
Backward find word under cursor
some_command | vim -R -
when in the shell, you can use vim as a pager by piping STDIN to it and putting it in readonly mode
highlight the entire line the cursor is on
when in normal mode, how do you enter into Ex mode (to do extended work in the #vim_command_line)
in Ubuntu, which folder has the default, system-wide vim files
:map ,, :w\|:!ruby %
how would you map ,, to writing the current buffer, then running it with ruby
repeat the last :! command
in vim 703 and above, how do you specify that you'd like column 78 to be colored, so that you can see whether you are passing an ideal width
what do you call the higher level contexts than editing character by character?
readline vi mode (tagged as #readline_vi_mode)
what's it called when you use vim as your line editor in the shell?
how do you open an editor while the shell is in #readline_vi_mode
move to the last non-whitespace character on a line
in zsh, how can you use #readline_vi_mode?
change a word without necessarily being selected on the first letter of the word
change the phrase "foo hello" to just "hello" (with cursor located at f*oo hello)
if you're using vim as your line editor, how can you turn it in to a full vim session
execute the vim code in the current line. To execute it in the shell, type :! at the beginning of the line
mark: set a mark in the 'A' register (globally)
make the selected text lower case
make the selected text upper case
paste yanked text into the #vim_command_line
mark: return to a globally set mark, even if in another buffer
</c><c -x></c><c -l>
move forward in the jump list
move backward in the jump list
open file under the cursor
remove all those nasty ^M characters from the end of each line in a file
autoindent lines already selected in visual mode
autoindent current line
in insert mode switch to normal mode for one command
format the current paragraph
list your movements
list your recent commands
lower case the whole line
upper case the whole line
display hex and ASCII value of character under cursor
display hex value of utf-8 character under cursor
rot13 whole file
jumps to last modified line
jumps to exact position of last modification
:h slash</c><c -d>
list all help topics containing the word "slash"
go backward in the change list in a file
go forward in the change list in a file
yank the current line into register "a"
fold: make folding use syntax
fold: turn off folding
fold: turn on folding (if it has been turned off)
fold: moves the cursor to the next fold
fold: moves the cursor to the previous fold
fold: move to start of current open fold
fold: Move to end of current open fold
show what is currently mapped to </f6><f6>
show all the mappings
show the content of all registers
:43,45 ce 80<enter>
center the lines from 43 to 45 within an 80 char width
fold: decrease the fold level by one
in visual mode, select a whole word
in visual mode, select a whole sentence
fold: increase the fold level by one
toggle between last two buffers
go to the center of the screen on the current line
Paste below the current line, adjusting indentation to match current line
paste register above current line, leaving cursor after new text
paste register below current line, leaving cursor after new text
insert the content of register a while in insert mode
Paste above the current line, adjusting indentation to match current line
Execute the macro recorded in register x on all lines of the current file
Execute the macro recorded in register x on a visually selected set of lines
in the #vim_command_line and in insert mode, insert the result of a 5*5 calculation
move cursor one *screen* line up, regardless of line wrapping
move cursor one *screen* line down, regardless of line wrapping
qQ ... added commands ... q
append more commands to a pre-existing @q register macro
rails.vim: extract some functionality into a partial
open the cucumber feature with that name [tag:setup_specific:gem]
(while searching or ex mode) do previous search or command
(while searching or ex mode) do next search or command
(while searching or ex mode) see previous searches or commands
count the number of occurrences of "forward" in a file
see previous commands in a "command-line window"
see previous searches
back a paragraph
forward a paragraph
back a sentence
forward a sentence
find matching parenthesis
join two lines
reformat the selected text
transpose two letters (delete and paste, technically)
move to the end of the word
append at end of word
move the cursor forward by a word
move the cursor backward by a word
in insert or the #vim_command_line this turns the next thing typed into a literal
Switch on spell checking
</c><c -x></c><c -s>
in insert mode correct the spelling of the current word
copy the current selection to a clipboard where other programs can use it
change all the words in between two quotes
/<c -r></c><c -w>
switch to search command mode, then copy in the word under the cursor
Go to the next item in the quickfix list
Go to the previous item in the quickfix list
insert last #vim_command_line command
insert last search command
write lines 10-30 to a file named foo.txt
append lines 10-30 to a file named foo.txt
insert results of ls external command below cursor
insert content of file below cursor
repeat last substitution
go to next modified buffer
:w !sudo tee %
save the current file as root (in case you opened it up without sudo accidentally and made changes to it)
in Ex mode, insert the last command
In insert mode, insert the character right above the cursor
In insert mode, delete the current line from the cursor position to the beginning of the line
In insert mode, re-insert the text inserted in the previous insert session
in Ex mode, insert the last search
When typing something into the #vim_command_line, switch to the editable command-line mode where the command line becomes a fully vim-compatible text area
when in a visual selection, which key will toggle to the other end of the selection?
get help for how control r is used in insert mode
get help for how control r is used in command mode
remove all the spaces from the current visual selection, which is only a partial line, not a full line
if expandtab is set, this will change all the tabs to spaces, expanding them as appropriate
maximize size of window split
insert at the beginning of the line
remark area that was just marked
same as :wq
redraw the screen
</c><c -x></c><c -f>
completes using filenames from the current directory.
block selection (column editing)
fold: open a fold at the cursor
delete to the end of the line
change to the end of the line
reload the vimrc file (or ":so %" if you happen to be editing the file)
append at the end of the line
decrement a number on the same line when in normal mode (can be used with n before it)
increment a number on the same line when in normal mode (can be used with n before it)
NERDTree: opens the filesystem menu for a file, allowing you to remove, rename, etc
mark: set a mark in the 'a' register in the current buffer
mark: return to the 'a' mark in the current buffer
uppercase or lowercase the character under the cursor
repeat the last command
</c><c -w></c><c -w>
switch between windows
show lines containing the word under the cursor
redirect the output of an Ex command into buffer a
reverse the characters in a visual selection
switch to the gui version
list all the matches with prepended line numbers in ex command output
insert previously inserted text (in insert mode)
delete word before cursor in insert mode
delete all inserted text on the line (in insert mode)
in the #vim_command_line, echo the current line number
visually select *around* a set of parentheses. Try it by moving the cursor (somewhere in here) and trying it
redir @a | :g/someregex/
Capture the lines that match a certain regex into the @a register for pasting
rm /tmp/clip.txt ; vim -c "normal \"+p" -c "wq" /tmp/clip.txt
Save the contents of the clipboard to a file by opening, pasting into, and closing vim.
go to the first occurrence in the file of the word under the cursor
go to next visual line, even if text wrapped
insert a blank line every 5 lines
go to the position before the latest jump
move the cursor backward to the previous occurrence of the character x on the current line.
scroll back one page
list the leaves in the tree of the undo changes
go to a newer text state (like </c><c -r>, but will move forward through all text states on multiple undo branches)
go to an older text state (like </c><c -r>, but will move backwards through all text states on multiple undo branches)
move the cursor forward to the next occurrence of the character x on the current line
move the cursor backward to right before the previous occurrence of the character x on the current line.
exchange the window with the next window (like if you split a new buffer into the wrong window location)
move the cursor to the middle of the screen
scroll current line to top of page
same as fx, but moves the cursor to right before the character, not all the way to it.
scroll forward one page
move current line to middle of page
repeat the last f/F/t/T command you gave
scroll one line up
scroll one line down
forward to start of next method
backward to start of previous method
scroll one character to the right
scroll one character to the left
scroll half a screen to the right
scroll half a screen to the left
scroll current line to bottom of page
set -o vi
in a the bash shell, how can you use #readline_vi_mode?
return from tag jump. For example, in help, if you've followed a link, how do you go back?
jump to tag under cursort (for example, following a link in help)
look up the word under the cursor in man
What's the name of a plugin that will help you align stuff
replay a vim macro recorded into register x on all lines between the current line and the bottom of the buffer
On every line containing foo *anywhere* in the line (before or after the bar), replace every occurrence of bar with xxx
:'< ,'>!uniq | sort
With some lines selected, how can I run them through external commands, substituting the result?
insert the file directory/filename for the current file into the buffer
Append the yank of the current line into the 'a' buffer
move every line that *does not* contain bar to the end of the file
:verb set ballooneval?
how can you check who last set ballooneval
%s/\v("[a-z_]+"): /\1 => /g
replace "foo": with "foo" => (to turn JSON into acceptable Ruby)
remove trailing spaces from all lines
how would you change the text "foo hello there" to 'foo hello there' using vim-surround?
show the older error list in the quickfix window (error lists are referred to as being in the quickfix stack)
show the newer error list in the quickfix window (error lists are referred to as being in the quickfix stack)
repeat the last command-line
"_dd ("_ is the black hole buffer)
delete a line without overriding the buffer
open the file listed in quickfix in a horizontal split
reverse the vertical order of all the lines
if you have a bunch of windows open, close all the other windows, making the current window the only window
From the shell command line (not vim's command line) how can you easily run a vim command?
with rails.vim, how do you open the rspec tests when you are in a model?
repeat last substitution
if you have the surround plugin, how would you remove the double quotes from "hello" when inside it?
vim filename -c 'execute "normal \<c -x>"'
how can you decrement the first number on the first line of the file? (how would you property escape the </c><c -x>?)
do a case-insensitive search for ruby (the \c can be anywhere, including at the end)
write the file and quit. This is basically here just so that there's something in the "Known" queue.
Here you can see it in action.
To start, just copy the contents of the file above into a vim buffer, save it, then source the file by typing
to move the first card from the top of the Study queue to the bottom. Rinse and repeat.
Over time your vim study lab can end up as a nice repository of newly acquired knowledge. Just add new cards as you pick up new tricks.
From From nerds.weddingpartyapp.com