The Path to Better Vi Skills

Among software developers there is no single subject that will generate more opinions, controversy or discussion than that of “Favorite Code Editor”. It seems we all have a definitive preference and will agrue vehemently in favor of that choice.
At the same time, there is no *nix system to which you can connect today that does not include a version of Vi. It is the single most ubiquitous editor on the planet!
Each of us has, in varying degrees, some mastery of Vi. The command set seems to be larger than any other single application. Most of the commands are very arcane, peculiar and – as a result – difficult to remember.
The various cheatsheets available on the Internet are handy as a reference, but seriously lacking as a directed tutorial guide.
In a deliberate effort to increase my Code Editing Kata, I spent several weeks explicitly using Vi on a regular basis.
And I want to INTRODUCE TO THE WORLD my own set of mnemonics that lessen the steep learning curve associated (real or perceived) with Vi.

A bit of history

Vi (for ‘Visual’) traces its ancetry all the way back to the origin of Unix (in AT&T). As a ‘screen’ oriented version of the editor(s) used with teletype machines, it represented a step into modern computing. The name ‘vi’ is derived from the commmand that switches the line editor, ‘ex’ (Bill Joy’s editor, released as part of the first BSD Unix release in March of 1978), to visual mode.
Bram Moolenaar released VIM publicly around 1991, although he had begun writing it for his Amiga in the late 1980s. It was originally called VI iMitation and, later, VI iMproved.
For the sake of commonality, the following set of tutorial steps will assume you have very, very little experience with Vi. I would venture to say, though, regardless of your experience there is alwayssomething new to learn in this feature-rich software application.
Additionally, everything here is based on my personal experience. The terminology and descriptions are my own and I take full responsibility for them.

Modes of Operation

I have observed several clearly distinct operational ‘modes’ when working with Vi.
  • Command Mode
  • Edit Mode
  • Window Mode
