May the source be with you, but remember the KISS principle ;-)

Contents Bulletin Scripting in shell and Perl Network troubleshooting History Humor

Vim - The editor

Western Orthodox Editors Page

News See also Recommended Links Beginner Tutorials Advanced
Reference Ctags Usenet and maillists
Pipes and ! command Text buffer execution Regular Expressions Searching and replacing External commands Multi
Windows support
Macros Cut and Paste
Color schemes in VIM Syntax Highlighting Folding Indenting Your Code in VIM ex commands Perl support    
VIM Configuration Vimrc Examples .exrc files History Tips  Random Findings Humor Etc

The introductory paper Orthodox Editors introduced some ideas on which this page was build. Here is the abstract of the paper:

This paper tried to introduce a new concept: orthodox editors as a special category of editors that have command line set of command and respective glue macrolanguage. We have found two such families:

We define the notion of  "orthodox editors" as having at least three distinct features:

This article is a modest attempt to create a basic classification useful for further studying this important class of editors. The author argues that this class of editors can serve as viable mid-weight editors for programmers (see a companion paper A Note on Size-based Classification of Text Editors for discussion of this editor classification)

Read more

I would like to stress the currently vim  is probably the best implementation of vi philosophy.  It preserved two modes editing paradigm and all important achievements of the original vi including:

At the same time vim editing mode (especially in gvim -- GUI version of vim) resembles more typical Windows editor editing mode. It also has better windows control, Perl interface (starting with version 5.x), folding (from  version 6). 

Folding in VIM

Plain vanilla folding primitives in vim6 are too low level to be convenient for the most users. I highly recommend you to install allfold macros  developed by Marion Berryman. It's better to add basic script (allfold_basic.vim)  to plugin directory. It provides all the necessary folding functionality. He also provided more complex experimental script (allfold_full.vim)  that you can play with if you became addicted to this folding ;-).  Some ideas developed by Marion in those two scripts are really good !!!. Here is a short description of the plugin:

The allfold scripts implement a feature set which allows VIM users to view ALL interesting lines in a buffer and FOLD the rest away.  Lines are selected to be interesting in one of the two following ways:

1. They match a regular expression pattern.
2. They are in a block of lines delimited inclusively by a line that matches  a beginning RE pattern and a line that matches an ending RE pattern.

Sets of lines matching different selection criteria can be combined using logical "and" and "or" operations. The selections may be inverted so that lines not matching the selection criteria are actually selected.

Beyond these basics other features do such things as manipulating lists of selection commands and using the raw selection "bit-map" directly to enhance the capabilities and ease of use of the scripts.

I would change the mnemonic to include the word "all" to respect history of this command. For example:

command! -nargs=+ Allb :call AFB_fold_blocks(<f-args>)
command! -nargs=0 Allf :call AFB_freshen()
command! -nargs=+ Allg :call AFB_grab_view_map(<f-args>)
command! -nargs=0 Allh :call AFB_has_folds()
command! -nargs=? Alli :call AFB_invert(<f-args>)
command! -nargs=+ All :call AFB_fold_pattern(<f-args>)
command! -nargs=0 ALL :call AFB_fold_remove()
command! -nargs=0 Allu :call AFB_undo_prev()

Please note that in the definitions above "All" is command to fold text and "ALL" to unfold. Actually if no parameters supplied to All, it can unfold the text (remove folding).  This was the original Xedit semantic and it makes sense to preserve it.

Like in other orthodox editors the central idea of vi is the idea of the command line command set, the idea that as I stressed before is in some respects more powerful and convenient than getting the same functionality implicitly via cascading menus. An interesting and pretty logical extensions of this idea in vi is the ability to generate command-line command parameters (or even whole commands) using screen.

The main ideas vi is pretty close to the orthodox editors paradigm that I discussed on the main page of the section.

I would like to reproduce Bill's Joy recollection of how vi was really written  (from  Linux Magazine November 1999 FEATURES The Joy of Unix):

LM:: What inspired you to write vi?

BJ: What happened is that Ken Thompson came to Berkeley and brought this broken Pascal system, and we got this summer job to fix it. While we were fixing it, we got frustrated with the editor we were using which was named ed. ed is certainly frustrating.

We got this code from a guy named George Coulouris at University College in London called em -- Editor for Mortals -- since only immortals could use ed to do anything. By the way, before that summer, we could only type in uppercase. That summer we got lowercase ROMs for our terminals. It was really exciting to finally use lowercase.

LM: What year was that?

BJ: '76 or '77. It was the summer Carter was president. So we modified em and created en. I don't know if there was an eo or an ep but finally there was ex. [laughter] I remember en but I don't know how it got to ex. So I had a terminal at home and a 300 baud modem so the cursor could move around and I just stayed up all night for a few months and wrote vi.

LM: So you didn't really write vi in one weekend like everybody says?

BJ: No. It took a long time. It was really hard to do because you've got to remember that I was trying to make it usable over a 300 baud modem. That's also the reason you have all these funny commands. It just barely worked to use a screen editor over a modem. It was just barely fast enough. A 1200 baud modem was an upgrade. 1200 baud now is pretty slow.

9600 baud is faster than you can read. 1200 baud is way slower. So the editor was optimized so that you could edit and feel productive when it was painting slower than you could think. Now that computers are so much faster than you can think, nobody understands this anymore.

The people doing Emacs were sitting in labs at MIT with what were essentially fibre-channel links to the host, in contemporary terms. They were working on a PDP-10, which was a huge machine by comparison, with infinitely fast screens.

So they could have funny commands with the screen shimmering and all that, and meanwhile, I'm sitting at home in sort of World War II surplus housing at Berkeley with a modem and a terminal that can just barely get the cursor off the bottom line.

It was a world that is now extinct. People don't know that vi was written for a world that doesn't exist anymore -- unless you decide to get a satellite phone and use it to connect to the Net at 2400 baud, in which case you'll realize that the Net is not usable at 2400 baud. It used to be perfectly usable at 1200 baud. But these days you can't use the Web at 2400 baud because the ads are 24 kilobytes.

Peter Salus in his Open Source Library - Papers gives the following version of events:

The original UNIX editor was ed. It was a line editor of reluctant and recalcitrant style. When UNIX (version 4) got to Queen Mary College, London, in 1973, George Coulouris -- a Professor of Computing -- wasn't happy with it. So he wrote a screen editor, which he called "em," or "ed for mortals."

Coulouris went on sabbatical to Berkeley, where he installed em on "his" machine. A graduate student noticed it one day, and asked about it. Coulouris explained. He then went off to New Jersey to Bell Labs, and when he returned to Berkeley, he found that em had been transmuted into ex, a display editor that is a superset of ed and a number of extensions -- primarily the one that enables display editing.

At the beginning of 1978, the first Berkeley Software Distribution was available. It consisted of a tape of the Berkeley Pascal System and the ex text editor. The graduate student was Bill Joy, and the distribution cost $50. The next year Berkeley got some ADM-3a terminals, and Joy rewrote em to vi -- a truly visual editor.

In sum, ed came out of Bell Labs in New Jersey, went to Queen Mary College in London, from there to the University of California at Berkeley, and from there back to New Jersey, where it was incorporated into the next edition of UNIX.

Dr. Nikolai Bezroukov

Top updates

Softpanorama Switchboard
Softpanorama Search


Old News ;-)

2004 2003 2002 2001 2000

[Jul 12, 2013] The vimrc File - Derek Wyatt's Blog

[Aug 29, 2012] Vim Taglist plugin features

The taglist plugin provides the following features:

[Aug 29, 2012] Color schemes in VIM

[Aug 29, 2012] The ultimate Vim configuration - vimrc

" => Text, tab and indent related
" Use spaces instead of tabs
set expandtab

" Be smart when using tabs ;)
set smarttab

" 1 tab == 4 spaces
set shiftwidth=4
set tabstop=4

" Linebreak on 500 characters
set lbr
set tw=500

set ai "Auto indent
set si "Smart indent
set wrap "Wrap lines

[May 13, 2011]  Vim Outliner

Vim Outliner is a Vim plugin that make it behave as a full- featured outliner of the likes of MaxThink, Grandview, ThinkTank, and more. It has its own add-ons for checkboxes and hoisting and is compatible with Vim spell-checkers like vimspell and engspeak. There are several scripts available from other to convert text outlines to HTML pages, Docbook files, and Open Office Impress files.


Adding a more visual cursor

Sometimes, you have a lot of syntax coloring in the file you are editing. This can make the task of tracking the cursor really hard. If you could just mark the line the cursor is currently in, then it would be easier to track it.

Many have tried to fix this with Vim scripts, but the results have been near useless (mainly due to slowness, which prevented scrolling longer texts at an acceptable speed). Not until version 7 did Vim have a solution for this. But then it came up with not just one, but two possible solutions for cursor tracking.

The first one is the cursorline command , which basically marks the entire line with, for example, another background color without breaking the syntax coloring. To turn it on, use the following command:

:set cursorline

The color it uses is the one defined in the CursorLine color group. You can change this to any color or styling you like, for example:

:highlight CursorLine guibg=lightblue ctermbg=lightgray

If you are working with a lot of aligned file content (such as tab-separated data), the next solution for cursor tracking comes in handy:

:set cursorcolumn

This command marks the current column (here the cursor is placed) by coloring the entire column through the entire file, for example.

As with the cursor line, you can change the settings for how the cursor column should be marked. The color group to change is named cursorcolumn.

Adding both the cursor line and column marking makes the cursor look like a crosshair, thus making it impossible to miss.

Even though the cursorline and cursorcolumn functionalities are implemented natively in Vim, it can still give quite a slowdown when scrolling through the file.

Modifying key bindings

All of us have probably, at some point, used an editor other than Vim. Because of this, most of us have learned to use some very specific keyboard shortcuts for doing different tasks. Even though the key bindings for the keyboard shortcuts in Vim are created with ease and use of speed in mind, sometimes it can still be faster to use the shortcuts you already know.

To facilitate this, Vim gives you the possibility to rebind almost every single key binding it has.

In this recipe, we will learn how to change the key bindings when using Vim in different modes.The main commands to know when dealing with key bindings are:

Each of the command takes two arguments—the first is what keys the command should be bound to, and the second is the command to bind. So, let's look at an example. Say you can't really get used to saving an open file by executing :w in the normal mode because you are used to using Ctrl-S to save a file and would like to keep it like that.

A mapping for this could be:

:map <C-s> :w<cr>

Notice the <C-s>;in the key binding. This is the Vim way for writing 'key combination Ctrl+S'. Instead of C (Ctrl), you could also use A (Alt) or M (Meta). The <cr> at the end of the command is what actually executes the command. Without it, the command would simply be written to the command line but not executed.

There are several other special notations for some of the other keyboard keys. The following table shows the most common of them:

