Posted: 25 May 2012
Tagged: tutorial vim
#Synergy tutorials, vim
This is the first in a series of tutorials I’ve put together to present to the synergy group, my research group at Virginia Tech. They were meant to be delivered as presentations, so the format may not be entirely natural when read, but I hope some will find this useful.
##Starting materials:
A tar archive with a portable configuration as well as some extra features and test files is available here, I would recommend setting up the configuration, but it is not necessary.
##Overview:
First off, vim is not an IDE, it is not a programming environment (i.e. lisp/emacs, java/eclipse) it is an editor with a surprisingly rich feature set and extension API. Chances are, if you want it to do something, it can, as a result of this even with an hour I can’t come close to covering the features I use in an average day let alone the full feature set. That said, I will cover some that I find most useful for general editing situations. Some things I may not cover but are built in or easily available (in no particular order) are.
First things first, the most basic possible workflow.
vim test.txt
i
[edit as usual]
<ESC>
:wq<ENTER>
You have now edited a file in vim. Not so hard, or daunting right? This is
where you learn the most important key command of all for a novice vim user,
undo. While the original vi had almost no functionality for undoing edits,
vim’s undo stack is infinite. If you did something you want undone, just hit
u
in normal mode, and it will be undone. To redo, <C-r>
, either of these can
be repeated ad-nauseum to back out of or retrieve any number of edits, never
fear accidentally destroying your file, even if you accidentally save it to
disk, so long as vim is running you can always back out.
Now we’ll get into some of the more interesting things about each part of that first example. First, you actually have choices when opening VIM, you can run vi, vim, view, or vimdiff and all will open vim, but they all have different properties.
Of these one is best explained by example, that’s vimdiff. Try ‘diff
difftest1.txt difftest2.txt’ and see what you get. I do not find this output
useful, while the lines do differ, the amount to which they differ is
completely unclear, let us try the same with vimdiff like this ‘vimdiff
difftest1.txt difftest2.txt’. Notice that while many of the lines are
different, they are different in small ways, something a regular text diff
cannot show easily. Also, the two panes are tied, if you scroll one down, the
other follows to make viewing any part of the diff simple. Now, use :qa
to
quit out of vim.
##MODES:
Unlike most editors, vim does not operate in insertion mode at all times. It actually has several different modes each of which use almost completely different keymaps and have different outcomes for any given single key, this is the most difficult part of learning vim for most people, in a way it’s also the most powerful thing about vim.
The editing modes we will be dealing with today are:
The vast majority of editors have one of these, insert mode, it is the mode
they start in and stay in at all times. Emacs has insert mode and arguably
command mode, but starts in insert mode. Vim confuses most by starting in
normal mode, and it is the mode in which most major edits are performed. In
general the modes are used for different tasks. Insert mode is used for
inserting new text into the file by the keyboard. Normal mode is for moving
around a file, controlling the environment, searching, deleting, copying,
cutting, and pretty much all the special functions of the editor that are
performed with relation to the cursor. This is usually the mode which scares
people the most, because in it two keystrokes could delete all the text in your
file, thankfully it is also the mode in which the u
key would immediately
restore all that text, so no need to worry. Command mode is very similar to
editing with ed or ex (vim’s ancestors), it is a command line within the editor
which is used for saving, quitting, performing operations which edit the file
without respect to the cursor, and allows one to set variables and call
functions to control the vim environment. The next two are highly related,
visual mode is the same as when you select text in a regular editor, it just
shows visually what part of the text has been selected. In general the keymaps
for visual and visual block are the same as for normal mode, they just act on a
different region and have a different argument precedence order (more on this
shortly). Visual block differs from visual only in that block selects by
columns and rows (a rectangular set of text) rather than logically along lines
like normal selection. This is usually considered an advanced feature, I
consider it essential, so we will be seeing it again later. Lastly is a mode
that won’t often get used, but is necessary for a terminal vim user. Some very
useful features, such as automatic indenting and text formatting, become
frustrating when pasting already formatted text into vim through a terminal.
Since vim thinks you’re typing it, it can get messed up very quickly, paste
mode is a special version of insert mode that turns off all automatic
formatting to prevent that problem. If you need to use it simply type :set
paste
while in normal mode, hit enter, paste your text, then :set nopaste
to
turn it off, that’s all you need to know about paste mode.
##NORMAL MODE COMMANDS AND THEIR STRUCTURE:
Now, having covered the modes, the next thing to know is why normal mode is awesome, and how commands in normal mode are structured. In general they are structured as follows.
<# of times to repeat>["<optional register argument>]<command key(s)><motion/range>
That’s kinda complicated, but it’s worth knowing this because once you start to learn what each of these things can be, it allows you to compose commands, movements or ranges into unexpectedly useful editing commands. Lets get to some basic examples of normal mode essentials, motions and commands.
##ESSENTIALS:
###Enter insert mode: before the cursor : i after the cursor : a beginning of line : I end of line : A in a new line below the cursor : o in a new line above the cursor : O replacing the character under the cursor : s replacing the line under the cursor : S replacing a range from the cursor : c replacing the part of the line after the cursor : c
Enter command mode: :
Return to normal mode from any other: <Esc>
##NORMAL MODE MOTIONS:
It’s always good to know how to move around in a file, these are some of the most useful ways (note not all). Also, remember these are normal mode commands, so they do take a repetition argument, i.e. 15k will move up 15 lines.
###Move cursor:
up :
###Move screen: up down half page ^u : ^d full page ^b : ^f one line ^y : ^e
##NORMAL MODE COMMANDS:
###delete: character under cursor : x range : d line : dd rest of current line : D
###change: character under cursor : r range : c line : cc rest of line : C
(any patterns emerging?)
###copy: range: [“optional buffer]y line: [“optional buffer]Y
###paste: after cursor : [“optional buffer]p before cursor : [“optional buffer]P after cursor and move to end : [“optional buffer]gp before cursor and move to end : [“optional buffer]gP
###general: repeat last command : . change case of letter under cursor : ~ undo : u increment next number on the line by 1 : ^a decriment next number on the line by 1 : ^a indent range by one level : > unindent range by one level : > format range of code : = format range of text : gq run range text through external command: !
###spelling: suggest alternate spellings for word under cursor : z= add word to good list : zg
###folding: unfold all levels of all folds: zR fold all levels of all folds: zM toggle folding by one level on current line: za toggle folding by all levels on current line: zA close fold by one level: zc open fold by one level: zo
there are many more, but this is a good start.
Now, so you can give some of this a try, open up implementation.tex. First,
lets try moving around in normal mode. Especially try moving by word w/b
,
moving by sentence (/)
, and moving by paragraph {/}
. Also, notice that the text
may have been ‘folded’ collapsed by sections for easier navigation, to open it
all up all the way, type zR
, zM
will reverse this.
Also, try some edits, delete a few characters, maybe add some text.
##RANGES AND WHY WE LOVE THEM:
Now that you’ve tried just editing in a relatively straightforward way, it’s time to take a look at the commands, motions, and ranges together. First, a range can be specified by visual selection, motion command, or region command. We’ve gone over all of these but the last, and these are the doozies. When specifying by a region you specify two things as below.
<command><in or around><region type>
This allows you to execute a command on a region of text your cursor is inside of without explicitly selecting it first, these are some of the more useful region types.
###region types: blocks: ) ] } or > strings: “ or ‘ word: w sentence: s paragraph: p
For example, in the latex file we’re working on, lets try formatting the first
paragraph so we don’t have so many lines sticking out of it. Try putting your
cursor on any character in that paragraph and typing gqip
or < format
text ><in><paragraph>
and see what happens. Magic right? Or try deleting a
paragraph, or a sentence. One of the more useful things, is using this to
change a word. Typing ciw
removes the word and enters insert mode to replace
it. Just want the word gone as if it were never there? Then daw
will remove
the word and the space on one side. Let’s exit out and open
calculate_potential.c instead. This is where things get fun. Try putting your
cursor inside any {}
block, and typing di}
, notice it deletes the entire
contents of the nearest enclosing curly braces. This works for all block
types and strings, makes it very easy to clear something out and replace it.
The around modifier works here too, but instead of removing the space on one
side it removes the block delimiters.
These are some of the most useful features of vim, the composability. Now that
you know how to do any of these things to a paragraph, what about the entire
file? Need to select all? Not even. Type gg
, then the command you want, then G
,
and the command is applied across the whole file. Usually this is best used
with either =
to format code, or with gq
if you set your formatoption to
something like astyle.
##COMMAND MODE COMMANDS:
We will touch briefly here, this space is so vast that it is not useful to even
try and cover it all, but we will cover the various ways to save and exit vim,
as well as do some basic actions. A :
command has a structure much like that of normal mode, but a bit different, see below.
<range><command><arguments>
Note that the range comes first, and many commands have arguments. These are some of the most common.
###save/quit: (add ! at the end of any to force) save file in current pane : w save all files : wa quit current pane : q quit all panes : qa save and quit all panes : wqa save as : sav
###search/replace:
replace occurences of
Some examples, replace all occurrences of foo with bar on all lines in a file (% is the range for whole file).
:%s/foo/bar/g
Delete all lines that contain ‘DEBUG’.
:g/DEBUG/d
Copy all lines that do not contain the word debug and paste them at the top of the file.
:v/DEBUG/t0
Also useful for running external commands, this is why I almost never use ^z.
###external commands/files:
read external file: r
Beyond the use for saving files and find/replace, the command mode is where files and splits and tabs are controlled.
###opening new files:
in current pane : e
##SPLITS AND TABS:
To view any number of files effectively, it helps to be able to open more than one at once, in vim the easiest way to do this is through splits and tabs. Personally I almost exclusively use splits, but that’s just my style.
To try this out, try opening one of the files as usual, then type :vsp
. You
will get a second pane splitting the window vertically, but viewing the same
file and buffer. This can occasionally be useful if you want to look at two
different parts of the same file at once. From there, you can type :e
to open a
different file in one of the panes.
Managing panes is much like working with a terminal multiplexor, assume any
command is prefixed with ^w
.
###split commands: (remember, ^w then whatever is below)
move to split at right :
Note that :q
will close one of these. For tabs, you use :tabnew
or :tabedit
to
open a new one, then switch with :tabnext or :tabp
. In the provided
configuration Alt+t will also open a tab, and Alt+}
will switch tabs right.
This is all especially useful because vim’s yank and paste mechanisms work
between all of these panes, keeping everything together rather than having to
jump window to window.
###COOL STUFF:
Ok, a few quick more advanced moves that will make things easier for everyone.
First, something that works with no configuration magic. Block selection,
insertion, and replacement. In normal mode v enters visual mode to select text.
By the same token ^v
enters block selection mode, which initially does not seem
terribly useful, but let’s do some examples. First, to comment out the following
code, try moving to the first column of the first row and press ^v
. Move to
the first column of the last row, press S-I
(shift I), then //
, then Esc
.
Then watch as not just the last line, but all lines are commented.
int a[50];
int b[50;
int c[50];
Now, say that instead of commenting that out, we want to replace the sizes, 50,
with 100 in all three lines. Use ^v
to select the block of text with all of
the 50s in it, press c
then type the new number (100) followed by Esc
. See
all of them replaced in one go. Some ask me why I always align key parts of
function calls and variable definitions, this is why. If things are reasonably
aligned, edits can be fast and effortless.
###try these: ^vI ^vA ^vc
I hope you found this useful, if you have any comments or suggestions, feel free to contact me or use the comment area below.
blog comments powered by Disqus