Is Vim Right For You? Answer: Yes

Vim has many things going for it. Not small detail things. All the small detail things can be customized. Vim is different in major ways.

  • Vi keys - Don’t like CTS, RSI, or even just feeling clumsy? Getting used to HJKL as movement keys seems very weird at first (I know! I remember my awkward early experiences clearly) but once you’ve spent a little time with this concept, you’ll hate all software that does not take advantage of it. Although many excellent programs do use it naturally (Mutt, less/man, even Bash if you want), when they don’t there’s often a way to fix that. The most important example is Vimperator and Vimium which turns your browser’s frustratingly clumsy interface into something efficient and productive.

  • Modal - Vim has a concept of "modes" which is very profound and worth contemplating seriously before rushing off with the shiny editor du jour. There are quite a few modes in Vim, but the two critical ones are "insert" and "edit". This sounds a bit technical, but think of "insert" mode as "compose" mode. Now you can see that Vim has divided all functionality into categories which, if you think about it, are very different. The only downside to this is that you have to explicitly know (and specify) which of these modes you want to be in. But once you’ve committed to making that decision every time you either compose or edit, the power available to you is greatly increased while distractions are removed. Just as MS Word with its one mode, "compose/edit/typeset/leak-metadata", is pointless if you plan to never typeset (i.e. most code), having an editor with fully live "compose" functions makes no sense if you are just debugging code ("editing").

  • The Unix way - Small things done properly is a core Unix value. Small things can be combined to form complex things. Learning the small things can be done at your own pace and each thing learned magnifies the power of all the other things you learn. For example, in Vim there are equivalent functions for the Emacs functions named forward-word, move-end-of-line, end-of-buffer, and forward-paragraph. They are named w,$,G,}. That may seem more cryptic but the Emacs bindings for these functions are ESC-F, CTL-E, ESC->,ESC-}. Of course in Vim they are bound to w,$,G,}. What’s really interesting, however, is what you find when you look deeper. Consider deleting. What if you want to delete a word, delete to the end of a line, delete to the end of a file, or delete to the end of a paragraph? Emacs has kill-word (bound to ESC-D) and kill-line (bound to CTL-K). Vim just has d (bound to d). That doesn’t sound very explicit and that’s because it isn’t. It gets combined with the movement keys to form dw, d$, dG, and d} which stand for "delete word", "delete to end of line", "delete to end of file", and "delete to end of paragraph" respectively. Now if you learned that to search for the word "stdio" in Vim was /stdio it probably wouldn’t surprise you or be hard to learn that d/stdio deletes everything up to the next instance of the word "stdio". If you learn that the command for inverting the case of something was ~, it wouldn’t surprise you to learn that inverting the case of the next word was ~w. Although the commands can seem cryptic, they do all have an incredibly elegant plan. They all work together and build upon each other. This makes learning much easier than you thought, even if it isn’t optimized only to be easy for novices. I believe that if using an editor is and will be a serious part of your vocation, optimizing on "easiest to use in the first few days" is a mistake anyway.

  • More on Vim’s compelling big concepts.

Vim References

How To Use Vim To Manage Passwords

Modern life is filled with passwords. I personally have hundreds of accounts and if there is any hope of me using good unique passwords, I simply can not remember them all. Some people use fancy password managers. The technique I use is to simply keep them in a text file which I manage with Vim. Of course keeping your passwords in a text file sounds like it would have many security deficiencies and were it not for Vim’s fantastic features this would not be a good idea. Here’s what I do.

Since I use this pretty often, I set up an alias to do all the hard work. The alias looks like this:

# Set up an alias for a Vim-based password manager.
PWFILE="~/mysecuredir/pw"
PWOPTS="\
foldmethod=indent \
noswapfile \
bufhidden=wipe \
tw=0 \
nobackup \
nowritebackup \
viminfo= \
foldclose=all \
"
PWCMD="/usr/bin/vim $PWFILE "
for PWOPT in $PWOPTS; do PWCMD="$PWCMD -c \"set $PWOPT\" " ; done
eval "alias pw='$PWCMD'"