Keys Notation
<BS> Backspace
<Tab> Tab
<CR> Enter
<Enter> Enter
<Return> Enter
<Esc> Escape
<Space> Space
<Up> Up arrow
<Down> Down arrow
<Left> Left arrow
<Right> Right arrow
<F1> <F12> Function keys 1 to 12
#1 #9#0 Function keys F1 to F9, F10
<Insert> Insert
<Del> Delete
<Home> Home
<End> End
<PageUp> Page up
<PageDown> Page down


Maybe you only want to be able to save when you are in the insert mode and actually editing the file. To change the command for this, you only need to have the following:

:imap <C-s> <esc>:w<cr>a

So, what happens now is that you map the Ctrl+S to do a combination of key presses. First, press <esc>; (the Escape key) to get out of the insert mode and into the normal mode. Then, use :w<cr> to execute the actual saving of the file, and finally the a to get back into the insert mode and go to the end of the line.

You could expand the mappings to fit all of the standard copy / paste / cut / save shortcuts from many applications. This could be constructed like this:

" save file (ctrl-s)
:map <C-s> :w<cr>
" copy selected text (ctrl-c)
:vmap <C-c> y
" Paste clipboard contents (ctrl-v)
:imap <C-p> <esc>P
" cut selected text (ctrl-x)
:vmap <C-x> x


If you are in Gvim, you can even get dialogs shown for the save-as and Open functionalities.


"Open new file dialog (ctrl-n)
:map <C-n> :browse confirm e<cr>
"Open save-as dialog (ctrl-shift-s)
:map <C-S-s> :browse confirm saveas<cr>


You can get into a situation where you map a key combination in which the first key is actually bound to a function of its own. An example could be the $ key, which is bound to the "jump to end of line" functionality in Vim. You might, however, want to have a key binding like $1 for some functionality, $2 for some other functionality, and so on. The mapping could then look like:


:map $1 :MyFunction1()<cr>
:map $2 :MyFunction2()<cr>


Now when you press $, Vim will wait for one second after you press the $ key, and if it does not get the second character in the key binding before the timeout, it will execute the normal "jump to end of line" functionality. However, if you press 1 before the timeout, it will execute your Myfunction1()function instead.

With the ability to change the keyboard mapping in Vim, you really have an access to a powerful way of modifying the editor completely according to your needs.

You can read more about mappings in the Vim help system under:


:help key-mapping


[Jan 15, 2010] Scripting the Vim editor

[Dec 16, 2009] Finally! A decent text editor for Linux with Windows key bindings. 46palermo

Vim Tip, on November 8th, 2009 at 19:32 Said:

just thought you might like to know, that vim does actually support windows keybindings. There should be an mswin.vim file on your system, which you can load to get ctrl-x, ctrl-v etc.

You may just owe me a White Russian

[Nov 21, 2009] Vim 101 A Beginner's Guide to Vim Linux Developer Network by Joe 'Zonker' Brockmeier

Searching and Replacing

Now that you know how to enter text, make some changes and so forth, it's time to learn how to use search and replace in Vim. It's really pretty easy. If you want to search through the document from command mode, use / followed by the text you want to search for. So, if I want to search for "bunny" I can enter / and then bunny and hit enter.

If I want to find it again, I hit n. If I want to look for a previous instance of the text, I'll use N instead, which will search the opposite direction through the document.

Want to reverse the direction of your search? Use ? instead of / and Vim will move backwards through the document. Using n and N as above will reverse the direction of the search.

That's all pretty easy, isn't it? Now to move on to an important operation: Cutting and pasting text.

... ... ...

Hit v to highlight some text. Then hit y to yank it into the buffer. Then move the cursor where you want it, and use p in command mode. There you go--you've just pasted some text!

The commands you most need to start out:


[Aug 28, 2009] vimconfig

Vimconfig is a complete set of Vim 6.x configurations files. It includes a personal vimrc config file with many features and some useful plugins, e.g. for HTML, TeX, Perl, mail, PHP, and so on.

[Jul 11, 2009] Screen (vim + gnu screen) - Start gnu screen w- your vim session and a split shell + send commands to the sh vim online

created by Eric Van Dewoestine


Note: gvim is not supported. You must be running vim in a console.

Currently tested on Linux and cygwin, but should work on any unix based
platform where screen is supported (OSX, BSD, Solaris, etc.).  Note that
in my testing of cygwin, invocations of screen were significantly slower
and less fluid than on Linux.

This plugin aims to simulate an embedded shell in vim by allowing you to
easily convert your current vim session into one running in gnu screen
with a split gnu screen window containing a shell, and to quickly send
statements/code to whatever program is running in that shell (bash,
python, irb, etc.).

  :ScreenShell [cmd] - Opens the split shell by doing the following:
    1. save a session file from your currently running vim instance
       (current tab only)
    2. start gnu screen with vim running in it
    3. load your saved session file
    4. create a lower gnu screen split window and start a shell
    5. if a command was supplied to :ScreenShell, run it
       Ex. :ScreenShell ipython

    Note: If you are already in a gnu screen session, then only steps
          4 and 5 above will be run.

  :ScreenSend - Send the visual selection or the entire buffer contents to
                the running gnu screen shell window.

  :ScreenQuit - Save all currently modified vim buffers and quit gnu
                screen, returning you to your previous vim instance
                running outside of gnu screen
    Note: :ScreenQuit is not available if you where already in a gnu
          screen session when you ran :ScreenShell.
    Note: By default, if the gnu screen session was started by
          :ScreenShell, then exiting vim will quit the gnu screen session
          as well (configurable via g:ScreenShellQuitOnVimExit).

An example workflow may be:
  Open a python file to work on:
    $ vim

  Decide you want to run all or pieces of the code in an interactive
  python shell:
    :ScreenShell python

  Send code from a vim buffer to the shell:

  Quit the screen session and return to your original vim session:

  - While running vim in gnu screen, if you detach the session instead of
    quitting, then when returning to the non-screen vim, vim will complain
    about swap files already existing.  So try to avoid detaching.
  - Not all vim plugins support saving state to or loading from vim
    session files, so when running :ScreenShell some buffers may not load
    correctly if they are backed by such a plugin.

install details

Download the script and put it in your plugin directory (~/.vim/plugin).

[Jul 10, 2009] Scripting the Vim editor, Part 1 Variables, values, and expressions

Vimscript is a mechanism for reshaping and extending the Vim editor. Scripting lets you create new tools (such as a problem-word highlighter) and simplify common tasks (like changing tabspacing, or inserting time and date information, or toggling syntax highlighting), and even completely redesign existing editor features (for example, enhancing CTRL-Y's "copy-the-previous-line" behavior).

For many people, the easiest way to learn any new language is by example. To that end, you can find an endless supply of sample Vimscripts—most of which are also useful tools in their own right—on the Vim Tips wiki. Or, for more extensive examples of Vim scripting, you can trawl the 2000+ larger projects housed in the Vim script archive. Both are listed in the Resources section below.

If you're already familiar with Perl or Python or Ruby or PHP or Lua or Awk or Tcl or any shell language, then Vimscript will be both hauntingly familiar (in its general approach and concepts) and frustratingly different (in its particular syntactic idiosyncrasies). To overcome that cognitive dissonance and master Vimscript, you're going to have to spend some time experimenting, exploring, and playing with the language. To that end, why not take your biggest personal gripe about the way Vim currently works and see if you can script a better solution for yourself?

This article has described only Vimscript's basic variables, values, expressions, and functions. The range of "better solutions" you're likely to be able to construct with just those few components is, of course, extremely limited. So, in future installments, we'll look at more advanced Vimscript tools and techniques: data structures, flow control, user-defined commands, event-driven scripting, building Vim modules, and extending Vim using other scripting languages. In particular, the next article in this series will focus on the features of Vimscript's user-defined functions and on the many ways they can make your Vim experience better.

[Jul 10, 2009] Scripting the Vim editor, Part 2 User-defined functions

Functions in Vimscript are defined using the function keyword, followed by the name of the function, then the list of parameters (which is mandatory, even if the function takes no arguments). The body of the function then starts on the next line, and continues until a matching endfunction keyword is encountered. For example:

Listing 1. A correctly structured function

function ExpurgateText (text)
    let expurgated_text = a:text

    for expletive in [ 'cagal', 'frak', 'gorram', 'mebs', 'zarking']
        let expurgated_text
        \   = substitute(expurgated_text, expletive, '[DELETED]', 'g')

    return expurgated_text

The return value of the function is specified with a return statement. You can specify as many separate return statements as you need. You can include none at all if the function is being used as a procedure and has no useful return value. However, Vimscript functions always return a value, so if no return is specified, the function automatically returns zero.

Function names in Vimscript must start with an uppercase letter:

Listing 2. Function names start with an uppercase letter
function SaveBackup ()
    let b:backup_count = exists('b:backup_count') ? b:backup_count+1 : 1
    return writefile(getline(1,'$'), bufname('%') . '_' . b:backup_count)

nmap <silent>  <C-B>  :call SaveBackup()<CR>

This example defines a function that increments the value of the current buffer's b:backup_count variable (or initializes it to 1, if it doesn't yet exist). The function then grabs every line in the current file (getline(1,'$')) and calls the built-in writefile() function to write them to disk. The second argument to writefile() is the name of the new file to be written; in this case, the name of the current file (bufname('%')) with the counter's new value appended. The value returned is the success/failure value of the call to writefile(). Finally, the nmap sets up CTRL-B to call the function to create a numbered backup of the current file.

Instead of using a leading capital letter, Vimscript functions can also be declared with an explicit scope prefix (like variables can be, as described in Part 1). The most common choice is s:, which makes the function local to the current script file. If a function is scoped in this way, its name need not start with a capital; it can be any valid identifier. However, explicitly scoped functions must always be called with their scoping prefixes. For example:

Listing 3. Calling a function with its scoping prefix
" Function scoped to current script file...
function s:save_backup ()
    let b:backup_count = exists('b:backup_count') ? b:backup_count+1 : 1
    return writefile(getline(1,'$'), bufname('%') . '_' . b:backup_count)

nmap <silent>  <C-B>  :call s:save_backup()<CR>

Redeclarable functions

Function declarations in Vimscript are runtime statements, so if a script is loaded twice, any function declarations in that script will be executed twice, re-creating the corresponding functions.

Redeclaring a function is treated as a fatal error (to prevent collisions where two separate scripts accidentally declare functions of the same name). This makes it difficult to create functions in scripts that are designed to be loaded repeatedly, such as custom syntax-highlighting scripts.

So Vimscript provides a keyword modifier (function!) that allows you to indicate that a function declaration may be safely reloaded as often as required:

Listing 4. Indicating that a function declaration may be safely reloaded
function! s:save_backup ()
    let b:backup_count = exists('b:backup_count') ? b:backup_count+1 : 1
    return writefile(getline(1,'$'), bufname('%') . '_' . b:backup_count)

