Notes on the Vim editor

Nothing too important in here... But, Vim is a text processor and not some wimpy (mere) text editor. The power doesn't like in the difficulty of negotiating a modeful editor, but in learning to use the modes and commands powerfully. This set of notes won't teach that; go elsewhere for a tutorial on Vi editing. I just put nice tricks in here that I don't want to forget if I don't use them for a while (and because I'm getting old).

vi/Vim cheat sheet

Vi Cheat


How to search for one word or another

The thing to remember in vi/Vim is that most of the regular-expression special characters must be escaped in the editor. It's a bit chaotic. Here's how to look for either "dog" or "cat":

  1. Get the search-forward command line by pressing / or search-backward by pressing ?.
  2. Type this:
    \(dog\|cat\)
    
    (In regular-express syntax this is really (dog|cat).)
  3. Press Enter.
  4. The editor will stop on the next occurrence of "dog" or "cat" at which point you can modify (or do anything else you want).
  5. Once finished modifying (or whatever), press N to go to the next occurrence.
  6. Extra credit
  7. If you wish to limit the results to words only (rather than strings of the characters "dog" or "cat"), add angle brackets to ensure "tokens":
    \<\(dog\|cat\)\>
    

How to wrap/unwrap a paragraph

This, executed when the cursor is at any point in the paragraph, will rewrap the paragraph. A pragraph is defined as everything and anything between (absolutely) blank lines.

:gqip

This does the opposite: it makes of a paragraph (the same definition as above applies) a single line (that may appear wrapped in your editor, but that's a different problem).

:vipJ

The utility of the immediately previous note comes when a) you typically type in autowrap mode and b) you want to take what you just wrote and paste it into a word processor, Slack or software that will want to control line wrapping in its own way.


How to toggle wrapping

I must use this frequently. A developer, I maintain notes on what I do. Often, these note contain code blocks or other text that I need to remain unwrapped whereas I'm very happy to have the simple, running text of my notes wrap out of convenience in my editor.

In short, if I'm creating a table, typing code, etc., I turn off wrapping. When I have finished, I turn it back on.

:set formatoptions-=t
:set formatoptions+=t    # (to turn back on)

or...

:set fo-=t
:set fo+=t    # (to turn back on)

How to toggle on/off menu bar in gvim
:set guioptions-=m
:set guioptions+=m    # (to turn back on)

or...

:set go-=m
:set go+=m    # (to turn back on)

.vimrc and .viminfo issues

Performing :version will reveal where Vim thinks it's getting your .vimrc, probably off ${HOME}/.vimrc. If you're not getting some of your function key mappings, you might look at your keyboard to see if the function keys are toggled on. (Some keyboards allow them to be off, default to off, etc. This is something to think about each time you start your host from cold/off.)


Misbehavior in .viminfo

~/.viminfo records significant things that you do while using Vim. In essence, Vim learns as you do things by making note in this file.

A common reason anything you expect in .viminfo fails to appear, have any later effect, etc., is the common occurrence of this file not belonging to you because user root created it. You should fix this:

russ@tuonela:~$ ll .viminfo
-rw-------   1 root root  11159 Nov  6 15:43  .viminfo
russ@tuonela:~$ sudo chown russ:russ .viminfo
russ@tuonela:~$ ll .viminfo
-rw------- 1 russ russ 11064 Nov  7 08:48 .viminfo

gvim issues

To remove unused toolbar from gvim, add this to bottom of .vimrc:

" Removes the button bar from under the menu of gvim saving wasting what's
" typically unused functionality.
set guioptions-=T

How to search using grep and open vim with the results

Assuming the use of grep (fgrep, etc.) to find specific strings in files that may lead you to want to edit them, ...

    $ fgrep -l some-string filenames

...with the -l option, you get only the list of containing files. How to get them into Vim? use xargs:

  1. This loads the first file into Vim with the others stacked up (using :n to visit each new file):
    $ grep -il some-string filenames | xargs vim
    
  2. This opens every file in its own pane in one Vim window:
    $ grep -il some-string filenames | xargs vim -o
    

How to fix last search string...

You entered a search string and mistyped something? Start searching again (by pressing / or ?), then press the up arrow (↑) and edit the string.


The 7 habits of effective text editing...

Bram’s presentation slides


EasyAccent to the rescue...

This gizmo lets me type diacritics in vim.

How to set it up

Download from http://vim.sourceforge.net/scripts/script.php?script_id=451.

