Vim allows you to access all operations and shell command from the command line. This is a feature of so called "orthodox editor" (see VIM)
The uniqueness of VIM is that is operated in several "modes", each of modes has it's own set of command and capabilities:
Regular mode: you can issue command that work with the current line (line on which the cursor resides)
Visual Mode: The visual mode permits the user to select the text like you would do with a mouse, but using the keyboard instead of the mouse. Useful to copy several lines f text for example. The shortcut is: "V".
Command Mode: Let's now speak about the command mode, a command begins with the symbol ":".
When you are in another mod you can use the escape key (sometimes you'll need to hit it twice) to come back to command mod at any time.
For a more in-depth explanation of the Vim modes, take a look at the vimtutor.
The challenge when working with vim is the vast number of commands that are available. It is just impossible for mere mortal to remember all of them. Although there is some system in this madness ;-) And that help to memorize more command that would be possible otherwise. For example all commands working with buggers start with the letter b. All command for switching from one window to another with Ctrl-W, and so on.
Some people have even produced vi cheat sheets, listing all available commands. But that's an overkill.
If you unable or unwilling to learn "intermediate VIM" you can still do most on the things required on the exam using just a dozen of VIM commands. But that is a handicap. You might better off spending additional time and getting to "intermediate" level (which is characterized by the ability to use multiple buffers, changes windows layout, use visual selection and registers, and pipe parts or all of the bugger via external filters.
In any case here is the basic set of VIM command:
- i -- switch to the insert mode
- a -- switch to append mode
- A - inserts text after the end of the line.
- :w save:
- :wq -- save and exit:
- q exit: :
- :w! -- forcefully overwrite
- :q! -- to trash all changes )
- :vsplit vertical split: open a document and then type :vsplit /path-to-document/document and this will open the specified document and split the screen so you can see both documents.
- y -- copy a line or selection :
- yy -- copy a line:
- paste: p
- o -- opens an empty line below the cursor and switch to Insert mode.
- O - opens a line above the cursor and switch to Insert mode
- x cutsymbol
- dd -- cut a line:
It is important to learn to use VIM help and vimtutor command. (Use yum install vim-enhanced to install it.) This command opens a vim tutorial that has you work through some nice additional exercises.
We need to distinguish between buffer, window and view. Buffer is a block of memory that is allocated when you begin a word-processing session. If you load a file this buffer is a temporary holding area for the files. It is emptied at the end of each session.
To save your work, you have to write the contents of the buffer to a file. A file is a permanent storage area on a disk (a hard disk or a floppy disk). After you have saved your work in a file, you can retrieve it for use in another session.
When you begin a session editing a document that exists on file, a copy of the file is made and its contents are read into the buffer. You actually work on the copy of the document stored in memory. The file is not changed until you save your changes during or at the end of your work session. You can also discard changes made to the buffered copy, keeping the original file intact, or save multiple versions of a document in separate files.
Particularly when working with larger documents, the management of disk files can become a major effort. If, like most writers, you save multiple drafts, it is easy to lose track of which version of a file is the latest. So serious writers use version management system like GIT.
The command s is the most important addition on this level. The format for the command that perform global change of one sting to another is:
from,to s/old/new/g
Here old and new are placeholders for actual strings and from and to are line numbers for region of the text where replacement should be performed. The optional g means to replace everywhere. Without it, only the first occurrence on each line will be replaced. To replace green with blue in your entire document, use
1,$s/green/blue/gTo replace blue with green in lines 10 through 24 use
10,24:s/blue/green/g
The search and replace command allows regular expression to be used over a range of lines and replace the matching string. The user can ask for confirmation before the substitution is performed. More examples:
1,$s/the/The/g Search the entire file and replace the with The. %s/the/The/g % means the complete file. (Same command as above, only range specification differs). .,5s/^.*//g Delete the contents from the current to 5th line. %s/the/The/gc Replace the with The but ask before substituting. 10,20s/^.//g Delete the first characters selected fragment (uncommenting).
The search command is more powerful when combined with the regular expression search strings. If the g directive is not included or range on line is one line then the change is performed only on the first occurrence of a match on each line.
Sometimes you may want to use the original search string in the replacement result. You could retype the command on the line but vi allows the replacement string to contain some special characters.
1,5s/help/&ing/g Replaces help with helping on the first 5 lines. %s/ */&&/g Double the number of spaces between the words.
Other 20 commands that you need to lear on this level:
For more information about intermediate level set of commands see article Vim Revisited by By Mislav Marohnić or, better, one of free ebook for VIM such as Vim Book
Please note that to reach advanced level of VIM is almost impossible for sysadmins. Only programmers, who chose VIM as their primary editor typically are able to achieve this level (with few exceptions).
We also discuss several key command from intermeduate level of VIM below.
Most Vim users are already familiar with using the read command (r), which inserts text from a specified file after the current line in the current buffer:
:r textfile
What is important is that you can read in the output any script of program. For example:
:r ! ll /home/user/directory
This redirect the output of that command into the buffer and it is inserted after the current line. This feature is useful for example to read the output of the Web page that you're editing, using a text-mode browser:
:r ! w3m http://en.wikipedia.org/wiki/Vi -dump
The -dump
option tells w3m to simply spit out the Web page as plain text and exit.
It's also possible to execute multiple commands connected via pipes, for example
:r ! df -h | sort -r :r ! ls -a | egrep -v '^_'
Effectively, we’re putting our shell command directly after the ! character, and when we execute this command, Vim is placed in a background process while the shell command is executed. Once the shell command is finished, the resulting output is placed into our buffer, directly beneath our current cursor position.
The read command might also be useful for creating a report about the incident the you are resolving by allowing you to add to your report fragments from logs and execution of necessary commands:
:r ! grep string /var/log/apache2/site-error.log
Vim also makes it easy to redirect the output of most standard Unix utilities into a file, and to pipe text from the file it's editing into standard Unix filters as well as Perl and AWK interpreters.
Even more useful feature of Vim is ability to pipe part of the buffer into script and then replace this part with the output of the script. That this feature can be used for example for beatifying your script or for commenting out sections of your programs. You can pipe all the buffer, or only your selection.
For example, to pipe all the buffer you need to specify the filer (which can be written by you Perl script) after ! command:
:1,$ ! perltidy
will beautify your program using perltidy. Beautifying your script is a classic example of using piping in vi. You can also create a macro using keystroke remapping. Instead of beautifier you can use any other filter. This way for example you can temporary remove all comments from the script as it simplifies understanding and then reread the file with comments back into the buffer:
To do the same for selection you need to provide boundary of selection to the command. The easiest way to do this is to use visual
mode: v
, V
, or Ctrl-v
commands to select the part of your script that you want to process.
In this case boundary of your selection are defined by two mark '< and '> which represent upper and lower boundary
correspondingly. They will be put on the command like automatically as soon as you enter : . For example:
'<,'>! perl -nle 'print "\#".$_'
(this operation is called "commenting out" and it can also be performed via a plugin, but it is a still a good illustration of using Perl filters with VIM).
Vim will run pass your selection to the script as STDIN and insert standard output in place of it. If you incorrectly overwrite
your selection or the whole buffer you can restore it using undo command (u
). As buffer is an "in-memory" mapping of the
file, rereading file from the disk using r command also allows you to restore the original text.
To repeat the previous pipe command, you need to type:
! object !
It is important to distinguish between file, buffer and window. Those are three key concepts of VIM editor:
The :ls command gives us a listing of all the buffers that have been loaded into memory (:ls). We can switch to the next buffer in the list by running the :bnext (can be abbreviated to bn) command or bprev (can be abbreviated to bp). The % symbol in this list indicates which of the buffers is visible in the current window, while the # symbol represents the alternate file. We can quickly toggle between the current and alternate files by pressing <C-^>. Press it once, and we’ll switch to a.txt; press it a second time, and we’ll get back to b.txt.
We can traverse the buffer list using four commands—:bp and :bn (or bprev and bnext) to move backward and forward one at a time, and :bfirst and :blast to jump to the start or end of the list. It’s a good idea to map them to something easier to reach. Some users can benefit from more concile mapping taken from Tim Pope’s unimpaired.vim plugin:
nnoremap <silent> [b :bprevious nnoremap <silent> ]b :bnext nnoremap <silent> [B :bfirst nnoremap <silent> ]B :blast
NOTE: Vim already uses the [ and ] keys as prefixes for a series of related commands (see [), so these mappings have a consistent feel to them. The unimpaired.vim plugin provides similar mappings for scrolling through the argument ([a and ]a), quickfix ([q and ]q), location ([l and ]l), and tag lists ([t and ]t). Check it out.)
The :ls listing starts with the buffer serial number, which is assigned to each buffer automatically on creation. We can jump directly to a buffer by number, using the :bN command Alternatively, we can use buffer names instead of numbers :b {bufname}. The {bufname} need only contain enough characters from the filepath to uniquely identify the buffer. If we enter a string that matches more than one of the items in the buffer list, we can use tab-completion
Vim creates a new buffer any time we open a file. If we want to delete a buffer, we can do so using the :bdelete command. This can take one of these forms:
:bdelete N1 N2 N3
:N,M bdelete
Note that deleting a buffer has no effect on its associated file; it simply removes the in-memory representation. If we wanted to delete buffers numbered 5 through 10 inclusive, you need to run the command :5,10bd. But if you wanted to keep buffers number 6, 7 and 8, then run :bd 5 9 10.
Buffer numbers are automatically assigned by Vim, and we have no means of changing them by hand. So if we want to delete one or more buffers, we first have to look them up to find out their numbers. Unless I have a good reason to delete a buffer, I usually don’t bother. As a result, the :ls listing comes to represent all of the files that I have opened in the course of an editing session.
If we want to arrange buffers in a way that makes more sense for our workflow we can use split windows and tabs. VIM associates each file with a buffer and can have multiple buffers opened. Some people open as much as 300 buffers in VIM.
Some additional useful command:
Vim allows to open files both from within Vim and from outside of Vim (by supplying the list of files as parameters). This can also be a single file or multiple files. If we specify multiple files you can use basic regular expression to define a group of files. If we wanted to open multiple files at once, we could manually specify them like so:
vim file1.txt file2.txt
Or if you want simultaneously split your window in subwindows for each file and view all files on the screen at once use:
vim -o file1.txt file2.txt
Within vim you can open the file using the “edit” command (:e), followed by the path to the file. To open a file within Vim, you’ll have to run the following command (the path can either be absolute or relative to the current working directory):
:e /path/to/your/file.txt
You can always reload the same file, wiping out you changes
:e! %
Edit command without argument will wipe out your changes and restore the state of the files before the last write to it.
Each loaded files is represented in VIM as a buffer. In other words a buffer is a file loaded into memory for editing. The original file remains unchanged until you write the buffer to the file.
It’s best for beginners to always be explicit and to use the word buffer, as it cements the idea of how Vim actually modifies buffers and not files.
Let’s look at a few different options for saving a file (which, as we should now know, really means we want to write our buffer back to the source file). The following command is known as the “write” command (we saw this in the last chapter when discussing how buffers work). It’s fairly straightforward, in that it does what you would expect from its name, and writes the buffer content back to the source file.
:w
You can also choose to “save and close,” by running the following composite command (by that I simply mean that we have combined two commands, the “write” command, :w, and the “quit” command, :q):
:wq
Note: If you prefer something a little more concise (well, one character less), you can use the alternative :x command, which differs only slightly, in that it will only write the buffer when a modification is actually detected.
For example, if we had a file with 10 lines of content and in which every line was modified in some way, we could choose to write only the changes on lines 5–9, by using the following command:
:5,9wq
It’s important to realize that if you have one window displayed on the screen, but multiple buffers open, it might not be clear that you have other buffers open at the same time and if some of those hidden buffers have been modified or not. If you were to try and quit Vim while some buffers had unsaved modifications, Vim would complain by throwing an error at you. If this happens, there are a few options available to you.
VIM load each file into its own buffer and that's the most common way of creating buffers in VIM. But you can create an empty buffer and then load file into it too. A fresh empty buffer is called a [No Name] buffer. Vim provides us with a few ways to create a new empty buffer. Let’s review each of them.
Now that we have a bit of an understanding of what file name modifiers are in Vim, we can look at another way to take advantage of them. In this example, we’ll look at how we can change the working directory of our project while we’re already inside Vim.
Let’s quickly clarify what the problem is that we’re trying to solve. If we are inside the folder ~/Code/ProjectA/ and we open Vim (let’s also assume we have some files from ProjectA open as well at this point), then Vim’s working directory will be ProjectA. Meaning, if we decide that we need to find some content that we know is inside another project directory (e.g., ~/Code/ProjectB/), we won’t be able to do that without either restarting Vim from within the ProjectB folder, finding the file and then jumping back to ProjectA, or opening a new shell and running Vim from the ProjectB folder and finding the file we’re after. (A real-world example for me is that I need to find a snippet of code I know I’ve used in another project, and so I want to copy it over to this project.)
Ideally, we would like to temporarily change the working directory while still inside the ProjectA folder, so we could find the file in ProjectB and then change the working directory back again to ProjectA. Using a combination of file name modifiers and Vim’s built-in cd command, this is not only possible but allows us to implement in a much simpler way. First, take a look at the following command:
:cd ~/Code/ProjectB