Switching between these modes usually requires pressing ESC.
An alternative to ESC is Ctrl [.
I find this much easier and quicker although I am having difficulty changing a long-standing habit of reaching for the ESCape key.

Command Mode

This is where you can issue commands to the editor to do things that I consider other than editing.
When in Command Mode the colon (:) is used to accept input for commands that are not editing nor navigation related.

Close

When I was an avid flyer of R/C planes we had a very popular 'meme' in my local club: "Take-offs are optional, landings are mandatory"
I would paraphrase that with respect to Vi and say that although OPENING the editor is optional, CLOSING it is mandatory.
As is 'true to form' for Vi, there are numerous ways to close and exit the editor.
zz is the quickest way to Save and Exit. I think of this as putting Vi to sleep (akin to the cartoon representation of sleep as a row of Zs)
:wq is the most common. This represents several discrete commands that are concatenated (which is a useful feature of the command mode):
  • w is to (w)rite to the currently open file
  • q is to (q)uit
I also like :x as a shortcut to save and close vi
If you wish to quit and discard any changes you have made, use the (q)uit command followed by shebang :q! This will ignore any changes and close the editor.
You can optionally provide a filename after the (w)rite command like this :w Gemfile. That will write the output to that file (creating it if necessary, on most systems).

Navigation

Navigating around the document is one of the most important functions of any editor.
I found it simpler than expected to master the essential commands for jumping through my code, in Vi, with a few mnemonic tricks.
Move the cursor Left, Right, Down, Up one character/line with hljk respectively. I found this is muchmuch quicker than trying to reach for the arrow keys (which, by the way, also work as expected)
By pressing b, in edit mode, the cursor will jump Back to the Beginning of the current word. Likewise,e will take the cursor to the End of the current word.
In a similar fashion w jumps to the next Word.
You can force the cursor to any location in the current line with the column number followed by the Pipe symbol. I think of 15| as "push the I-beam cursor to position 15".
Likewise, the Pipe symbol alone will move to the first character/column in the line. Actually | and 0|are equivalent. "Nothing" is interpreted as ZERO here.
Before leaving the commands for cursor movement, let's add these two:
  • + moves the cursor to the beginning of the next line. I think of it as Incrementing the line position
  • - moves the cursor to the beginning of the previous line, like Decrementing the line position
Scrolling the screen with Ctrl u (I think of Up) and Ctrl d (I remember Down). These only move the screen about half-width. A complete "next" screen is Ctrl f (Forward). And, as you might have guessed, Ctrl B (for Back) goes UP one screen.
You can Go to any line in the file with 32G. The "G", for GO, is preceded by the line number.
Since 8G will Go to line number 8, it is obvious that 1G will jump to the first line in the file. What is NOT apparent - but quite useful - is that G alone will jump to the last line in the file. Unlike the command for moving the cursor to the beginning of the line, "Nothing" represents The End in this case
A handy, but a bit obscure, command is z followed by RETURN, which sets the editor so the current line is the top line on the screen.

Editing Commands

Now that we are able to move the cursor freely about the screen and scroll through the currently open file, let's see how to make actual changes to the text.
I must admit, the mnemonics for these are not quite as straight-forward as others. But it is quite common to think of "X" as CROSS-OUT or Remove. So, bearing that in mind we have
  • x to delete the next character
  • X will delete the previous character
  • dd to delete the entire line
These can be preceded by a number to indicate that many characters. For example, 7x will eradicate the 7 characters after the cursor and 5X will delete the 5 characters to the left of the cursor.
Combining what we have seen from above, with respect to moving the cursor among words, if you usedb or dw (preceded by a number) that many words will be deleted (before the cursor or after the cursor, respectively)
There is an anomaly, a 'shortcut' of sorts that I find myself using quite often. For that reason I will not complain about my inability to devise a proper mnemonic. It is D, which deletes all text to the right of the cursor - to the end of the line. {You could, perhaps, remember it as The BIG D that performs a BIG Delete, or imagine the shape leading to the right; the end of the line}
You instantiate Insert Mode with i. Of course, you lose the simplicity of moving the cursor with h/j/k/l - and I sometimes forget that fact.
Another command I find myself using most often is A, which also instantiates Insert mode but takes you to the very end of the line. I think of it as "insert After" the last character on the line.
Selections and Blocks of Text
There is another 'mode' in Vi (think of it a sub-Mode) that emulates the GUI operation of selecting large blocks of text.
The Visual mode is accessed with v and allows you to continue using the navigation keys (that is why I consider it a subordinate to Navigation) to make selections.
This is handy for a
  • Delete with dd
  • Yank (the term for copying) with y
  • Paste by using P to paste after the current cursor position and p to paste just before the cursor
You can indent a selected block of code with > and outdent it with <
Combining these for something useful, go to a line with lots of text (code) and try this
wwwhvbcREPLACED

And, each time you catch yourself shouting, "OOOPS!" (or something similar but less 'family-friendly') remember to use u for Undo.
I have occasionally become a bit overzealous with 'u' when I made several changes I wish to revert. In those cases I can Undo my Undo by applying the command for Redo, Ctrl r.

Opening Multiple Files

:e <path and filename>
If you are not sure of the precise path and/or filename just use a filespec.
:e . displays a menu-like list of files in the current directory (if you used 'dot', for example). You can navigate the filesystem (use the standard jk and Enter
Shell Command
You can jump out of Vi and to the shell with :sh
This is handy for doing a quick chmod on a file or running irb.
When you exit from the shell you are back in Vi where you left.

Search and Replace

Every editor (of any kind) must include the essential ability to Search and Replace text. And Vi is not at all hesitant about being robust in this area.
Any search begins in Command mode.
The simplest is SLASH followed by a word. This /flower will find the first occurance of the word "flower". Using :n you can go to the next occurance.
In order to REPLACE text there are a few key options:
  • :s/SearchFor/ReplaceWith/g {The 'g' means Global. Without it the search is limited to the current line}
  • ?Find/Replace/gi will do the same operation in reverse {the 'i' modifier forces case-insensitive}
What's odd here is the letter 's' is used when you want to Search AND Replace. The mnemonic I use for this is to remember Search-and-Replace versus Find with just a Slash.
If you prefer confirmation on each replace action, just add the 'c' modifier, like this :s/Find with Confirmation/Each one/gc
You may notice the familiar Regular Expression modifiers (g, i). And, in fact, the Search and Replace commands will accept [many] Regular Expression evaluation characters.
There is a great detailed description of all the parameters at Vim Regular Expressions 101
I never knew this existed in Vi until I stumbled across it accidentally.
Jumping to Matching Braces (curly braces, square brackets or standard parentheses) is simply %when the cursor is on one of the braces. What a time-saver !!

Editor Windows

Buffers

Vi embraces the concept of Buffers and applies this to the management of multiple files. I have witnessed a Vi expert bouncing among numerous screens and in multiple files and been completely awe-struck.
You can be that Vi Wizard after some practice with these few, key, buffer commands
Each time you open a new file, with :e filename, it is loaded in a new (sequentially numbered) buffer.
All the buffer commands begin with b in command mode
  • :b# next buffer
  • :bf first buffer
  • :bl last buffer
  • :b4 switches to another buffer by its number (see callout)
Before you ask, “How do I know the number of the buffer I want?”, listing all the buffers in use is so simple. It is :ls. Just like the *nix command for a file listing.

Dealing with a Split Personality

Working with a split screen is only a slight modification to working with buffers. This is handy in Rails, for example, to work on a Controller and its view(s) simultaneously.
You can open another file, into a split screen with :split filename
If you are opening the editor, you can specify multiple files – which will be loaded into split screen(s) – with vi -o file1 file2...
You can rearrange the windows’ locations on the screen; but that is a bit beyond the scope of this article.
Switching windows is a matter of Ctrl w followed by Ctrl w to jump from window to window. If you remember the navigation keys (h, j, k, l) use them with to jump to a specific window based on its location on the screen relative to the current window.
Using Ctrl w followed by q will close (quit) the current window.
The currrent window can be split with Ctrl w followed by s.
If you ever lose track of which file you are currently editing, Ctrl g will display details about the file including its name.

Conclusion

That is enough to grasp for an introduction to this extremely feature-rich application. If you have been intimidated by Vi I really hope this has helped to make it more approachable. If you have a bit of experience with Vi, I hope this highlighted some new areas in which to grow your expertise.
It does not take very long before these commands become “muscle memory”.
I hope you will apply serious effort, on a regular basis, to practicing these few commands and I expect you to see improvements in your code development as a consequence of that effort.

0 comments: