[email protected] ©1995-2000

Last update: Mon Sep 11 19:00:00 MET DST 2000

VIM - Editing Intro

This text will hopefully get started editing with VIM. Please note that some things are special to VIM, ie you cannot use them with standard VI.

This text still needs a good structure. As I am busy with other stuff, too, you will have to send me email to encourage further work on it. :-)

TODO: link to VI FAQ



Terminology

Well, before every good text there need be some definitions. They make it easier for you to understand. Please take the time to read this - I am sure you will benefit from it!
line
A sequence of characters. Start: First character after an EOL character (or first character of buffer). End: Next EOL character. The EOL is included.
running text
A sequence of consecutive characters.
block
A sequence of (full) lines.
paragraph
see block
Hmm, this needs a lot more work...
Q: How do I quit?
A: Type ":q".
If this gets inserted then press ESC and type ":q" again.
Q: How do I insert text?
A: Type an 'i' to start insert text.
All characters you enter will be inserted -
except ESC which ends the insertion of characters.
Q: How do I start a new line while typing?
A: Type in the character 13 aka as control-M.
It is usually entered with the key labelled "return".
Q: How do you start a new line?
A: Type 'o' to "open" a new line below the current one.
   Type 'O' to "Open" a new line above the current one.
Q: How do you move the cursor?
A: The characters 'hjklwbWB0${}HML' all move the cursor:
   h	left	moves cursor onto the character to the left
   l	right	moves cursor onto the character to the right
   j	down	moves cursor onto the next line below
   k	down	moves cursor onto the next line above
   w	word	move cursor onto start of next word
   b	back	move cursor back to start of current or previous word
   0	zero	move cursor onto column zero ie start of current line
   $	end	move cursor onto the last column ie end of current line
   {		move current to start of current/previous paragraph
   }		move current to end   of current/next     paragraph
   H	high	move cursor onto highest line on window ie top line
   M	middle	move cursor onto the middle line of window
   L	last	move cursor onto last line of window
   NG	goto	move cursor onto line number N  (you must type N before G)
Q: How do I delete the current line?
A: Type "dd".
Q: How do I delete unto the end of the line?
A: Type 'D'.
Q: How do I delete unto the beginning of the line?
A: Type 'd0'.  ("dee zero")
Q: How do I make a copy the current line?
A: Type "yy".
Q: How do I insert what I have copied?
A: Type 'p' to "put" the text after  the current character/line.
   Type 'P' to "Put" the text before the current character/line.
   If the last thing you copied was a line of a block of lines
   then it will be put between lines.

Sample Abbreviations

Abbreviations are quite simple word to word translations. Very handy when you type the same things over and over again. It is useful for long words like this: "Donaudampfschiffahrtsgesellschaftkapitaenwitwengesetzzusatzparagraph" This actually is a proper German word. Don't ask! The abbreviation for this word might be "DON" and the definition in the vimrc would look like this:
ab DON Donaudampfschiffahrtsgesellschaftkapitaenwitwengesetzzusatzparagraph

I also use abbreviations for Email addresses, important file name such as setup files, and some URLS of my web pages.

Examples:

ab _vimrc    $HOME/.vimrc
ab _mymail   [email protected]
ab _homepage http://www.math.fu-berlin.de/~guckes/
NOTE: It does not matter how many spaces there are between the abbreviation and the expanded word. This allows for some nice formatting. Abbreviations can be a lot more than mere word substitutons, though. Actually anything you type can used. [TODO: HTML example]

Sample Mappings

Mappings make the use of VIM more interesting yet. Complex commands be made with just a few keystrokes.

Caveat: Mapping must be "prefix free", ie no mapping must be the prefix of any other mapping. Example: "map ,abc foo" and "map ,abcd bar" will give you the error message "Ambigous mapping".

" 950101 ,v = vimrc editing (edit this file)
  map    ,v :e $HOME/.vimrc
" 950101 ,u = "update" by reading this file
  map    ,u :source $HOME/.vimrc
" 950330 ,dp = dequote current paragraph
  map    ,dp {jma}kmb:'a,'bs/^> *//
" 950330 ,qp = quote current paragraph
  map    ,qp {jma}kmb:'a,'bs/^/> /

Removing empty lines