No redeclaration checks are performed on functions defined with this modified keyword, so it is best used with explicitly scoped functions (in which case the scoping already ensures that the function won't collide with one from another script).

Calling functions

To call a function and use its return value as part of a larger expression, simply name it and append a parenthesized argument list:

Listing 5. Using a function's return value
"Clean up the current line...
let success = setline('.', ExpurgateText(getline('.')) )

Note, however, that, unlike C or Perl, Vimscript does not allow you to throw away the return value of a function without using it. So, if you intend to use the function as a procedure or subroutine and ignore its return value, you must prefix the invocation with the call command:

Listing 6. Using a function without using its return value

"Checkpoint the text...
call SaveBackup()

Otherwise, Vimscript will assume that the function call is actually a built-in Vim command and will most likely complain that no such command exists. We'll look at the difference between functions and commands in a future article in this series.

Parameter lists

Vimscript allows you to define both explicit parameters and variadic parameter lists, and even combinations of the two.

You can specify up to 20 explicitly named parameters immediately after the declaration of the subroutine's name. Once specified, the corresponding argument values for the current call can be accessed within the function by prefixing an a: to the parameter name:

Listing 7. Accessing argument values within the function
function PrintDetails(name, title, email)
    echo 'Name:   '  a:title  a:name
    echo 'Contact:'  a:email

If you don't know how many arguments a function may be given, you can specify a variadic parameter list, using an ellipsis (...) instead of named parameters. In this case, the function may be called with as many arguments as you wish, and those values are collected into a single variable: an array named a:000. Individual arguments are also given positional parameter names: a:1, a:2, a:3, etc. The number of arguments is available as a:0. For example:

Listing 8. Specifying and using a variadic parameter list

function Average(...)
    let sum = 0.0

    for nextval in a:000        "a:000 is the list of arguments
        let sum += nextval

    return sum / a:0            "a:0 is the number of arguments

Note that, in this example, sum must be initialized to an explicit floating-point value; otherwise, all the subsequent computations will be done using integer arithmetic.

Combining named and variadic parameters

Named and variadic parameters can be used in the same function, simply by placing the variadic ellipsis after the list of named parameters.

For example, suppose you wanted to create a CommentBlock() function that was passed a string and formatted it into an appropriate comment block for various programming languages. Such a function would always require the caller to supply the string to be formatted, so that parameter should be explicitly named. But you might prefer that the comment introducer, the "boxing" character, and the width of the comment all be optional (with sensible defaults when omitted). Then you could call:

Listing 9. A simple CommentBlock function call
call CommentBlock("This is a comment")


and it would return a multi-line string containing:

Listing 10. The CommentBlock return
// This is a comment


Whereas, if you provided extra arguments, they would specify non-default values for the comment introducer, the "boxing" character, and the comment width. So this call:

Listing 11. A more involved CommentBlock function call
call CommentBlock("This is a comment", '#', '=', 40)

would return the string:

Listing 12. The CommentBlock return
# This is a comment

Such a function might be implemented like so:

Listing 13. The CommentBlock implementation

function CommentBlock(comment, ...)
    "If 1 or more optional args, first optional arg is introducer...
    let introducer =  a:0 >= 1  ?  a:1  :  "//"

    "If 2 or more optional args, second optional arg is boxing character...
    let box_char   =  a:0 >= 2  ?  a:2  :  "*"

    "If 3 or more optional args, third optional arg is comment width...
    let width      =  a:0 >= 3  ?  a:3  :  strlen(a:comment) + 2

    " Build the comment box and put the comment inside it...
    return introducer . repeat(box_char,width) . "\<CR>"
    \    . introducer . " " . a:comment        . "\<CR>"
    \    . introducer . repeat(box_char,width) . "\<CR>"

If there is at least one optional argument (a:0 >= 1), the introducer parameter is assigned that first option (that is, a:1); otherwise, it is assigned a default value of "//". Likewise, if there are two or more optional arguments (a:0 >= 2), the box_char variable is assigned the second option (a:2), or else a default value of "*". If three or more optional arguments are supplied, the third option is assigned to the width variable. If no width argument is given, the appropriate width is autocomputed from the comment argument itself (strlen(a:comment)+2).

Finally, having resolved all the parameter values, the top and bottom lines of the comment box are constructed using the leading comment introducer, followed by the appropriate number of repetitions of the boxing character (repeat(box_char,width)), with the comment text itself sandwiched between them.

Of course, to use this function, you'd need to invoke it somehow. An insertion map is probably the ideal way to do that:

Listing 14. Invoking the function using an insertion map
"C++/Java/PHP comment...
imap <silent>  ///  <C-R>=CommentBlock(input("Enter comment: "))<CR>

"Ada/Applescript/Eiffel comment...
imap <silent>  ---  <C-R>=CommentBlock(input("Enter comment: "),'--')<CR>

"Perl/Python/Shell comment...
imap <silent>  ###  <C-R>=CommentBlock(input("Enter comment: "),'#','#')<CR>

In each of these maps, the built-in input() function is first called to request that the user type in the text of the comment. The CommentBlock() function is then called to convert that text into a comment block. Finally, the leading <C-R>= inserts the resulting string.

Note that the first mapping passes only a single argument, so it defaults to using // as its comment marker. The second and third mappings pass a second argument to specify # or -- as their respective comment introducers. The final mapping also passes a third argument, to make the "boxing" character match its comment introducer.

Functions and line ranges

You can invoke any standard Vim command—including call—with a preliminary line range, which causes the command to be repeated once for every line in the range:

"Delete every line from the current line (.) to the end-of-file ($)...

"Replace "foo" with "bar" everywhere in lines 1 to 10

"Center every line from five above the current line to five below it...

You can type :help cmdline-ranges in any Vim session to learn more about this facility.

In the case of the call command, specifying a range causes the requested function to be called repeatedly: once for each line in the range. To see why that's useful, let's consider how to write a function that converts any "raw" ampersands in the current line to proper XML &amp; entities, but that is also smart enough to ignore any ampersand that is already part of some other entity. That function could be implemented like so:

Listing 15. Function to convert ampersands
function DeAmperfy()
    "Get current line...
    let curr_line   = getline('.')

    "Replace raw ampersands...
    let replacement = substitute(curr_line,'&\(\w\+;\)\@!','&amp;','g')

    "Update current line...
    call setline('.', replacement)

The first line of DeAmperfy() grabs the current line from the editor buffer (getline('.')). The second line looks for any & in that line that isn't followed by an identifier and a colon, using the negative lookahead pattern '&\(\w\+;\)\@!'(see :help \@! for details). The substitute() call then replaces all such "raw" ampersands with the XML entity &amp;. Finally, the third line of DeAmperfy()updates the current line with the modified text.

If you called this function from the command line:

:call DeAmperfy()

it would perform the replacement on the current line only. But if you specified a range before the call:

:1,$call DeAmperfy()

then the function would be called once for each line in the range (in this case, for every line in the file).

Internalizing function line ranges

This call-the-function-repeatedly-for-each-line behavior is a convenient default. However, sometimes you might prefer to specify a range but then have the function called only once, and then handle the range semantics within the function itself. That's also easy in Vimscript. You simply append a special modifier (range) to the function declaration:

Listing 16. Range semantics within a function
function DeAmperfyAll() range
    "Step through each line in the range...
    for linenum in range(a:firstline, a:lastline)
        "Replace loose ampersands (as in DeAmperfy())...
        let curr_line   = getline(linenum)
        let replacement = substitute(curr_line,'&\(\w\+;\)\@!','&amp;','g')
        call setline(linenum, replacement)

    "Report what was done...
    if a:lastline > a:firstline
        echo "DeAmperfied" (a:lastline - a:firstline + 1) "lines"

With the range modifier specified after the parameter list, any time DeAmperfyAll() is called with a range such as:

:1,$call DeAmperfyAll()

then the function is invoked only once, and two special arguments, a:firstline and a:lastline, are set to the first and last line numbers in the range. If no range is specified, both a:firstline and a:lastline are set to the current line number.

The function first builds a list of all the relevant line numbers (range(a:firstline, a:lastline)). Note that this call to the built-in range() function is entirely unrelated to the use of the range modifier as part of the function declaration. The range() function is simply a list constructor, very similar to the range() function in Python, or the .. operator in Haskell or Perl.

Having determined the list of line numbers to be processed, the function uses a for loop to step through each:

for linenum in range(a:firstline, a:lastline)

and updates each line accordingly (just as the original DeAmperfy() did).

Finally, if the range covers more than a single line (in other words, if a:lastline > a:firstline), the function reports how many lines were updated.

Visual ranges

Once you have a function call that can operate on a range of lines, a particularly useful technique is to call that function via Visual mode (see :help Visual-mode for details).

For example, if your cursor is somewhere in a block of text, you could encode all the ampersands anywhere in the surrounding paragraph with:

Vip:call DeAmperfyAll()

Typing V in Normal mode swaps you into Visual mode. The ip then causes Visual mode to highlight the entire paragraph you're inside. Then, the : swaps you to Command mode and automatically sets the command's range to the range of lines you just selected in Visual mode. At this point you call DeAmperfyAll() to deamperfy all of them.

Note that, in this instance, you could get the same effect with just:

Vip:call DeAmperfy()

The only difference is that the DeAmperfy() function would be called repeatedly: once for each line the Vip highlighted in Visual mode.

A function to help you code

Most user-defined functions in Vimscript require very few parameters, and often none at all. That's because they usually get their data directly from the current editor buffer and from contextual information (such as the current cursor position, the current paragraph size, the current window size, or the contents of the current line).

Moreover, functions are often far more useful and convenient when they obtain their data through context, rather than through their argument lists. For example, a common problem when maintaining source code is that assignment operators fall out of alignment as they accumulate, which reduces the readability of the code:

Listing 16. Assignment operators out of alignment
let applicants_name = 'Luke'
let mothers_maiden_name = 'Amidala'
let closest_relative = 'sister'
let fathers_occupation = 'Sith'

Realigning them manually every time a new statement is added can be tedious:

Listing 17. Manually realigned assignment operators

let applicants_name     = 'Luke'
let mothers_maiden_name = 'Amidala'
let closest_relative    = 'sister'
let fathers_occupation  = 'Sith'

To reduce the tedium of that everyday coding task, you could create a key-mapping (such as ;=) that selects the current block of code, locates any lines with assignment operators, and automatically aligns those operators. Like so:

Listing 18. Function to align assignment operators

function AlignAssignments ()
    "Patterns needed to locate assignment operators...
    let ASSIGN_OP   = '[-+*/%|&]\?=\@<!=[=~]\@!'
    let ASSIGN_LINE = '^\(.\{-}\)\s*\(' . ASSIGN_OP . '\)'

    "Locate block of code to be considered (same indentation, no blanks)
    let indent_pat = '^' . matchstr(getline('.'), '^\s*') . '\S'
    let firstline  = search('^\%('. indent_pat . '\)\@!','bnW') + 1
    let lastline   = search('^\%('. indent_pat . '\)\@!', 'nW') - 1
    if lastline < 0
        let lastline = line('$')

    "Find the column at which the operators should be aligned...
    let max_align_col = 0
    let max_op_width  = 0
    for linetext in getline(firstline, lastline)
        "Does this line have an assignment in it?
        let left_width = match(linetext, '\s*' . ASSIGN_OP)

        "If so, track the maximal assignment column and operator width...
        if left_width >= 0
            let max_align_col = max([max_align_col, left_width])

            let op_width      = strlen(matchstr(linetext, ASSIGN_OP))
            let max_op_width  = max([max_op_width, op_width+1])

    "Code needed to reformat lines so as to align operators...
    let FORMATTER = '\=printf("%-*s%*s", max_align_col, submatch(1),
    \                                    max_op_width,  submatch(2))'

    " Reformat lines with operators aligned in the appropriate column...
    for linenum in range(firstline, lastline)
        let oldline = getline(linenum)
        let newline = substitute(oldline, ASSIGN_LINE, FORMATTER, "")
        call setline(linenum, newline)

