As I mentioned in a previous post about using SSH to edit websites, while ordinarily I use “nano” for all of my text editing I feel confident from the feedback of friends that vi is actually the better choice of editors. It requires a little more of a learning curve, but allows you to do ordinarily complicated things a little bit more rapidly.
To edit a file with the vi text editor ordinarily at a command prompt you would type vi filename.php or some permutation there of. If you start a new file then on the far left hand side of the screen it will show a series of tildes. These are placeholders and indicate an empty buffer.
When you first start the vi editor you will enter the text editor in “command mode.” This is the mode that makes vi quite special. Vi’s useful commands increase the number of things you can do from such an bland looking screen with efficiency.
In the videos from YouTube below, starting with lesson 1, the first command mentioned is called last-line mode. While in command mode, to enter last-line mode you press a :. The colon then appears at the bottom of the screen with your focus indicated by a blinking cursor (on the last-line).
A simple command to enter using last-line mode would be :q. This colon followed by a q, and then subsequently an enter key will exit from the program so long as there has been no actual changes to the file. If there have been, and you’d like to abandon the changes you will need to enter :q!.
Insert mode is the alternative to the default mode, which is “command mode.” Insert mode allows you to insert text. As mentioned earlier, when you first enter vi you will default to command mode. In order to proceed to insert mode from which you can actually add text to that empty buffer of a new file, you must enter the insert mode command.
To do this, while in command mode you press the letter i. At this point, on the last-line the phrase “– INSERT –” will appear at the bottom of the screen.
Returning to Command Mode
After you’ve inserted the text of your choice, you may return to command mode via the esc button.
Interestingly, if you hit the esc button a few times your PC will make a tone to alert you that you’re already in command mode, and that pressing it a few more times doesn’t do any good! Kind of a neat audible feedback you can rely on even from most ssh clients.
Navigating Text in Vim
Basic navigation of text can be done using arrows keys to move up and down or left in right while in command mode. You may also use page up or page down (if you have those keys) to traverse text rapidly. Home or end will take you to either the beginning or end of a line, as in most text editors as well.
Traversing One Word at a Time
If you want to step forward in a text one word at a time you can press the w button (while in command mode). To move backwards one word at a time you just press the b button while in command mode. If you press b while on the first word of a line, then it will take you to the last word at the end of the preceding line.
No Home and End Keys? No Problem.
If you happen to be on a keyboard without home or end keys (if you’re editing from a smartphone, for example), or find them somewhat inconveniently out of reach you can press the $ button while in command mode to jump to the end of the line, and press 0 to jump to the beginning of the line.
To move the cursor to the top of the screen press H (as in high) while in command mode, to move to the middle press M, and to move to the lower part of the screen press L.
To move forward one full screen of text press control and the letter f. To move backward one full screen of text press control and b.
Navigating by Line Numbers in Vi
While in command mode (remember, press the esc button to enter command mode at any time) you can access the “GO command” to take you to any given line number… all you have to do is type in the number of the line you want to jump to followed by the capital letter G. So line 35, for example, you would jump to by typing 35G while in command mode.
A lot of useful tools on linux provide exact line numbers, so if for example, I use “git diff” from shell to see the difference between files staged for a commit, and files in a current working directory this will give me feedback involving exact line numbers. Using these numbers, in even large and confusing files, I can jump to exactly where I need to be using the “go command” in vi.
Deleting Characters on Vim
To delete characters to the right of the cursor while in command mode press x. In many windows text editors this would be roughly the equivalent to pressing the delete key.
To delete characters to the left of the cursor use a capital x. (So while in command mode, hold shift and press x).
Deleting Chunks of Text
If for some reason you happen to know the approximate length of the text chunk you want to delete that happens to be to the right of your cursor, while in command mode, and that number you’d like to delete is 45, then you can type 45x. Likewise, to delete 45 characters to the left of the current cursor then you’d type 45X (with a capital X again, to go to the left of the cursor).
Using the dw command to Delete Words
While in command mode to delete the word you’re currently on (beginning on and going to the right of your cursor) type dw.
Repeating Previous Commands Rapidly
Additionally, if you want to delete multiple words, instead of repeatedly typing dw you can then press .. The ., while in command mode, repeats your previous command as many times as you press it.
To delete from your current cursor position to the beginning of the line you’re currently on, you can press d0. Pressing d$, however, deletes from your current position ot the end of the line.
To delete the entire line you’re currently on, while in command mode, press dd. Yet again, to repeat the dd command, after issuing it once you can simply press the . button to repeat your last entered command.
Also, if you know the exact number of lines you want to delete, for this example we’ll say 15 lines… you could press 15dd, at which point the 15 lines following your current cursor downward would be removed from the buffer.