Where do I drop this script (EasyAccents.vim) in order for it to be in effect (/home/russ/? c:\Documents and Settings\russ\My Documents?) and how do I set g:EasyAccents_VowelFirst to zero?

Bring up vim; type...

	:echo &rtp

...and you’ll see a comma-delimited list of directories. Pick one, preferably not a system one (i.e.: not where vim stores its plugins), and create a subdirectory, /plugin. Put the EasyAccents script in there. You can read more about this using:

	:help 'rtp'

Now for the second question: again, while in vim do:

	:echo $HOME

You should place in the directory so displayed the .vimrc (_vimrc) file. Within it, have the following lines in effect...

	set nocp
	filetype plugin on
	let g:EasyAccents_VowelFirst = 0

How to use it

It’s easy to toggle on and off, just type:

	\eza

Merely type a vowel after any of the following:

	`    (grave)
	'    (acute)
	^    (circumflex)
	:    (dieresis/umlaut)

...or a comma (,) followed by c or C for ç or Ç; and b or B for ß.

For remaining diacritics like ñ and å, you must do this instead...

	let g:EasyAccents_VowelFirst = 1

...and type the vowel followed by the accent...

	n~
	a@
	etc.


Copy using mouse...

Use mouse to select a block and press y.


Find word under cursor...

Use # to find the word under the cursor going backward. * will find the next occurrence of the word under the cursor.


Accumulated tricks

Many for gvim, but most hold for vim.

  1. Turn off audible beeping: :set visualbell

  2. Sort a range of lines alphabetically (after clicking and dragging to define a range).
        :{range}sort [u]
    
    Use the u if you also wish to lose duplicate lines. What I do (in gvim) is click and drag to select the range, then (with the range still selected) I type :sort u, which looks like this:
        :'<,'>sort u
    

  3. Split window vertically: Ctrl-w v

  4. Split window horizontally: Ctrl-w s

  5. Click and drag for a visual selection; pressing : to begin search and replace will bring up '>,'< to which you add s/search/replace/g and it will act within that range rather than the whole file.

  6. To move between Java methods, use
    n]m to move to start of nth succeeding method
    n]M to move to end of nth succeeding method
    n[m to move to start of nth previous method
    n[M to move to end of nth previous method

  7. To set number of lines and width of window:
        :set lines=66 columns=120
    
  8. To turn off auto-wrapping of text when you're trying to edit really long lines without causing them to wrap again:
        :set formatoptions-=t
        :set formatoptions+=t    # (to turn back on)
    
  9. To keep wrapping text (visually), but avoid inserting line breaks, do this:
        :set textwidth=0 wrapmargin=0
    
  10. To append lines to a temporary register, use lower-case buffer name to overwrite, upper-case to append; do this:
    "ayy yanks first line and overwrites register
    "Ayy yanks another line and appends to register

  11. Sort lines alphabetically, only running under a real, nix-shell, do this:
    1. Select block of lines visually (click and drag or type Shift-V and press down arrow, etc.).
    2. Invoke sort from shell by typing :, at which point you'll see: :'<',>
    3. Type sort at the cursor.
    4. Press Enter and see the magic.

  12. gvim: Launch gvim/vim to open multiple files each in its own tab
    $ gvim -p file-1 file-2 file-3 etc.
    
    Already in the editor on multiple files (each with its own buffer)?
        :tab ball              # (tab buffer all)
    
  13. vim: Launch gvim/vim on files in subdirectories:
    1. launch vim or gvim,
    2. type : to reach the vim command line,
    3. type :args **/*.java (to edit Java code),
    4. press Enter.
  14. Search for a pattern, replace what's found with what's in that pattern and add a newline. Note that ^v here is entered using Ctrl-v; it's the wiggle that permits a control or other character to be entered next without distracting the reader of what you're typing. I typically use a slash (/) to delimit search from replace strings, but here I use a colon instead.
    %s:\([~]\):\1^v/r:g
      ▲▲ ▲  ▲ ▲▲ ▲ ▲ ▲▲
      ││ │  │ ││ │ │ ││
      ││ │  │ ││ │ │ │└── perform the search and replace globally
      ││ │  │ ││ │ │ └─── ending delimiter of replacement string
      ││ │  │ ││ │ └───── carriage return (but inserts a newline on Linux)
      ││ │  │ ││ └─────── (^v) accept the next character as a control character
      ││ │  │ │└───────── the 1st pattern matched (in this case, the ~)
      ││ │  │ └────────── ending delimiter of search string
      ││ │  └──────────── ending of pattern definition
      ││ └─────────────── regular expression bracketing reducing ~ to just ~
      │└───────────────── beginning of pattern definition
      └────────────────── beginning delimiter of search string
    
    The short of it is that the vi/vim expression above will reformat X12 segments to one segment per line which makes them easier to read.

Folding tricks

Think of folding as represented by the character   Z   because this character suggests something folded in three parts. The character z is a component of most of the folding commands.


gvim: Opening multiple files each in its own tab
$ gvim -p file-1 file-2 file-3 etc.

Already in the editor on multiple files (each with its own buffer)?

    :tab ball              # (tab buffer all)

gvim: GLib-GObject-WARNING **: cannot retrieve class for invalid

Normally, GLib-GObject-WARNING while running gtk applications in the command line, are normally ignored by developers and demonstrate a poorly written applications.

vim-gnome has this problem, but vim-gtk does not, so this is a quick fix for the problem:

$ sudo apt-get remove vim-gnome
$ sudo apt-get install vim-gtk3

Launch gvim/vim on files in subdirectories

To accomplish this:

  1. launch vim or gvim,
  2. type : to reach the vim command line,
  3. type :args **/*.java (to edit Java code),
  4. press Enter.

Carry on register content to other sessions in .viminfo

Register contents are saved in .viminfo, a companion file to .vimrc, whenever you have a) have contents in registers and b) exit your session cleanly. For example, I write a comment in a C file, poop.c. Then I delimit it for storing in register a whereupon, I exit my editing session (by issuing ZZ or :wq). In ~/.viminfo I see the following. (Note that I've artificially wrapped line 89 for display in this note; it's all on a single line in .viminfo.)

85 ""a	LINE	0
86   /* This is a test of the Emergency Broadcast System. This is only a test. The
87    * quick brown fox jumped over the lazy dog's back and got clean away.
88    */
89 |3,1,10,1,3,0,1541606178,"/* This is a test of the Emergency Broadcast System.
    This is only a test. The"," * quick brown fox jumped over the lazy dog's back
    and got clean away."," */"
90 ...

When I edit crap.c, and insert the contents of register a into my file, I see that content I copied and stored from poop.c, i.e.:

/* This is a test of the Emergency Broadcast System. This is only a test. The
 * quick brown fox jumped over the lazy dog's back and got clean away.
 */

How to open files in subdirectories
$ cd src
$ gvim                  (launch [g]Vim)
:argadd **/*.java       (Vim command)

Then, use Vim command :n to advance from file to file.


How to adopt files with a new extension into a filetype

Note: this discussion does not explain how to create a hitherto unhandled filetype for vim. Pay attention as you read to the example here.

Let's say that you have a new, special type of XML file whose extension is going to be .ixml and that you want vim to display its syntax just as if it were XML. To cause this to happen, do this:

  1. Create ~/.vim/ftdetect
    russ@tirion ~ $ mkdir -p .vim/ftdetect
  2. Create a new configuration file there for your new file extension:
    russ@tirion ~ $ gvim .vim/ftdetect/ixml.vim
  3. ...and add this content to the file. In bold are the crucial details that outline what you're trying to accomplish, to wit that any file ending with the extension .ixml should be treated as any usual XML file (ending with the extension .xml):
    autocmd BufNewFile,BufRead *.ixml set filetype=xml
    
  4. Exit vim (gvim) to restart.
  5. Edit your file(s) whose extension is the new one:
    russ@tirion ~ $ gvim some-file.ixml
    You should now find your files with the newly handled extension to exhibit syntax highlighting, etc. as any other XML file.

How to reveal bad characters

I saw some bad/junk characters that showed up from some HTML that I wrote, but I couldn't find them in vim. So, I googled for "how to display bad html character in vim" and stumbled upon this:

:set listchars=eol:$,tab:>-,trail:~,extends:>,precedes:<
:set list

Now, this is pretty obscure (and nasty to type), but it put dollar signs in for newlines and, as I already knew the ballpark of where my bad characters were, I found them isolated on lines that hadn't shown any representation of characters. They were displayed as spaces before the $, but as those lines were supposed to be blank, I knew to erase the character(s) on those lines because they shouldn't be there. The result was that on browsers that detected and dislayed crap, the crap was now gone.