nmap <silent>  ;=  :call AlignAssignments()<CR>

The AlignAssignments() function first sets up two regular expressions (see :help pattern for the necessary details of Vim's regex syntax):
let ASSIGN_OP   = '[-+*/%|&]\?=\@<!=[=~]\@!'
let ASSIGN_LINE = '^\(.\{-}\)\s*\(' . ASSIGN_OP . '\)'


The pattern in ASSIGN_OP matches any of the standard assignment operators: =, +=, -=, *=, etc. but carefully avoids matching other operators that contain =, such as == and =~. If your favorite language has other assignment operators (such as .= or ||= or ^=), you could extend the ASSIGN_OP regex to recognize those as well. Alternatively, you could redefine ASSIGN_OP to recognize other types of "alignables," such as comment introducers or column markers, and align them instead.

The pattern in ASSIGN_LINE matches only at the start of a line (^), matching a minimal number of characters (.\{-}), then any whitespace (\s*), then an assignment operator.

Note that both the initial "minimal number of characters" subpattern and the operator subpattern are specified within capturing parentheses: \(...\). The substrings captured by those two components of the regex will later be extracted using calls to the built-in submatch() function; specifically, by calling submatch(1) to extract everything before the operator, and submatch(2) to extract the operator itself.

AlignAssignments() then locates the range of lines on which it will operate:

let indent_pat = '^' . matchstr(getline('.'), '^\s*') . '\S'
let firstline  = search('^\%('. indent_pat . '\)\@!','bnW') + 1
let lastline   = search('^\%('. indent_pat . '\)\@!', 'nW') - 1
if lastline < 0
    let lastline = line('$')

In earlier examples, functions have relied on an explicit command range or a Visual mode selection to determine which lines they operate on, but this function computes its own range directly. Specifically, it first calls the built-in matchstr() function to determine what leading whitespace ('^\s*') appears at the start of the current line (getline('.'). It then builds a new regular expression in indent_pat that matches exactly the same sequence of whitespace at the start of any non-empty line (hence the trailing '\S').

AlignAssignments() then calls the built-in search() function to search upwards (using the flags 'bnW') and locate the first line above the cursor that does not have precisely the same indentation. Adding 1 to this line number gives the start of the range of interest, namely, the first contiguous line with the same indentation as the current line.

A second call to search() then searches downwards ('nW') to determine lastline: the number of the final contiguous line with the same indentation. In this second case, the search might hit the end of the file without finding a differently indented line, in which case search() would return -1. To handle this case correctly, the following if statement would explicitly set lastline to the line number of the end of file (that is, to the line number returned by line('$')).

The result of these two searches is that AlignAssignments() now knows the full range of lines immediately above or below the current line that all have precisely the same indentation as the current line. It uses this information to ensure that it aligns only those assignment statements at the same scoping level in the same block of code. Unless, of course, the indentation of your code doesn't correctly reflect its scope, in which case you fully deserve the formatting catastrophe about to befall you.

The first for loop in AlignAssignments() determines the column in which the assignment operators should be aligned. This is done by walking through the list of lines in the selected range (the lines retrieved by getline(firstline, lastline)) and checking whether each line contains an assignment operator (possibly preceded by whitespace):

let left_width = match(linetext, '\s*' . ASSIGN_OP)

If there is no operator in the line, the built-in match() function will fail to find a match and will return -1. In that case, the loop simply skips on to the next line. If there is an operator, match() will return the (positive) index at which that operator appears. The if statement then uses the built-in max() function to determine whether this latest column position is further right than any previously located operator, thereby tracking the maximum column position required to align all the assignments in the range:

let max_align_col = max([max_align_col, left_width])

The remaining two lines of the if use the built-in matchstr() function to retrieve the actual operator, then the built-in strlen() to determine its length (which will be 1 for a "=" but 2 for '+=', '-=', etc.) The max_op_width variable is then used to track the maximum width required to align the various operators in the range:
let op_width     = strlen(matchstr(linetext, ASSIGN_OP))
let max_op_width = max([max_op_width, op_width+1])

Once the location and width of the alignment zone have been determined, all that remains is to iterate through the lines in the range and reformat them accordingly. To do that reformatting, the function uses the built-in printf() function. This function is very useful, but also very badly named. It is not the same as the printf function in C or Perl or PHP. It is, in fact, the same as the sprintf function in those languages. That is, in Vimscript, printf doesn't print a formatted version of its list of data arguments; it returns a string containing a formatted version of its list of data arguments.

Ideally, in order to reformat each line, AlignAssignments() would use the built-in substitute() function, and replace everything up to the operator with a printf'd rearrangement of that text. Unfortunately, substitute() expects a fixed string as its replacement value, not a function call.

So, in order to use a printf() to reformat each replacement text, you need to use the special embedded replacement form: "\=expr". The leading \= in the replacement string tells substitute() to evaluate the expression that follows and use the result as the replacement text. Note that this is similar to the <C-R>= mechanism in Insert mode, except this magic behavior only works for the replacement string of the built-in substitute() function (or in the standard :s/.../.../ Vim command).

In this example, the special replacement form will be the same printf for every line, so it is pre-stored in the FORMATTER variable before the second for loop begins:

let FORMATTER = '\=printf("%-*s%*s", max_align_col, submatch(1),
\                                    max_op_width,  submatch(2))'

When it is eventually called by substitute(), this embedded printf() will left-justify (using a %-*s placeholder) everything to the left of the operator (submatch(1)) and place the result in a field that's max_align_col characters wide. It will then right-justify (using a %*s) the operator itself (submatch(2)) into a second field that's max_op_width characters wide. See :help printf() for details on how the - and * options modify the two %s format specifiers used here.

With this formatter now available, the second for loop can finally iterate through the full range of line numbers, retrieving the corresponding text buffer contents one line at a time:

for linenum in range(firstline, lastline)
    let oldline = getline(linenum)

The loop then uses substitute() to transform those contents, by matching everything up to and including any assignment operator (using the pattern in ASSIGN_LINE) and replacing that text with the result of the printf() call (as specified by FORMATTER):
    let newline = substitute(oldline, ASSIGN_LINE, FORMATTER, "")
    call setline(linenum, newline)

Once the for loop has iterated all the lines, any assignment operators within them will now be aligned correctly. All that remains is to create a key-mapping to invoke AlignAssignments(), like so:
nmap <silent>  ;=  :call AlignAssignments()<CR>

Looking ahead

Functions are an essential tool for decomposing an application into correct and maintainable components, in order to manage the complexity of real-world Vim programming tasks.

Vimscript allows you to define functions with fixed or variadic parameter lists, and to have them interact either automatically or in user-controlled ways with ranges of lines in the editor's text buffer. Functions can call back to Vim's built-in features (for example, to search() or substitute() text), and they can also directly access editor state information (such as determining the current line the cursor is on via line('.')) or interact with any text buffer currently being edited (via getline() and setline()).

This is undoubtedly a powerful facility, but our ability to programmatically manipulate state and content is always limited by how cleanly and accurately we can represent the data on which our code operates. So far in this series of articles, we've been restricted to the use of single scalar values (numbers, strings, and booleans). In the next two articles, we'll explore the use of much more powerful and convenient data structures: ordered lists and random-access dictionaries.

[Sep 16, 2008] Vim 7.2


Vim is an almost fully-compatible version of the Unix editor Vi. Many new features have been added including multi-level undo,

It is descended from the vi clone "stevie" and runs on many systems, including Unix, MS Windows, OS/2, Macintosh, VMS, and Amiga.

This is a stable version with many bugfixes and updated runtime files. The only new feature worth mentioning is support for floating point. Upgrading from a previous version is highly recommended: A few crashing bugs and several security issues were fixed.

[Feb 6, 2008] Eclim 1.3.4 by Eric Van Dewoestine

About: Eclim (Eclipse integration in vim) is a set of eclipse and vim plugins that bring Eclipse functionality to the vim editor. It exposes Eclipse features through a server interface and includes a set of vim plugins that communicate with Eclipse over that interface.

[Feb 6, 2008] Project details for Cream for Vim

Cream is a configuration of the famous Vim text editor that makes it easier to use, like an Apple- or Windows-style text editor. It uses Vim's own extensibility to improve menus, keyboard shortcuts, and editing behavior. Cream seamlessly maintains Vim's insertmode to access all the power of the original Vim plus many custom Cream extensions.

Release focus: Minor feature enhancements

This is a minor release that adds three common keyboard shortcuts, an updated French translation for menus, better Apple/Mac behavior, and improvements to the Email Prettyfier and Slide Generator add-ons. Cream is now distributed under the newest version of the GNU General Public License, now version 3.

[Dec 28, 2007] Vim tips Using tabs By Joe 'Zonker' Brockmeier

January 24, 2007 |
Before Vim 7.0 was released last May, I usually had six or seven xterms or Konsole windows open, each with a single Vim session in which I was editing a single file. This takes up a lot of screen space, and isn't very efficient. With Vim 7.0, users now have the option of using tabs within Vim. With Vim's tab features you can consolidate all your sessions into one window and move between files more easily.

If you're using an version of Vim older than 7.0, you won't have access to this feature. By now, though, most distros have moved to Vim 7.0, so if you're using a recent release you should be OK.

Opening a tab

Let's start by opening a new tab in Vim. There are a few ways to do this. Probably the easiest to remember is to run the :tabnew command while in normal mode. This will open a new tab with an empty buffer. If you want to edit a file in the new tab, you can run :tabnew filename and Vim will load the file in the new tab.

Another way to do this is to open more than one file at startup using the -p option. If you want to open three files in separate tabs, you'd use this syntax:

vim -p file1 file2 file3

This will start a Vim session with file1 in the first tab, file2 in the second tab, and file3 in the third.

Vim will open up as many tabs as you like on startup, up to the maximum number of tabs set in the .vimrc file. The default maximum is 10 tabs, but you can change this by setting the tabpagemax option in your .vimrc, like so:

set tabpagemax=15

If you exceed the number of tabs allowed by tabpagemax Vim will simply open the maximum number of tabs, and the other files will be open but not displayed. You can edit the remaining files by using the :next or :last command to move to the files that are not displayed in a tab. Note that this setting only applies to the maximum number of tabs Vim will open on startup -- you can still open more tabs during your Vim session.

The :tabf command allows you to search for a file in your current path and open it in a new tab. For instance, if you want to open a file called inventory.txt that's in your current path, you could run:

:tabf inven*

That will search for a file that matches the string inven and any number of characters after it. If only one file is found, Vim will open it in a new tab. If you have several files that match, Vim will complain that too many files match, and you'll have to narrow the search a little. The :tabn command will do autocompletion of file names in your path, so you can just type the first few characters of a filename and hit Tab to find the right file.


Moving between tabs

You can switch between tabs using :tabn and :tabp, or you can use gt while you're in normal mode. Of course, if you're using Vim's GUI, GVim, you can also use the mouse to switch between tabs or use keyboard shortcuts. In GVim, you can also access a context menu for tabs by right-clicking on the tab bar. Here you can open new tabs with a new buffer or an existing file, or close the current tab.

If you have a lot of tabs open, you can use :tabfirst, or just :tabfir, to jump to the first tab, and :tablast to jump to the last tab that's open.

By default, the tab labels are shown at the top of the Vim window only when tabs are open. If you want to see the tab bar all the time, you can modify the showtabline option in your .vimrc. To set this to display all of the time, use:

set showtabline=2

If you want to turn it off altogether, use 0 instead of 2.

Note that the tabs are still there, even if the tab bar isn't displayed. If you have the tabline option set to 0, you can still see what tabs are open by using the :tabs command, which will provide a summary of open tabs, as you can see in the figure.

Speaking of setting options, if you don't like the existing shortcuts for the tab commands, you can add your own. For instance, if you want to make it easy to open a new tab, you might insert this into your .vimrc:

imap ,t <Esc>:tabnew<CR>

This tells Vim to set up a keymap for ,t in insert mode, to run Esc to put Vim into normal mode, then :tabnew and a carriage return to run the command. You can set up mappings for all of the tab commands that you use regularly. For more on setting up mappings, see our article Using Vim mappings and abbreviations.

Rearranging tabs

If you're really meticulous and want to position tabs just so in Vim, you can move the tabs to a specific spot in the tab order using :tabm n , where n is the position number that you want to use. If you don't give the :tabm command an argument, then the current tab will be moved to the last spot.

Vim starts tab numbering from 0, so if you have six tabs open, you'll have tab 0 through tab 5. So, if you're in the first tab and want to move it to the fourth position, you'd run :tab 3.

Note that you can still use viewports normally within tabbed windows, and tabs are useful for doing a quick edit in a file when you have a main Vim window set up with a couple of viewports arranged just right.

Running commands in tabs

Let's say you're editing six or seven files in Vim and realize that you need to replace a variable name with a new one. Using the :tabdo command, you can run a search and replace through all of the tabs at once rather than changing each file individually. For instance, if you want to replace foo with bar, you'd run this:

:tabdo %s/foo/bar/g

That will run through each open tab and run the search and replace command (%s/foo/bar/g) in each one.

Tabs can be extremely useful, and it only takes a short while to become proficient with them. For more on working with tabs in Vim, run :help tab-page-intro within Vim.

[Nov 6, 2007] Adding a little Cream to (g)Vim By Scott Nesbitt

 May 16, 2007 |
Even though I'm a die-hard Emacs user, there are times when I have to use the vi editor -- specifically gVim, the graphical face of the popular vi clone Vim. Since I use gVim so infrequently, I don't readily remember many of the editor's basic commands. Either I muddle through or reach for my well-thumbed copy of the vi Editor Pocket Reference. That was until I discovered Cream. With Cream, gVim becomes an easy-to-use editor -- so easy, in fact, you might not believe that you're using vi.

Cream is a set of scripts and add-ons that sit on top of gVim. Cream doesn't change the appearance of gVim, but it does change the way it behaves. You no longer need to remember or use the traditional colon followed by one or more letters to execute a command -- for example, :w to save a file. Instead, you can use keystroke combinations that are common to many Linux and Windows text editors, such as Ctrl-C to copy text or Alt-F to open the File menu. Cream's developers bill it as "a modern configuration of the Vim text editor."

Getting Cream is easy. You can download the sources, as well as packages for Debian, Gentoo, Ubuntu, and FreeBSD, from the Cream Web site. A Windows installer is also available. Ubuntu users can get Cream using the Synaptic Package Manager, while users of Linspire and Freespire can install it via the CNR Service. If you use Debian, just run apt-get install cream at the command line.

Cream's gVim menus  
Cream's gVim menus - click to enlarge
Getting to work 

You start Cream by either clicking the icon that was added to your menu (Applications -> Accessories in Ubuntu), or by typing cream at the command line or in your application launcher. If you've used gVim before, you'll notice that, post-Cream, the menus have changed. As one friend of mine put it, "Cream un-techified Vim." Gone are menus like Syntax and Buffers, which have been replaced by more user-friendly menus with names like Format, Settings, and Insert. You don't have to dig as deeply through Cream's menus to find the command that you're looking for; those commands are just a couple of clicks away.

Cream retains just about all of Vim's features, and it has a few interesting ones of its own. Some of the more useful are a tabbed interface (only available if you're using Vim 7.0 or newer), the ability to quickly wrap or justify text, and a spelling checker. While version 7.0 of Vim has an on-the-fly spelling checker, that feature is missing from older versions of the editor -- like the one I use, version 6.4.6. You can also switch between using Cream keystrokes and commands and those used by vi or Vim. That way, you get the best of both worlds, if you're so inclined.