Q: How do you remove all empty lines?
A:
:g/^$/d
Q: How do you remove all lines with whitespace (spaces or tabs) in them?
A:
:g/^\s\+$/d
Q: How do you "squeeze" a range of empty lines to a single empty line?
A1:
:v/./.,/./-1join
to compact 2 or more blank lines into just one. [Rick Hellicar ([email protected])]
A2:	map  _b  GoZ^[:g/^[ ^I]*$/,/[^ ^I]/-j^MGdd
Note that this mapping inserts an extra line at the end of the buffer and removes it after the global command is done. This trick makes it possible that the global command works on the last part of the buffer, too. Robert Webb ([email protected]) [960326]

Mapping the TAB key

Q: How do you map the tab key? [960311]
A:      :map ^V^V^V^I right-hand-side

Mapping the ESC key

[960311] On some keyboards the escape key is not placed place very well. It's either part of the numeric block or it can be a small button (as with some Macintosh keyboards). But do not despair - make your own escape key! You can map one of the commands keys you do not need to ESC. Example: map CTRL-o to ESC:
	:map  
That's ":map CTRL-vCTRL-o CTRL-vCTRL-ESC".

Jumping back to marked line *and* position

Q: How do I get back to the exact position within a line I have marked with 'a'?
A: Use "`a" (that's a backtick!).

Viewing the commands you type

Q: How I see what I type?
A: Use ":set showcmd".

Changing line feeds from DOS to UNIX

Last update: 990104 (I should redo this, but - no time) Situation: You copied a file with DOS end-of-lines (characters 13 followed by 10) to a UNIX filesystem where the linefeed is just the character 10.

Q:  How to convert DOS line-ends (13,10) to Unix line-ends (10)?
NOTE:  Whenever this question arises, people give *wrong* answers.
The error usually lies in the assumption that you simply have to
"do away with *all* ^M" - but not every ^M is followed by a ^J,
ie a ^M can be part of a line.  Removing all ^M therefore is *wrong*.
A1: Using the power of Vim: Assume that the file is in the current buffer.
	within vim-5:
		:set fileformat=unix
		:w
	within vim-3 and vim-4:
		:set textmode
		:w
    You can, of course, use an external command as a filter, too:
	Use "tr" ("translate") as filter:
	:%!tr '\015' '\012'
	Drawback:  "tr" does not exist on all platforms.
	Use perl as filter:
	:%!perl -pe ";"
	Advantage: Perl exists on almost every platform and is a great tool.
	Drawback:  Perl isn't easy to install and overkill for this purpose.
	Note: An empty perl script should suffice as Perl automatically writes
	files with the correct eol character for the system it's being run on.
	This should work, too:
	perl -pe 's/\15\12/\12/' file
A2:  Using "that other editor (Emacs)":
	M-x shell-strip-ctrl-m RET
	(Not possible with emacs 19.31.1 in slackware 3.1, I hear.)
	Advantage: Some versions of Emacs automatically convert on startup.
	Drawback:  Emacs is BIG.  Mind-boggingly big.
	;;;; for you emacs setup file ($HOME/.emacs):
	;;; Note: You can insert ^M literally (by typing ^Q ^M) -
	;;; but you can also write it as "\C-m", "\r", or "\^M".
	(defun todos ()
	  (interactive "*")
	  (replace-regexp "$" "\r"))
	(defun tounix ()
	  (interactive "*")
	  (replace-regexp "\r$" ""))
	However, these functions can be slow.  So Erik Naggum
	has implemented some other functions for Emacs:
	convert-lineends.em
A3:  Using the editor "joe":
	^T Z
	This command hides the EOL.  *No* changes, though.
	Thanks to Marc Lehmann [email protected] for telling me.
A4:  Using the Unix command "col":
	col -b
	(not tested)
A5:  Using "dos2unix":
	dos2unix < infile > outfile
A6:  Using "awk":
	awk 'BEGIN{ORS="\r\n"};/.*/' file1
General Note:
There are many conversion tools just for this purpose.
Have a look at the various archives (DOS: Garbo, Simtel).
Some transfer programs (most notably "ftp") also convert
line endings automatically.  But a lot of these are buggy.
Summary:
Good editors (and programs that include editing facilities) are *independant*
of the underlying OS by supporting conversion of line-ends for all systems as
the user prefers, ie no automatic conversion unless specified.
Some noted:
Borland's Turbo C++ editor turns UNIX text into DOS text.
Some wrong solutions:

vi and clones:
	:%s/^M//g
	Problem:  *All* occurrences of ^M are removed.
	sed -e s/\015/""/g $1 &gt; $1.new
	Problem:  *All* occurrences of ^M are removed.
	sed 's/$/\r&/g'
	Problem:  sed uses regexpr(3) which does not know about "\r".


VIM - Tranposing characters and lines

A frequent typing error is tranposing two characters, ie you type them in the wrong order. Example: You type "in" as "ni". So what is the easiest method of changing this? Some editors have a "transpose command" usually bound to "control-t". However, this is no standard. And "vim" does not have it. However, it is as easy as deleting the first charcter and placing it after the second. You can do this by placing the cursor on the first character and then use the command sequence "xp".
Example:
  "ni"
  Put the cursor on the "n".
  Use "x" to delete the "n".
  Note:  The cursor will be placed on the next charcter, ie "i".
  Use "p" to "put" the deleted text (the "n") after the current position ("i").
  Result:
  "in"
You can also start on the second character and use "Xp". Command "X" deletes the character *before* the current character.
Tranposition of two lines works in the same way, ie delete one line and put it after/before the adjoining one. The command sequences here are "ddp" and "ddP". [950306]

VIM - builtin formatting

Q: How do you format the current paragraph?
A: With Vim-4 type "Qp".
A: With Vim-5+ type "gqip".

Substitutions - Search&Replace;

Q: How do you substitute from line marked with x to a line marked with y ?
A: :'x,'ys/this/that/

Reading in data

Q: How do I read in a file to the current buffer?
A: Use ":r file".  The contents of "file" will be appended *after*
   the current line.
Q: How do I append a signature to my text?
A: Jump to the end of the text with "G" and then read in the signature file.
Example:  ":r ~/.signature"
Q: How do I read in the output of a command?
A: Use ":r!command".
Example: ":r!date"

Abbreviations

Q: Why cant I abbraviate "'xy"? A: The abbreviation consists of a non-id character followed by two id characters, which does not satisfy either category of a "full-id". However, "_ps" and "'p" will work.

Special VIM stuff

Highlight mode jumping

Q: Are there commands to jump to the beginning/end of the highlighted text?
A: Yes, command 'o' will jump to the beginning/end of the highlighted text.

Completion of negated settings

Q: Why does completion of ":set n" not show negated settings, eg "noautoindent"? Completion of ":set no" seems to work.
A: The thing is that the "no" is not actually part of the option's name, the name comes after that. So after "no" vim knows to complete any boolean setting name (starts the completion just after the "no", which is not part of the name). After "n", vim will complete all setting names starting with "n". It would be a bumber if you wanted to complete "number", but had to wade through all the boolean option names with "no" prepended too.
Answer by Robert Webb [email protected], author of the completion code.

Formatting text

vim4 allows to format the current paragraph with "Qp". The "Q" means "format" and the following "p" will let the formatting operate on the current paragraph. The really good thing is that it preserves "quoting", ie indentation with "quote characters".

[TODO: add example of quoted text before and after formatting]

However, the builtin formatting command does not suit everybody. There are a few scripts about which you can use to pipe your text through. Here are two scripts - one in PERL and one in AWK:

  • mfmt.pl
  • fmt.awk

    Basic knowledge about PERL and AWK required. Caveat: scripts are not tested yet! use at own risk! TODO: test the scripts


    Digraphs

    Q:  Is there a command to remove any or all digraphs?
    A:  No.  There is a table that is defined at compile time.
        You can only add new ones.
        Adding a command to remove digraphs is on the todo list.
    


    UUencoding text

    Sending text like a vimrc will sometimes lose special characters. Therefore uuencoding them is a good idea.
    Q: How do I encode text with uuencode?
    A: !uuencode filename
    

    Saving - Writing

    Q: How do you specify the current filename?
    A: Use "%".
    Examples:
    	:w %
    	:w %.bak
    	:w ../%.copy
    Q: How do you specify the current filename without the extension?
    A: Use "%<".
    Examples:
    	:w %<
    

    Executing a line as a command from the shell

    Ever wanted to tell people which command to execute? Testing it yourself requires you to type in the command again. But with vim's feature of stuffing the contents of a buffer onto the command line this is easier than ever!
    " Yank the current line into buffer y and execute it
    map - "yyy:@y^M
    "	Use buffer
    y	buffer y
    yy	yank current line
    :	switch to command line
    @y^M	put contents of buffer y onto command line
    

    Command line editing

    Pasting yank buffer into command line
    Fact:
    You can record keystrokes to a yank buffer and thus you can put it into the
    edit buffer.
    Question:
    How do you paste a yank buffer into the command line?
    Answer:
    Assume that there is something in buffer 'y'.
    Enter ":@y" then hit return.
    

    Vim's smartindent option is nice. But there's one thing, I dislike a lot:
    Whenever you start a line with "#", Vim ignores the current indent and
    places the # at the begin of line. This is o.k. when editing C-code,
    but if you're writing shell or awk scripts, # introduces a comment...
    If I want to write something like
      if [ $a = "x" ]; then
        # comment about what's done here
    I have to indent the # line manually. :-(
    I don't use vim, but I see where that could be a problem.  Even in C/C++-code
    I don't start lines with # at the first column.  The product I work on
    (Preditor/2) uses one codebase to support multiple platforms (OS/2, Windows
    and Win95/NT).  It uses a multi-platform class library and *lots* of #ifs to
    do this, many of which are nested.  If all of th #ifs start in the 1st column,
    you easily get hopelessly lost and confused.  Therefore I always indent the
    #ifs just like the rest of th code so it can be read.
    Yes maybe there should be different types of smartindenting?  For the moment
    you can get around this by putting this in your .vimrc or .exrc file:
        inoremap # X^H#
    where ^H is typed as .
    Strange, most C compilers won't allow the # to be anywhere other than in the
    first column.  I think the ANSI standard requires it to be in the first
    column.  You can of course have spaces/tabs after the '#' and before the
    "if" or whatever.  -Rob.
    

    In Vim 3.0, * (in the command mode) searches forward for the next occurrence
    of the *word* that is under the cursor.  And # searches backward.
    If you want to search the word which can be part of another word, you
    can try the following map
            map \s wb"zyeo/^["zpbb"zy$u@z^M
            where ^M is Ctrl-V Ctrl-M
    
    do one of the following you should be able to relocate the tmp directory:
            - set directory=/ in EXINIT
            - or, "set directory=/" in your .exrc file
            - or, in a vi session do ":set directory=/"
    where pathname is the location you want to put the temp file.
    

    I have problems using vi with characters which have an ascii value > 128.
    For example if I insert ue the editor echoes \334 in insert mode. After leaving
    the insert mode everything is fine. Also fmt removes all characters with ascii
    > 128 from the text being formated.
    You have to define the environment-variable LC_CTYPE.
    If you are using csh then put in your .cshrc following line:
    setenv LC_CTYPE=iso_8859_1
    


    Yanking current word [950608, 950828]
    (y) - yank
    Q: How do you put the "current word" into the yank buffer?
    A: Use "wbye".
    "ye" will yank to the end of the current word. But we need to put the cursor onto the beginning first. If the cursor is on the beginning of the word then "b" will go to the beginning of the previous word. So we use "w" to go to the next word first. Result: "wbye"

    Editing Usenet Posts

    Whenever I post to a newsgroup giving info about my pages I also include my email address or the url of my pages. Those addresses are quite long words, so I let VIM do the work for me by defining abbreviations:
    " my addresses - email, home page, and vim pages
    "
    ab YMAIL [email protected]
    ab HPM   http://www.math.fu-berlin.de/~guckes/
    ab HPV   http://www.math.fu-berlin.de/~guckes/vim/
    
    Abbreviations given with "ab" are also expanded on the command line. Thus you can define abbreviations for file names and use these in commands. I use this for adding the appropriate signature to posts:
    " abbreviations - file names
    "
    ab SIGVIM $HOME/public_html/sig/sig.vim
    
    Now I can read in my signature for posts about vim with "G:r SIGVIM". Easy!

    But I also have a more general method to read in a signature. I have put all my signatures into a seperate directory and I use ",s" to set everything for reading in a signature at the current line:

    " 950101 ,s = "sign" - read in signature file (requires manual completion)
    map	,s :r $HOME/public_html/sig/sig.
    
    Please note that there is no return at the end as I want to complete the name of the file first. And it gives me the possibility to abort the command in case I have accidentally typed the command.
    [960622]

    Links

    VIM FAQ
    https://www.vim8.org/faq/
    Author: Sven Guckes [email protected]


    http://www.math.fu-berlin.de/~guckes/vim/howto/edit.html
    https://www.vim8.org/howto/edit.html (mirror)
    Created:     Mon Apr  1 00:00:00 MET 1996
    
    Send feedback on this page to
    Sven Guckes [email protected]