This format of the alias shows clearly all the special Vim settings that I use. This suppresses Vim’s normally helpful behavior to save everything you do in a somewhat insecure way. This does not allow a viminfo file, nor backup creation, nor swapfile use. The option for tw (text width) is so I don’t get automatic line feeds since I’m not typing prose. Finally the foldmethod and foldclose options set up folding.

The idea with the folding is that when the file is opened, none of the passwords will be visible. Only when you search for the password you want will it be revealed under the fold. The point to this is that if you have to look up a password in an insecure place, people in the vicinity won’t be able to gawk at all your passwords. To make this work you need to exercise some discipline with the format of your password file, but it’s not complicated. Here is an example of a password list with the correct formatting.

-
    southcentralairlines.com
    mrfflyer:nLew7f-il
-
    eztax.com
    mrtaxpayer87:bDtc8fPa
-
    at&t AT&T att ATT
    1-800-288-2020
    Called 11-06-27 to cancel Confirmation #D91429932
    My land line number 858-560-1254
    Account number 858 560 1254 718 2
    Online registration code: 30287891
    vengeful@pookmail.com:fu1lowrath:fullof-sh1t (required a # in username!)
    These guys are complete shite:
    "TLE107: We apologize for the inconvenience. We are currently experiencing a
    temporary system error that prevents us from retrieving your account
    information." April 30, 2011
    CC#: 6999999999999999 1/12 123
    Security questions:
    "What is your dream job?":"Putting ATT out of business."
    "What is your favorite football team?":"I seriously hate ATT!"
-
    monstersfighting.com
    http://parents.monstersfighting.com
    quitedead:xed-monstersfighting@pookmail.com:30ssapb33bd
    Birthday used: January 1, 2005
    Hint: penguin, tiger, fox, fox, rabbit
    crazebra:30sszp933bd
-
    cheapjunkfromchina.com
    mrbuyalot:oex3nLGep

Things to note: Each record begins with a -. This is used to let the folding know that this is a record separator. It is not indented. Next notice that all the other lines are indented. You can make it tabs or spaces but it’s a good idea to be consistent. I use four spaces. You can see that I don’t just store password data, but I also often include pretty full details about what I need to remember about a company or account. In the infamous ATT example, I keep a record of all the times their stupid web site was down. I also keep particular custom credit card numbers that I only use with this vendor here (Discover used to provide this capability). Since it’s Vim, you have complete flexibility. Since you’re using folds, it’s perfectly reasonable to write as much as you want. When you save this file and then use the alias (pw as defined above) to edit it, it should look like this:

 -
 +--  2 lines: southcentralairlines.com------------------------------
 -
 +--  2 lines: eztax.com---------------------------------------------
 -
 +-- 15 lines: at&t AT&T att ATT-------------------------------------
 -
 +--  6 lines: monstersfighting.com----------------------------------
 -
 +--  2 lines: cheapjunkfromchina.com--------------------------------

As you navigate around the document, only the fold that your cursor is on will be open. Since I have so many accounts in this file, I generally hit / right away and search for the account I’m interested. Because of this, I’m pretty careful to always use lower case, or, as with the AT&T example, multiple options if I think I will forget.

Now that you have a nice system for creating a very straightforward text file for storing your passwords, it is probably a very good idea to impart some cryptographic protection. It turns out that Vim comes with an encryption mechanism built in.

Warning
The Vim developers claim that the encryption isn’t the strongest encryption possible. I could imagine that a very dedicated attacker could break this encryption. However, I don’t think that’s a realistic threat model for me. If you do, you might want to use other encryption techniques (gpg or ccrypt maybe).
Note
The putative insecurity of Vim’s default mechanism has been fixed with an option that allows the user to specify the encryption method. The option is cryptmethod and it can be the default zip or the theoretically more secure blowfish. People in the know say the latter is much more secure so it’s probably a good idea to do a set cryptmethod=blowfish while your file is open. You only need to do this once and from that point on it should be encrypting with the Blowfish cipher. It’s like having Bruce Schneier personally kung-fu fighting the NSA.
Note
While the blowfish method described above was a big improvement for Vim encryption, this seemed to invite even greater scrutiny by sophisticated people now deigning to use Vim for secure tasks. And it turned out that there were some weaknesses found. And then there was a resulting fix, a cryptmethod called blowfish2. This is available on Vim 7.4.399. Read about the details here.

To encrypt a file with Vim (remember, this handy feature works with any file you want to keep private), in edit mode type :X. It should respond with Enter encryption key: which you should do. Note that a long pass phrase with spaces is allowed and probably a good idea. Perhaps something Dylanesque like "2 much confusion, I can’t get no relief." It will ask you to Enter same key again: to make sure you really know how to type what you think you’re typing. Now the encryption key is set. To encrypt it, just do a normal :w. It should say something like "pw" [crypted] 34L, 1060C written where the "crypted" flag lets you know it’s no longer being saved as plain text. Now when I do less pw to look at the file from the unix command line, it says "pw" may be a binary file. See it anyway?". It sure is a binary file:

$ cat -A pw | head -c 20
VimCrypt~01!9M-^QM-^

That’s all that you get to know about the file from examining its encrypted contents.

In the future, when you use the pw alias, it will ask you for your pass phrase. Once you enter it, you can edit as normal and when you’re done, you can save it as normal. To make a file stop being encrypted, just do :X as before, but just hit enter for the passwords. Then use :w to save it as plain text again. This is also how to change the password, for example, if you think it became compromised.

Warning
One other thing to keep in mind is that if you are using a normal modern terminal (gnome-terminal, etc) you may have a bunch of sensitive password information from your edit session tied up in your scrollback buffer. I pretty much always use a new window of a screen session to work with my passwords and exit from that window when I’m done. It might be a good idea to open a fresh terminal to use your password file and kill that terminal when you’re done. Also, it should be obvious that if you put sensitive things in the clipboard buffer, well, there will be sensitive things in the clipboard buffer.

Large Amounts Of Prose

The question is whether to put hard returns in as you go or keep each paragraph continuous. I like to see the hard returns and can deal with them fine. But when you need to export your composition to a word processor or a web form box, it can be necessary to join the lines in a paragraph. The following works pretty well for that:

:%s/\n\([^\n]\)/ \1/
:%s/^/\r/
:%s/*/\r*/g

The last one sorts out any bullet lists you may have had. If you don’t need bullets worked out:

:%s/\n\([^\n]\)/ \1/ | :%s/^/\r/

How to break up large chunks of single line text

Often you get a file that comes from a sensible word processor (maybe even vi itself). This text only puts hard returns at the end of paragraphs. If you need hard returns put in everywhere so that you can deal with the text in vi or other line oriented tools, here’s the sequence. This routine basically makes a textwidth of 75.

# This is obsolete but still serves as an example of the macro format.
qq        # start a macro named `q'
77|        # move to column 77
?<spc><enter>    # search for the previous space which should be before 77
r<enter>    # replace it with an enter
k        # move up to the line that was just created to prime search
/^.\{75,} <enter>    # goto next line with more than 75 characters
q        # end macro definition

To execute this, go to a line that needs some hard returns (don’t start on a small line that doesn’t need any!) and use @q. Using @@ will cause it to continue. Since the number of lines is not known (you’re creating new ones all the time with this), it’s tough to automate it completely. Try 500@q and see if that gets it. It should stop at the end if the search is not found, but this could depend on the WRAPSCAN setting.

Also note that the gq command will automatically sort out text like this macro. Probably best to stick with that.

Vimium

Vimium is an extension for Google Chrome that makes the browser interface much less horrific. Here are some useful shortcuts for it.

?

Help

gs

go source

d|u

down|up a half a page

yy

copy current URL to clipboard

yf

copy link’s URL to clipboard

gf

go next frame

H|L

back|forward in history

[[|]]

previous|next link follower on pages with "Next" features

gi

go to next input box

How To Use Vim For C Programming

First you need to understand how to get make to work for you. Use set makeprg=make to set your make executable (gmake or maybe a make\ \CC=gcc). Set up your Makefile or whatever your make program likes.

Tip
Makefiles are annoyingly fussy about tabs (which I usually avoid in all other situations). See the section on tabs for details.

Test the make process from the command line outside of Vim and when it works fine, it should work fine in Vim by using the :make command. This can be shortened to :ma for the impatient.

After make runs, if there are errors, Vim takes you to the first of them. To move to the next error use :cnext or :cn. Also there are clast, cfirst, and cprevious.

Some people like to see line numbers (with :set number or :se nu) but I find it pointless since you can always go right to where the issue is by typing the line number of interest and gg. So to go to line 15, type 15gg.

I haven’t used it but there is also support for exuberant-ctags (try apt-get install exuberant-ctags). And maybe look into :cscope (try apt-get install cscope).

Tabs

I do not like tabs because to me it seems like non-obvious behavior. There is, or may be, maybe not something invisible lurking in your document. When moving around a document, having it suddenly jump is unnerving when you didn’t tell it to do that. It is easy in Vim to not use tab characters and get the same indentation functionality.

Show Tabs

Sometimes just seeing the mess is the most important step to solving it. To see tabs you can have search highlighting on and just do /\t or you can turn on set list. Set list can be customized further with something like this.

set listchars=tab:>-,trail:_

Or if you want fancy characters that you won’t confuse for your real ones, try something like this.

set listchars=tab:»·,trail:¤

Tab Settings

Here are the important functions for dealing with tab settings.

  • set tabstop=4 - Also ts. Sets how many spaces a tab is worth. If real tab codes aren’t to be used, it is the number of spaces that are used.

  • expandtab - Also et. When tabs are entered as normal, this puts spaces in the document instead. The number of spaces is controlled by tabstop. To enter a real tab when expandtab is active, use CTL-v and then <tab>. If you have no tab key (think SSH from a phone), use CTL-v CTL-i.

  • retab - Also ret. Replace all whitespace sequences with appropriate tabs based on the new tabstop value. This means that 8 tabs with a tabstop value of 4 will turn into 4 tabs when :retab 8 is declared. If expandtab is set, then tabs are converted to the number of spaces specified.

  • set shiftwidth=4 - Also sw. Used with autoindent to assign how many columns text is indented. Also used with << and >> to indent blocks.

Converting From Tabbed Formatting

If there are tabs in a file and you wish that was not the case do this:

set ts=4 | set et | ret 4

Converting To Tabbed Formatting

If you have a sensible document and heretics (like Linus Torvalds) insist that you put stupid tabs in something, then do this.

set ts=8 | set noet | %s/        /\t/g

Multi window operations

ctrl-W

kicks off the multiwindow functions

s or :split

splits window into 2 parts

:split filename

splits to edit filename simultaneously

f

splits and edits file under cursor

n

splits to New window

q

quit editing and close a split window

c

close window and put buffer in background

o

make current window the only one on the screen

j

move to window below

k

move to window above

:buffers

list buffers in action

:bnext

puts next buffer in window

Searching

The general form of a search and replace operation is: :1,$s/findme/repwithme/g

  • the 1 is the line #1

  • the $ is the "last" line

  • the s is the command that kicks off the search

  • the / is the first of three delimeters that separate the parts

  • findme is the string that we are looking for

  • repwithme is the string that we’d like to be in the place of findme

  • the g is a flag to make the operation global - otherwise only one s&r per line

  • :%s... can be used instead of 1,$ to specify the entire range

Macros - Hey, they’re easy!

Define A Macro

To define a macro, press q and then some symbol, usually a letter. This starts the macro recorder for the macro named the symbol you chose. For example: press q then x. This sets the recorder for the macro named x. Now everything that you type will be saved as something you might want replayed later. When you are finished recording your sequence that you want repeated, press q again.

Replay A Macro

Then position the cursor where you want the sequence to kick off again and press @ (shift 2 on my keyboard and on a German one it’s in the same area). This is the play button, but you still need to tell it what to play. Press x.

If for some weird reason you’d like to pretend a macro didn’t happen (not undo!) and purge it and replace it with the original nothingness, use this: qxq

You should not define a macro that plays itself like this: qxiHITHERE!<esc>q qx@xq That’s bad! I’ve had it go crazy, but I think hanging is more normal - pressing Ctrl-c seems to do the trick. At least Vim has a well behaved error recovery!

Using Vim To Acquire Input

Let’s say you have a script that needs the user to contribute some text. You could use simple things like Bash’s read built-in but maybe you want the program to allow fancier editing. For example, I have a program that processes my blog and one of the modes allows me to compose an entry in the middle of this running program.

Bash

#!/bin/bash
VIMCMD="/usr/bin/vim"
TDIR="/tmp"
T=$(mktemp --tmpdir=${TDIR} textinput.tmp.XXXXX)

${VIMCMD} -c "set tw=0" ${T}

# Do something with file ${T}
D=$(date "+%Y%m%d %H:%M")
sed -i "1s/^/${D} /" ${T}

cat ${T}
rm ${T}

Python

def live_edit_new_content():
    import tempfile
    import subprocess
    tmpfileob= tempfile.NamedTemporaryFile(dir='/tmp')
    tmpfile= tmpfileob.name
    vimcmd= '/usr/bin/vim'
    subprocess.call([vimcmd,tmpfile])
    the_content= tmpfileob.read()
    tmpfileob.close() # Deletes tempfileob too.
    return the_content

Visual Mode - (it’s vi, not ex, but that’s not what they mean)

The "visual" mode is just a mode where you can highlight text and then do things to it. And they say vi is old fashioned! Just press v and do the move around bit. You can also do Shift-V for linewise selecting and ctrl-V for blockwise selecting. Isn’t that great?

Well what are you gonna do with that highlighted text? d :: Gets rid of it ~ :: Changes its case "miXED up!" is now "MIxed UP!" U :: Uppercase "Mixed up!" is now "MIXED UP!" u :: Lowercase "Mixed up!" is now "mixed up!" y :: seems like copy - you can then use p to reinsert it o :: go to the other end of the selection to modify that point J :: joins the selected lines of text together <<:: Indents it to the left. >>:: Indents it to the right.

Set the settings

To set the digraphs flag use :set dg This allows you to do cool stuff by typing part one, BS, and then part two.To see what your options are, check out the codes with :dig Sometimes this doesn’t work out on some displays and some terminals, etc. But I have little doubt that Vim is planting the correct character codes for your encoding as you specify.

Another one that I like is the tw setting. I usually use 70, like this:

:set tw 70

Why 70? Voodoo superstition. Anyway, this adds a hard return after the last word that was completed before the column number you specify.

Compilation Feature

This is a list of some of the relevant things that should be compiled into Vim. This can be discovered by using the :ve command (version). (see :help feature-list)

autocmd

allows things to happen on events - works with syntax

cindent

special formatting modes for C programs

cmdline_compl

commandline completion

cmdline_info

facility enabling ruler and status display

comments
cryptv

a general purpose encryption scheme

cscope
digraphs

ability to enter accented characters

eval

ability to perform calculations and logic operations

ex_extra
extra_search
insert_expand

allows for various useful completions (filename, word, etc)

linebreak
menu
mouse
mouse_gpm
perl

a tie in with perl itself, execute perl commands in vim

smartindent
syntax

color and highlights of special formats (html,c,etc)

title
user-commands

allows user to define ex style commands

viminfo

auto saves registers and history across sessions in a file

visualextra

allows a few more things in visual mode

wildignore

can skip certain patterns in filename completion

wildmenu

shows completion options dynamically

xterm_clipboard
X11

restores old title to window (kvt, for example)

Troubleshooting

Some time in 2014 my Vim started to get very laggy. I could type entire sentences before they would show up. I discovered that this was curable with set syntax=off. Unfortunately, I like syntax highlighting.

After a tiny bit of research I found some other things that can be done to help.

set re=1
set ttyfast
set lazyredraw

Unfortunately these help but don’t help enough. The first one is interesting since it changes the regular expression engine to an older one that is actually faster in many situations.

My Vim:

VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Oct 15 2014 09:10:07)
Included patches: 1-273
Modified by Gentoo-7.4.273

Still working on this.