One aspect of Cream that I found a bit frustrating was not being able to use the handful of Vim extensions that I'd installed. For example, when I open a LaTeX document in gVim, the LaTeX extension displays three additional menus that help me edit and compile files -- but not if I have Cream installed. I wasn't able to find a way to get around this problem.


Files via Cream  
Files via Cream - click to enlarge
Using add-ons and plugins 

Add-ons are functions that add extra flexibility to Cream. Cream comes with 20 add-ons, some of which you may find useful and others you can do without. With the add-ons, you can strip ASCII text from a binary file, convert a text file to HTML, sort lines, and reformat an email address so that it's not vulnerable to harvesting by spammers. There's also a slide generator add-on that can create an HTML-based slide show using images in a directory that you specify, and a built-in typing tutor for users who wants to improve their typing speed.

Cream also comes with some useful plugin utilities. One is the File Tree, which acts a lot like the Emacs Speedbar extension. Using the File Tree, I quickly navigate around my file system and open files without using the Open File dialog box. While I don't find it incredibly useful, I know a couple of Cream aficionados who can't live without the Calendar plugin, which embeds a calendar within the editor.

If you're a long-time user of Vim and/or gVim, Cream probably isn't for you. You're undoubtedly familiar with many of Vim's commands, and don't need the assistance of a CUA-enabled editor. On the other hand, if you use gVim infrequently or want to take advantage of the power of Vim without learning the editor's commands, then Cream is definitely worth a look.

Scott Nesbitt is a freelance journalist and technical writer.

[Nov 5, 2007] A more informative status line for Vim

This article is excerpted from the recently published book Hacking Vim.

To the right, the default status line shows the number of the current row and column and to the left it shows name of the file currently open (if any). Whenever you execute a Vim command, the status line disappears and the command buffer is shown in that line instead. If the command you execute writes any messages, then those are shown on the right of the status line.

For simple and fast file editing, this status line is adequate. But if you use Vim every day and for a lot of different file formats, it would be nice to have a more informative status line.

The command that sets how the status line should look is called:

:set statusline format

where format is a printf-like string that describes how the status line should look.

If you look in the Vim help system by typing :help 'statusline', you will see that the status line can contain a wide variety of information. Some pieces are more useful in your daily work than others.

My status line always contains information about:

The following command will turn your status line into a true information bar with all the above information:

:set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [ASCII=\%03.3b]\ [HEX=\%02.2B]\ [POS=%04l,%04v][%p%%]\ [LEN=%L] 

I have added a '[ ]' around each of the pieces of information so that it is easier to distinguish them from each other. This is purely to give a visual effect; you can leave them out.

Even after entering that command, the status line still shows the old non-informative status line, as in the default installation. This problem occurs because Vim, by default, does not show the status line at all. Instead, it just shows the command buffer with a little bit of information in it. To tell Vim that you would like to have a real status line shown, you have to add the following setting to your vimrc file. This command will make sure that your status line is always shown as the second last line in the editor window:

:set laststatus=2 

You will then see that the command buffer gets a place of its own in the last line of the editor window. This way there's always room for the status line, and you will always have information about the file right in front of you. The status line does of course take up some of the editing area. You can always remove it for the rest of the editing session by executing the following command from within Vim:

:set laststatus=0

Toggle menu and toolbar

If you are used to working with Vim in the console mode, you are used to having no menus and toolbars at the top of the window. Gvim, however, provides both a menu and toolbar by default in the GUI.

Many users believe that extra room for text is more important than the menu and the toolbar. However, some scripts add useful functionality in the menu, and it is therefore important to have the menus. The solution for this could be toggling whether the menu and toolbar is shown.

The following code maps the key combination Ctrl-F2 to toggle the menu and toolbar in Gvim. You can add it to your vimrc file if you want this functionality.

map <silent> <C-F2> :if &guioptions =~# 'T' <Bar>
                         \set guioptions-=T <Bar>
                         \set guioptions-=m <bar>

                    \else <Bar>
                         \set guioptions+=T <Bar>
                         \set guioptions+=m <Bar>


Now, whenever you don't need the menu and toolbar, you can just press Ctrl-F2 and you will get the full space for your text.

If you want either the menu or the toolbar to be hidden all the time, add one of the following lines to your vimrc file. To remove the menu completely:

:set guioptions-=m 

To remove the toolbar completely:

:set guioptions-=T 

Other parts of the GUI can be modified with the setguioptions command. To find out what you can modify, look in :help 'guioptions'.

[Oct 5, 2007] Turn Vim into a bash IDE By Joe 'Zonker' Brockmeier

June 11, 2007 |
By itself, Vim is one of the best editors for shell scripting. With a little tweaking, however, you can turn Vim into a full-fledged IDE for writing scripts. You could do it yourself, or you can just install Fritz Mehner's Bash Support plugin.

To install Bash Support, download the zip archive, copy it to your ~/.vim directory, and unzip the archive. You'll also want to edit your ~/.vimrc to include a few personal details; open the file and add these three lines:

let g:BASH_AuthorName   = 'Your Name'
let g:BASH_Email        = ''
let g:BASH_Company      = 'Company Name'

These variables will be used to fill in some headers for your projects, as we'll see below.

The Bash Support plugin works in the Vim GUI (gVim) and text mode Vim. It's a little easier to use in the GUI, and Bash Support doesn't implement most of its menu functions in Vim's text mode, so you might want to stick with gVim when scripting.

When Bash Support is installed, gVim will include a new menu, appropriately titled Bash. This puts all of the Bash Support functions right at your fingertips (or mouse button, if you prefer). Let's walk through some of the features, and see how Bash Support can make Bash scripting a breeze.

Header and comments

If you believe in using extensive comments in your scripts, and I hope you are, you'll really enjoy using Bash Support. Bash Support provides a number of functions that make it easy to add comments to your bash scripts and programs automatically or with just a mouse click or a few keystrokes.

When you start a non-trivial script that will be used and maintained by others, it's a good idea to include a header with basic information -- the name of the script, usage, description, notes, author information, copyright, and any other info that might be useful to the next person who has to maintain the script. Bash Support makes it a breeze to provide this information. Go to Bash -> Comments -> File Header, and gVim will insert a header like this in your script:

#          FILE:
#         USAGE:  ./
#       OPTIONS:  ---
#          BUGS:  ---
#         NOTES:  ---
#        AUTHOR:  Joe Brockmeier,
#       COMPANY:  Dissociated Press
#       VERSION:  1.0
#       CREATED:  05/25/2007 10:31:01 PM MDT
#      REVISION:  ---

You'll need to fill in some of the information, but Bash Support grabs the author, company name, and email address from your ~/.vimrc, and fills in the file name and created date automatically. To make life even easier, if you start Vim or gVim with a new file that ends with an .sh extension, it will insert the header automatically.

As you're writing your script, you might want to add comment blocks for your functions as well. To do this, go to Bash -> Comment -> Function Description to insert a block of text like this:

#===  FUNCTION  ================================================================
#          NAME:
#       RETURNS:

Just fill in the relevant information and carry on coding.

The Comment menu allows you to insert other types of comments, insert the current date and time, and turn selected code into a comment, and vice versa.

Statements and snippets

Let's say you want to add an if-else statement to your script. You could type out the statement, or you could just use Bash Support's handy selection of pre-made statements. Go to Bash -> Statements and you'll see a long list of pre-made statements that you can just plug in and fill in the blanks. For instance, if you want to add a while statement, you can go to Bash -> Statements -> while, and you'll get the following:

while _; do

The cursor will be positioned where the underscore (_) is above. All you need to do is add the test statement and the actual code you want to run in the while statement. Sure, it'd be nice if Bash Support could do all that too, but there's only so far an IDE can help you.

However, you can help yourself. When you do a lot of bash scripting, you might have functions or code snippets that you reuse in new scripts. Bash Support allows you to add your snippets and functions by highlighting the code you want to save, then going to Bash -> Statements -> write code snippet. When you want to grab a piece of prewritten code, go to Bash -> Statements -> read code snippet. Bash Support ships with a few included code fragments.

Another way to add snippets to the statement collection is to just place a text file with the snippet under the ~/.vim/bash-support/codesnippets directory.

Running and debugging scripts

Once you have a script ready to go, and it's testing and debugging time. You could exit Vim, make the script executable, run it and see if it has any bugs, and then go back to Vim to edit it, but that's tedious. Bash Support lets you stay in Vim while doing your testing.

When you're ready to make the script executable, just choose Bash -> Run -> make script executable. To save and run the script, press Ctrl-F9, or go to Bash -> Run -> save + run script.

Bash Support also lets you call the bash debugger (bashdb) directly from within Vim. On Ubuntu, it's not installed by default, but that's easily remedied with apt-get install bashdb. Once it's installed, you can debug the script you're working on with F9 or Bash -> Run -> start debugger.

If you want a "hard copy" -- a PostScript printout -- of your script, you can generate one by going to Bash -> Run -> hardcopy to This is where Bash Support comes in handy for any type of file, not just bash scripts. You can use this function within any file to generate a PostScript printout.

Bash Support has several other functions to help run and test scripts from within Vim. One useful feature is syntax checking, which you can access with Alt-F9. If you have no syntax errors, you'll get a quick OK. If there are problems, you'll see a small window at the bottom of the Vim screen with a list of syntax errors. From that window you can highlight the error and press Enter, and you'll be taken to the line with the error.

Put away the reference book...

Don't you hate it when you need to include a regular expression or a test in a script, but can't quite remember the syntax? That's no problem when you're using Bash Support, because you have Regex and Tests menus with all you'll need. For example, if you need to verify that a file exists and is owned by the correct user ID (UID), go to Bash -> Tests -> file exists and is owned by the effective UID. Bash Support will insert the appropriate test ([ -O _]) with your cursor in the spot where you have to fill in the file name.

To build regular expressions quickly, go to the Bash menu, select Regex, then pick the appropriate expression from the list. It's fairly useful when you can't remember exactly how to express "zero or one" or other regular expressions.

Bash Support also includes menus for environment variables, bash builtins, shell options, and a lot more.

Hotkey support

Vim users can access many of Bash Support's features using hotkeys. While not as simple as clicking the menu, the hotkeys do follow a logical scheme that makes them easy to remember. For example, all of the comment functions are accessed with \c, so if you want to insert a file header, you use \ch; if you want a date inserted, type \cd; and for a line end comment, use \cl.

Statements can be accessed with \a. Use \ac for a case statement, \aie for an "if then else" statement, \af for a "for in..." statement, and so on. Note that the online docs are incorrect here, and indicate that statements begin with \s, but Bash Support ships with a PDF reference card (under .vim/bash-support/doc/bash-hot-keys.pdf) that gets it right.

Run commands are accessed with \r. For example, to save the file and run a script, use \rr; to make a script executable, use \re; and to start the debugger, type \rd. I won't try to detail all of the shortcuts, but you can pull up a reference using :help bashsupport-usage-vim when in Vim, or use the PDF. The full Bash Support reference is available within Vim by running :help bashsupport, or you can read it online.

Of course, we've covered only a small part of Bash Support's functionality. The next time you need to whip up a shell script, try it using Vim with Bash Support. This plugin makes scripting in bash a lot easier.


[Nov 14, 2006] Vifm

Vifm is a ncurses based file manager with vi like keybindings. If you use vi, vifm gives you complete keyboard control over your files without having to learn a new set of commands.

Basic Movement


Searching Additional Normal Mode Keys Commands File Filters

[Oct 25, 2006] Vim 7!

May 8, 2006 (vimannonce grroup) Vim 7 is ready! After years of development this feature packed editor
is waiting for you.

Since Vim 6.4 many new features have been added. To mention a few:

- Spell checking support for about 50 languages
- Intelligent completion for C, HTML, Ruby, Python, PHP, etc.
- Tab pages, each containing multiple windows
- Undo branches: never accidentally lose text again

- Vim script supports Lists and Dictionaries (similar to Python)
- Vim script profiling
- Improved Unicode support
- Highlighting of cursor line, cursor column and matching braces
- Translated manual pages support.
- Internal grep; works on all platforms, searches compressed files
- Browsing remote directories, zip and tar archives
- Printing multi-byte text

Once you have installed Vim 7.0 you can find details about the changes
since Vim 6.4 with ":help version7".

[May 25, 2006] Vim tips Folding fun

The problem with writing and editing on a computer, versus having words on paper, is that it's usually hard to compare text from different sections of a document when they don't fit on the screen together. One way to do it is to use Vim's viewports feature. Another is to "fold" the text. Using Vim's folding features, you can tuck away portions of a file's text so that they're out of sight until you want to work with them again. Here's how.

Vim's folding commands begin with z -- which, as the Vim docs point out, sort of looks like a folded piece of paper. OK, maybe not much, but at least the commands are consistent. If you want to do something with folding, it probably starts with z. (Since Vim 7 added spellchecking, some of the spellcheck commands also start with z, but that's a topic for another article.)

Creating folds

Let's start with some simple folding actions. Pick a text file, preferably a longer one like your xorg.conf, or just about any text file that's too big to fit on the screen by itself. Open it in Vim, and place the cursor at the beginning of a paragraph. Make sure you're in normal mode, and type zf2j. After you press j, Vim will create a fold covering three lines -- the line you started the fold on, and the next two lines. If you're familiar with Vim's movement commands, you know that the command 2j would usually tell Vim to move down two lines. Vim uses the same movement commands to define folds.

Folding also works in visual mode. If you enter visual mode using v or V, then select a few lines of text using the movement keys, and type zf, Vim will create a fold comprising those lines.

Another option is to specify a range in command mode. For instance, if you wanted to create a fold from lines 20 through 101, you could just use :20,101 fold and press Enter. In fact, you don't even need to type the entire word -- you can use fo instead of fold if you want to save a couple of keystrokes. Note that this will work backwards as well -- so if you use :.,20 fo when the cursor is on line 101, Vim will reverse the range and create the fold from lines 20 to 101.

Vim can also make some smart text selections. Let's say you're working on a script or program and you have a block of text within braces ({}). Position the cursor on the first brace, and type zfa}. Vim will create a fold from the line with the first brace through the last; it's not necessary to know which lines you're working with, Vim will just look for the closing brace. This also works with other block enclosures -- parenthesis, brackets ([]), and angle brackets (<>).

As an added bonus, Vim also recognizes nested blocks, so it will create the fold based on matching delimiters, and not the first closing bracket it comes across. Vim will also work backwards. If you're on a closing brace, type zfa{ and Vim will create a fold from the current spot to the beginning brace.

Folds are nestable as well -- that is to say, you can create a fold, and then include that within a larger section of folded text.

Finally, you can create a fold from the cursor position to a search result. If you run zf/string , Vim will create a fold from the cursor position to the first instance of the search string. Again, this is useful when you know you want a fold to go from the line you're on to a line further down in the file, but you're not sure what the line number is.

Once you've created a fold you'll see a single line of text that shows how many lines are folded, as well as the initial text, like this:

+-- 15 lines: set_up_socket_dir () {--------------------------------------------

The dashes indicate the foldlevel of the particular fold. For a top-level fold, you should see two dashes. Nested folds will have more dashes. We'll cover the foldlevel in more depth in just a bit.

Vim folding commands
zf#j creates a fold from the cursor down # lines.
zf/string creates a fold from the cursor to string .
zj moves the cursor to the next fold.
zk moves the cursor to the previous fold.
zo opens a fold at the cursor.
zO opens all folds at the cursor.
zm increases the foldlevel by one.
zM closes all open folds.
zr decreases the foldlevel by one.
zR decreases the foldlevel to zero -- all folds will be open.
zd deletes the fold at the cursor.
zE deletes all folds.
[z move to start of open fold.
]z move to end of open fold.

Using folds

Creating folds is only half the fun. At some point, you'll no doubt want to unfold the text. One way to do this is to place the cursor on the same line as the fold and type zo. This will "open" the fold, but not delete it. So if you want to do a quick check on some text that's been folded, use zo, and then zc to close it back up when you're finished.

To move between folds quickly, use the zj and zk commands to move to the next and previous fold. Note that it doesn't matter whether the folds are open or closed; if they exist, zj and zk will move backwards and forwards between them. These commands should be easy to remember, since they combine the fold command (z) with movement commands (j to move down a line, and k to move up a line). If you want to move between the start and end of a fold, use [z and ]z, respectively.

As we've already covered, Vim will create nested folds. If you use zo on a nested fold, it will open only the first fold -- the remaining folds will stay closed. However, if you'd like to open all of the nested folds on that line, use zO -- Vim will open all of the folds. Running zc in normal mode will close all the folds after using zO.

The zr command will open all first-level folds in Vim, and zR will open all of the folds in the file. The zm command will re-fold the first-level folds, and zM will close all open folds in a file. If you have multiple foldlevels, a fold within a fold within a fold, running zm will refold them sequentially -- so if all folds are open it will refold the deepest folds, then folds on the next foldlevel, and so on. The zr command works the same way, only in reverse -- it will open the top-level fold, then the next level, and so forth.

When you decide you want to get rid of a fold entirely, position the cursor on the fold and run zd. This will work whether the fold is open or closed. To zap all of the folds at once, type zE. Delete with caution, however. Vim's undo and redo features don't apply to folds; if you delete a fold, you can't press u and bring it back, and the . command won't run the last fold command.

You might be wondering, how does Vim treat text within folds when you are searching for text, or doing a search and replace on a file? Vim treats the text normally. If you search for a string of text that's within a fold, Vim will unfold the text when the cursor moves to the string within the fold. Unfortunately, Vim is a little less than tidy in this regard -- if a search causes a fold to be expanded, Vim doesn't re-fold the text after moving the cursor outside the fold. However, a quick zm will restore the folds.

Vim also treats a folded section of text as a single line for the purpose of deleting and yanking text. If you place the cursor on a section of folded text and use dd, it will delete the entire section, not just the first line. Vim will also allow you to yank the entire folded section of text just by placing the cursor on the folded text and typing Y or yy. The folded section can then be pasted into another section of the text using the p or P commands.

The foldmethod option

Vim's foldmethod option might be of interest to programmers. The default foldmethod is manual -- that is, creating folds manually. However, Vim can also create folds based on the way a file is indented, its syntax, or markers in the text.

To set the foldmethod according to the way a file is indented, run :set foldmethod=indent. This will automatically create folds at every indent. Consider a Cascading Style Sheet (CSS) file like this one:

body {
        background-color: #CCCCCC;
	font-family: arial, helvetica, sans-serif;

strong.header {
        font-family: arial, helvetica, sans-serif;
        color: #1D3C47;

Once you've set foldmethod=indent, it will look like this:

body {
+---  2 lines: background-color: #CCCCCC;---------------------------------------

strong.header {
+---  2 lines: font-family: arial, helvetica, sans-serif;-----------------------

Vim also offers a marker method, where folds are set by visible text markers rather than invisible manual marks. To set this mode, run :set foldmethod=marker. Then, when you set a fold, you'll see a marker with three braces at the beginning and end of the fold, like this:

Folded text goes here...

The braces are set off by comment characters, depending on the type of file. So, if you're working with an HTML file, you'll see <!--{{{-->, and if you're editing a Python script, you'll see #{{{. You can also insert fold markers manually if you want, and Vim will recognize them as well. Vim will also delete the markers with the zd command, whether they were set manually or not.

Fold created with the marker method are subject to undo and redo operations, unlike normal manual folds.

It's possible to set the foldmarker to something other than {{{ if you need to, but the Vim docs recommend that you stick with the defaults. To change the foldmarker, use :set foldmarker=nnn,mmm where nnn is the character string to start the marker, and mmm is the string to end the marker.

If you want to use a foldmethod other than "manual" all the time, add this line to your ~/.vimrc:

set foldmethod=foldoption

Vim has a few other foldmethods that may come in useful. See the foldmethod documentation in the Vim reference materials for more on the foldmethod option.

Saving folds

After you've gone to all the trouble of creating several folds in a longer document, it'd be a shame to lose them when you close the file. If you'd like to save the folds before you leave the file, run :mkview. When you reload the file, run :loadview, and Vim will restore the folds to the state the file was in at the time you ran :mkview.

The :mkview command supports multiple revisions of a file's state, so you can give a view a number and reload later on. For example, if you run :mkview 2, make a few changes, and then run :loadview 2, it will revert to the previous state of the file as far as folds are concerned. Note that it won't restore the file itself to the previous state; if you delete 10 lines of text after saving a view, Vim won't restore those lines when you load an older view using :loadview.

But why do something manually when you can do it automatically? To see to it that Vim saves and restores folds when a file is closed and re-opened, add these two lines to your ~/.vimrc:

au BufWinLeave * mkview
au BufWinEnter * silent loadview

Now, each time you close a file, its fold state will be saved and reloaded when you reopen the file in Vim.

When you add folds to other features like viewports and marks and jumps, Vim becomes an insanely productive tool for text editing and programming.

[May 17, 2006] Vim tips Moving around using marks and jumps by Joe 'Zonker' Brockmeier

Basically, a mark is a bookmark or placeholder that allows you to return to a spot in the file where you were editing. This can be handy when you're working on longer projects, whether you're writing a long paper, making changes to your Apache configuration, or writing code.

Jumps are movements within a file. For example, when you use G to move to the last line of a file from your current position, that's a jump. Vim not only makes it easy to move from one point in the file to another, it also makes it easy to retrace your steps.

m marks the spot

Let's take a look at Vim marks. All you need to do to set a mark is to enter normal mode, then type mx , where x is the letter you want to assign to the mark.

For example, if you're typing and decide that you need to set a mark so you can return to a sentence or line of code you're not entirely happy with, press Esc to leave insert mode, then type ma to set a mark at the spot your cursor was on.

You can use any letter in the alphabet, upper or lower case. However, capital letters are global marks, so you should use them only in special circumstances, which I'll explain in just a bit. It's not necessary to use them in alphabetical order; you can set mark z right after setting mark a if you like, or skip a altogether and start with z.

To return to the mark you've set, enter normal mode (if you're not in normal mode already) and type `x where x is the letter associated with the mark you want to revisit. The backtick (`) will return you to the exact spot where the mark was set. You can also use the single quote ('), which will return you to the beginning of the line you were at, but not the exact cursor position.

Marks set with lowercase letters are specific to the file that they're set in. That is to say, if you are using a Vim session to edit two files in a split viewport, then you can set mark a in both files. When you're editing file 1, using `a would take you to mark a in file 1. When in file 2, `a would take you to the spot in file 2 marked a -- which is probably what you'd expect.

However, if you're using Vim to edit two files and you've set mark A, it will be specific to that file. So, if you're editing file 2, and have mark A set in file 1 and use `A, Vim will close the current file and take you to mark A in file 1. If file 2 has unsaved changes, Vim will complain that you haven't written the file since the last change, and refuse to open the new file.

While global bookmarks are useful on occasion, it's usually best to stick to lower-case marks unless you have a specific need for global bookmarks.

Now where did I leave that?

After spending an hour or two editing a file, you might forget exactly where you've set marks in a file. If you'd like to see where they are, you can enter command mode and use the :marks command. Vim will display the name of each mark, the line and column number where it is set, and part of the text from that line. Note that Vim won't start the display on the column where the mark begins -- instead, you'll see the beginning of the line where the mark is set. So, if you've set marks for a, b, and c, you will see where those marks are set, but you'll also see a few other marks that you might not recognize. Here's a shortish example:

mark line  col file/text
 '    112    0
 a     11    3 <p>For example, if you're typing and decide that you
 b    103    0 <p>By default, when you exit Vim, the marks that you've
 D     26    0 ~/src/gaim-2.0.0beta2/src/Makefile
 0     61   60 <p>The " mark is set to the last position of the cursor
 1    103    0 <p>By default, when you exit Vim, the marks that you've
 "     35    0 <p><strong><code style="background-color: yellow;">'"</code>
 [     52    0
 ]     54    0
 ^     54    0
 .     73  115 <p>The . mark will take you to the last position a change
Press ENTER or type command to continue
Vim mark quick reference

mx tells Vim to add a mark called x.

`x tells Vim to return to the line and column for mark x.

'x tells Vim to return to the beginning of the line where mark x is set.

`. moves the cursor to the line and column where the last edit was made.

'. moves the cursor to the line where the last edit was made.

'" moves the cursor to the last position of the cursor when you exited the previous session.

:marks shows all marks set.

:marks x shows the mark named x.

:jumps shows the jumplist.

Ctrl-o moves the cursor to the last jump.

Ctrl-i moves the cursor to the previous jump.

H moves the cursor to the top of the screen or viewport.

M moves the cursor to the middle of the screen or viewport.

L moves the cursor to the bottom of the screen or viewport.

Specifically, you'll see marks for ., [, ], ", ', and a few others. Those marks are present whether you've set any marks manually or not. The [ and ] marks indicate the last changed or copied ("yanked") text. The [ mark is the first character of the text that's been changed or yanked, the ] is the last character of that text. Note that these marks don't work until you actually make a change in the file.

The . mark will take you to the last position a change was made. So, '. will take you to the line where the last change was made in your file, and `. will take you to the cursor position where the last change was made.

If you make a jump within a file -- that is, if you use a movement or search command to move within the file -- the ` character will return you to the position you started from. For example, using the G movement command you can jump to the bottom of the file. If you want to return to the last cursor position, use `` and you'll be moved back to the last location of the cursor before using G. We'll discuss jumps in more detail a bit later.

The " mark is set to the last position of the cursor when you exited the previous Vim session, if you have Vim configured to save your session information using a viminfo file. We'll cover that in just a bit too.

Finally, if your session information is being saved, you can also use numbered marks to return to the last position the cursor was at when you closed a file. Using numbered marks, `0 will move the cursor to the last position it was at when you closed a file. `1 will move the cursor to the last position it was at when you closed the file the time before last, and so forth.

If you just want to know where a specific mark is in the file, you can use :marks markname to display just those marks. To see marks a and B, for instance, you'd just use :marks aB. This is pretty useful when you have 10 or 20 marks set.

Advanced marking

Marks are useful for more than just moving about a file -- though that feature alone is very useful. Marks can also be used to specify a range for commands. Normally, if you want to delete a few lines, you can use line numbers to specify the line, like so:

:22,55 d

That will delete lines 22 through 55. But it's much easier to remember marks than line names most of the time. If you have line 22 marked as g and 55 marked as k, you could substitute :'g,'k d and remove those lines without having to go back and confirm the line numbers. This works with other commands too, so you could just as easily write those lines to a file using :'g,'k w filename or use the range for a substitution command like this:

:'g,'k s/foo/bar/g

The jumplist

Vim stores a list of your movements throughout a file, whether they're associated with marks or not. To see a full list of jumps within a file, use :jumps. Here's a short sample:

 jump line  col file/text
    3     1    0 /**
    2   608    0 }
    1    33    0 #include "log.h"
Press ENTER or type command to continue

Vim lists the jump number, line number, and column of the last location of the cursor for each jump, as well as a bit of text to help provide context. You can cycle between jump locations using the Ctrl-o and Ctrl-i keybindings. Ctrl-o will move you to the last jump, then the next-to-last, and so forth. In this instance, if you use Ctrl-o, you'd be taken to line 33, then line 608, then 1. To move forwards through the jump history, use Ctrl-i -- which would take you from line 1 (jump 3) to line 608, then line 33.

Though they're not jumps, since we're discussing moving around a file easily, you might want to familiarize yourself with the movement commands G, gg, H, M, and L. G, as we've already discussed, will take you to the bottom of the file. The gg command will move you to the top of the file. The H, M, and L commands will move you to the top, middle, and bottom of the screen, respectively.

Saving marks and jumps

By default, when you exit Vim, the marks and jumps that you've created are lost. Luckily, there's an easy way to save the marks you've created by making use of the viminfo file, which saves state information between Vim sessions.

To make sure this feature is enabled, open your .vimrc and look for a line that begins with set viminfo=. If you don't have that line, insert it. It should look something like this:

set viminfo='100,f1

If you have viminfo set, it will save local marks (a-z) by default. The '100 tells Vim to save marks and other information for up to 100 files. The f1 directive tells Vim to also save global marks (A-Z) when it exits. If you don't want Vim to do this, set it to f0 instead.

You can use the viminfo file for a lot more than saving marks and jumps, but we'll have to cover that in a future installment.

[May 10, 2006] Vim tips Using viewports

A lot of folks use Vim, but many exploit only a small percentage of the editor's features. Sure, you might know how to do the basics in Vim, but what about using more advanced features such as folding, split windows, and marks? With a little practice, you can really boost your productivity with Vim.

In this and future articles, I'm going to cover Vim features that you may not be familiar with if you're a casual Vim user. If you're confident using Vim to edit configuration files or make short edits in text files, but maybe not too comfortable with undertaking major writing or coding in Vim, then these articles should be for you.

Splitting Vim's viewport

A really useful feature in Vim is the ability to split the viewable area between one or more files, or just to split the window to view two bits of the same file more easily. The Vim documentation refers to this as a viewport or window, interchangeably.

You may already be familiar with this feature if you've ever used Vim's help feature by using :help topic or pressing the F1 key. When you enter help, Vim splits the viewport and opens the help documentation in the top viewport, leaving your document open in the bottom viewport.

Vim viewport keybinding quick reference

:sp will split the Vim window horizontally. Can be written out entirely as :split .

:vsp will split the Vim window vertically. Can be written out as :vsplit .

Ctrl-w Ctrl-w moves between Vim viewports.

Ctrl-w j moves one viewport down.

Ctrl-w k moves one viewport up.

Ctrl-w h moves one viewport to the left.

Ctrl-w l moves one viewport to the right.

Ctrl-w = tells Vim to resize viewports to be of equal size.

Ctrl-w - reduce active viewport by one line.

Ctrl-w + increase active viewport by one line.

Ctrl-w q will close the active window.

Ctrl-w r will rotate windows to the right.

Ctrl-w R will rotate windows to the left.

If you want to use this feature for something other than viewing Vim's help files, you can split the viewport by using :sp, :split, or Ctrl-w n -- they do the same thing, but just typing :sp will save you a few characters, and it's easier to use with arguments, such as filenames. Remember the Ctrl-w part, though, because it will come in handy for most operations with windows.

The :sp command will divvy up the viewport into two equal viewports for the file that you have open. If you'd like to work on two files simultaneously, no problem -- just follow the command with the filename you'd like to use, like this:

:sp filename

That will open filename in the new viewport. You can even add a search string to that to move directly to the first instance of a keyword, like so:

:sp +/searchstring filename

Easy as falling off a log. What if you don't want to have equal viewports? For example, let's say you want to open a reference file in the top viewport, but want the majority of the viewport available for the file you're actually editing. No problem. Just prepend a number to the sp command, and the new viewport will fill that number of lines:

:10 sp filename

Now you have a viewport with 10 lines, but what if you've decided that you'd like to give both viewports equal real estate? That's easy enough too. Instead of going into command mode, you can use a normal keybinding to accomplish this. Ctrl-w = tells Vim to assign an equal number of lines to each viewport.

To move between the viewports while working, use Ctrl-w j to move down, and Ctrl-w k to move up. This should prove easy to remember -- Ctrl-w for "window" commands, and the normal vi movement commands j for down and k for up. You can also cycle between viewports by using Ctrl-w Ctrl-w.

You can increase or decrease a viewport's size after it's been created. Use Ctrl-w + to increase the active viewport, and Ctrl-w - to decrease its size by one line. If one line at a time isn't sufficient, add a modifier before the + or -. For instance, to add 13 lines, use Ctrl-w 13+.

If horizontal viewports just don't do it for you, Vim also supports splitting viewports vertically. To do this, just use :vsp, or :vsplit if you prefer to spell it out. Movement between vertical viewports is similar to moving between horizontal viewports. Ctrl-w Ctrl-w works, and instead of using the j and k movement keys, use the h and l movement keys to move back and forth between viewports. To move to the viewport to the right, for example, you'd use Ctrl-w l.

It's also worth mentioning that you can open a file in a viewport just to view the file, without opening it to edit. To do this, use the :sview filename command. To do it vertically, use :vert sview filename .

You can close a window in one of several ways. The easiest is to just use the quit command, :q, or you can use Ctrl-w q. Note that if it's the only window open with a file, Vim will prompt you to save the file if it isn't saved already.

Also, it's possible to rotate the windows, if you decide you'd prefer to have the top window on the bottom or vice versa. To do this, use Ctrl-w r to move windows to the right or down. When you do this, for example, in a Vim session with three horizontal viewports open, the top viewport would go to the middle position, the middle viewport would take the bottom position, and the bottom viewport would rotate to the top. To go in the opposite direction, use Ctrl-w R instead.

Vim often offers several different ways to achieve the same things. For instance, as I pointed out, :sp, :split, and Ctrl-w n all create a new viewport. I haven't listed all of the possible commands or keybindings to accomplish all of the tasks here.

Over the years, I've found Vim's split windows features to be very useful. I often use it to edit a column or article in one viewport, and to read and copy from notes in another viewport.

[Mar 28, 2006] All about Linux Vim author gets hired by Google

Things have changed though - at least for Mr Moolenaar, because he has just been hired by Google and will start working for the search giant in Zurich. Does that mean, further development of Vim is going to take a back seat? Not at all! Bram has committed himself to its further support and development albeit at a reduced pace.

On a different note, I came across this cool cheatsheet which acts as a spring board in getting up and running in using vi / vim with ease. Of course, this is not in any way related to the official project.

[Nov 15, 2005] Windows Manager - 1.0

winmanager.vim is a plugin which implements a classical windows type IDE in Vim-6.0. Vim6.0 has some very cool features one of which is vertical splitting of windows. The time was thus ripe to make something like this. People have already made excellent File and Buffer explorers seperately and I thought that it might be a cool idea to combine them both.

winmanager.vim combines the standard File Explorer which ships with Vim6.0 and a Buffer Explorer written by Jeff Lanzarotta into one package. Unfortunately, I had to change a few features here and there so instead of using the packages as is, I have to ship a relatively very small plugin with all of the original code from both packages basically just dumped at the end with just a few things changed here and there. When you open up a new file, simply type in :WManager. This will start up the file explorer.

[Jun 01, 2005] perl-support.vim : Perl-IDE

Write and run Perl-scripts using menus and hotkeys. (2.6) + blocks: opening brace no longer on a new line (adjustable for backward compatibility). + Vim (without GUI): new key mappings: all entries in the run menu do have mappings now. + Vim (without GUI): perldoc can be read with hotkeys \h and \rp . + Vim (without GUI): perldoc displays docs using plain text converter.+ output into buffer: cursor goes to top of file. + trailing ^M in perldoc window... - Fritz Mehner

[Mar 1, 2005] Vim Color Schemes

Featuring 161 themes:


Recommended Links

Softpanorama Top Visited

Softpanorama Recommended



Some comparisons

Usenet and mail lists

Please read all of the VIM FAQ before asking questions. Thanks!

Usenet Newsgroup with a lot of vim users: comp.editors

Yahoo! Groups vim


Advanced VI


see also The VI Pages - All About VI and its clones

Reference cards:

  1. How do I move the cursor in the file?

  2. How do I insert text?

Once you entered input mode, the way to return to command mode is by hitting the Escape key: ESC or CONTROL-[.

  1. How do I delete something?

  2. How to undo and repeat commands?

Sun bloggers

The Clingan Zone

Random Findings

the vi reference mug


FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available in our efforts to advance understanding of environmental, political, human rights, economic, democracy, scientific, and social justice issues, etc. We believe this constitutes a 'fair use' of any such copyrighted material as provided for in section 107 of the US Copyright Law. In accordance with Title 17 U.S.C. Section 107, the material on this site is distributed without profit exclusivly for research and educational purposes.   If you wish to use copyrighted material from this site for purposes of your own that go beyond 'fair use', you must obtain permission from the copyright owner. 

ABUSE: IPs or network segments from which we detect a stream of probes might be blocked for no less then 90 days. Multiple types of probes increase this period.  


Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy


War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes


Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law


Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least

Copyright © 1996-2015 by Dr. Nikolai Bezroukov. was created as a service to the UN Sustainable Development Networking Programme (SDNP) in the author free time. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License.

The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to make a contribution, supporting development of this site and speed up access. In case is down currently there are two functional mirrors: (the fastest) and


The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the author present and former employers, SDNP or any other organization the author may be associated with. We do not warrant the correctness of the information provided or its fitness for any purpose.

Last modified: February 19, 2014