What are the dark corners of Vim your mom never told you about?

UnixVimEditorVi

Unix Problem Overview


There are a plethora of questions where people talk about common tricks, notably "Vim+ctags tips and tricks".

However, I don't refer to commonly used shortcuts that someone new to Vim would find cool. I am talking about a seasoned Unix user (be they a developer, administrator, both, etc.), who thinks they know something 99% of us never heard or dreamed about. Something that not only makes their work easier, but also is COOL and hackish. After all, Vim resides in the most dark-corner-rich OS in the world, thus it should have intricacies that only a few privileged know about and want to share with us.

Unix Solutions


Solution 1 - Unix

Might not be one that 99% of Vim users don't know about, but it's something I use daily and that any Linux+Vim poweruser must know.

Basic command, yet extremely useful.

:w !sudo tee %

I often forget to sudo before editing a file I don't have write permissions on. When I come to save that file and get a permission error, I just issue that vim command in order to save the file without the need to save it to a temp file and then copy it back again.

You obviously have to be on a system with sudo installed and have sudo rights.

Solution 2 - Unix

Something I just discovered recently that I thought was very cool:

:earlier 15m

Reverts the document back to how it was 15 minutes ago. Can take various arguments for the amount of time you want to roll back, and is dependent on undolevels. Can be reversed with the opposite command :later

Solution 3 - Unix

:! [command] executes an external command while you're in Vim.

But add a dot after the colon, :.! [command], and it'll dump the output of the command into your current window. That's : . !

For example:

:.! ls

I use this a lot for things like adding the current date into a document I'm typing:

:.! date

Solution 4 - Unix

Not exactly obscure, but there are several "delete in" commands which are extremely useful, like..

  • diw to delete the current word
  • di( to delete within the current parens
  • di" to delete the text between the quotes

Others can be found on :help text-objects

Solution 5 - Unix

de Delete everything till the end of the word by pressing . at your heart's desire.

ci(xyz[Esc] -- This is a weird one. Here, the 'i' does not mean insert mode. Instead it means inside the parenthesis. So this sequence cuts the text inside parenthesis you're standing in and replaces it with "xyz". It also works inside square and figure brackets -- just do ci[ or ci{ correspondingly. Naturally, you can do di (if you just want to delete all text without typing anything. You can also do a instead of i if you want to delete the parentheses as well and not just text inside them.

ci" - cuts the text in current quotes

ciw - cuts the current word. This works just like the previous one except that ( is replaced with w.

C - cut the rest of the line and switch to insert mode.

ZZ -- save and close current file (WAY faster than Ctrl-F4 to close the current tab!)

ddp - move current line one row down

xp -- move current character one position to the right

U - uppercase, so viwU upercases the word

~ - switches case, so viw~ will reverse casing of entire word

Ctrl+u / Ctrl+d scroll the page half-a-screen up or down. This seems to be more useful than the usual full-screen paging as it makes it easier to see how the two screens relate. For those who still want to scroll entire screen at a time there's Ctrl+f for Forward and Ctrl+b for Backward. Ctrl+Y and Ctrl+E scroll down or up one line at a time.

Crazy but very useful command is zz -- it scrolls the screen to make this line appear in the middle. This is excellent for putting the piece of code you're working on in the center of your attention. Sibling commands -- zt and zb -- make this line the top or the bottom one on the sreen which is not quite as useful.

% finds and jumps to the matching parenthesis.

de -- delete from cursor to the end of the word (you can also do dE to delete until the next space)

bde -- delete the current word, from left to right delimiter

df[space] -- delete up until and including the next space

dt. -- delete until next dot

dd -- delete this entire line

ye (or yE) -- yanks text from here to the end of the word

ce - cuts through the end of the word

bye -- copies current word (makes me wonder what "hi" does!)

yy -- copies the current line

cc -- cuts the current line, you can also do S instead. There's also lower cap s which cuts current character and switches to insert mode.

viwy or viwc. Yank or change current word. Hit w multiple times to keep selecting each subsequent word, use b to move backwards

vi{ - select all text in figure brackets. va{ - select all text including {}s

vi(p - highlight everything inside the ()s and replace with the pasted text

b and e move the cursor word-by-word, similarly to how Ctrl+Arrows normally do. The definition of word is a little different though, as several consecutive delmiters are treated as one word. If you start at the middle of a word, pressing b will always get you to the beginning of the current word, and each consecutive b will jump to the beginning of the next word. Similarly, and easy to remember, e gets the cursor to the end of the current, and each subsequent, word.

similar to b/e, capital B and E move the cursor word-by-word using only whitespaces as delimiters.

capital D (take a deep breath) Deletes the rest of the line to the right of the cursor, same as Shift+End/Del in normal editors (notice 2 keypresses -- Shift+D -- instead of 3)

Solution 6 - Unix

One that I rarely find in most Vim tutorials, but it's INCREDIBLY useful (at least to me), is the

g; and g,

to move (forward, backward) through the changelist.

Let me show how I use it. Sometimes I need to copy and paste a piece of code or string, say a hex color code in a CSS file, so I search, jump (not caring where the match is), copy it and then jump back (g;) to where I was editing the code to finally paste it. No need to create marks. Simpler.

Just my 2cents.

Solution 7 - Unix

:%!xxd

Make vim into a hex editor.

:%!xxd -r

Revert.

Warning: If you don't edit with binary (-b), you might damage the file. – Josh Lee in the comments.

Solution 8 - Unix

gv

Reselects last visual selection.

Solution 9 - Unix

Sometimes a setting in your .vimrc will get overridden by a plugin or autocommand. To debug this a useful trick is to use the :verbose command in conjunction with :set. For example, to figure out where cindent got set/unset:

:verbose set cindent?

This will output something like:

cindent
    Last set from /usr/share/vim/vim71/indent/c.vim

This also works with maps and highlights. (Thanks joeytwiddle for pointing this out.) For example:

:verbose nmap U
n  U             <C-R>
        Last set from ~/.vimrc

:verbose highlight Normal
Normal         xxx guifg=#dddddd guibg=#111111 font=Inconsolata Medium 14
        Last set from ~/src/vim-holodark/colors/holodark.vim

Solution 10 - Unix

Not sure if this counts as dark-corner-ish at all, but I've only just learnt it...

:g/match/y A

will yank (copy) all lines containing "match" into the "a/@a register. (The capitalization as A makes vim append yankings instead of replacing the previous register contents.) I used it a lot recently when making Internet Explorer stylesheets.

Solution 11 - Unix

:%TOhtml

Creates an html rendering of the current file.

Solution 12 - Unix

Want to look at your :command history?

q:

Then browse, edit and finally to execute the command.

Ever make similar changes to two files and switch back and forth between them? (Say, source and header files?)

:set hidden
:map <TAB> :e#<CR>

Then tab back and forth between those files.

Solution 13 - Unix

Vim will open a URL, for example

vim http://stackoverflow.com/

Nice when you need to pull up the source of a page for reference.

Solution 14 - Unix

Macros can call other macros, and can also call itself.

eg:

qq0dwj@qq@q

...will delete the first word from every line until the end of the file.

This is quite a simple example but it demonstrates a very powerful feature of vim

Solution 15 - Unix

^O and ^I

Go to older/newer position. When you are moving through the file (by searching, moving commands etc.) vim rember these "jumps", so you can repeat these jumps backward (^O - O for old) and forward (^I - just next to I on keyboard). I find it very useful when writing code and performing a lot of searches.

gi

Go to position where Insert mode was stopped last. I find myself often editing and then searching for something. To return to editing place press gi.

gf

put cursor on file name (e.g. include header file), press gf and the file is opened

gF

similar to gf but recognizes format "[file name]:[line number]". Pressing gF will open [file name] and set cursor to [line number].

^P and ^N

Auto complete text while editing (^P - previous match and ^N next match)

^X^L

While editing completes to the same line (useful for programming). You write code and then you recall that you have the same code somewhere in file. Just press ^X^L and the full line completed

^X^F

Complete file names. You write "/etc/pass" Hmm. You forgot the file name. Just press ^X^F and the filename is completed

^Z or :sh

Move temporary to the shell. If you need a quick bashing:

  • press ^Z (to put vi in background) to return to original shell and press fg to return to vim back
  • press :sh to go to sub shell and press ^D/exit to return to vi back

Solution 16 - Unix

Assuming you have Perl and/or Ruby support compiled in, :rubydo and :perldo will run a Ruby or Perl one-liner on every line in a range (defaults to entire buffer), with $_ bound to the text of the current line (minus the newline). Manipulating $_ will change the text of that line.

You can use this to do certain things that are easy to do in a scripting language but not so obvious using Vim builtins. For example to reverse the order of the words in a line:

:perldo $_ = join ' ', reverse split

To insert a random string of 8 characters (A-Z) at the end of every line:

:rubydo $_ += ' ' + (1..8).collect{('A'..'Z').to_a[rand 26]}.join

You are limited to acting on one line at a time and you can't add newlines.

Solution 17 - Unix

Typing == will correct the indentation of the current line based on the line above.

Actually, you can do one = sign followed by any movement command. ={movement}

For example, you can use the % movement which moves between matching braces. Position the cursor on the { in the following code:

if (thisA == that) {
//not indented
if (some == other) {
x = y;
}
}

And press =% to instantly get this:

if (thisA == that) {
    //not indented
    if (some == other) {
        x = y;
    }
}

Alternately, you could do =a{ within the code block, rather than positioning yourself right on the { character.

Solution 18 - Unix

" insert range ip's
"
"          ( O O )
" =======oOO=(_)==OOo======

:for i in range(1,255) | .put='10.0.0.'.i | endfor

Solution 19 - Unix

This is a nice trick to reopen the current file with a different encoding:

:e ++enc=cp1250 %:p

Useful when you have to work with legacy encodings. The supported encodings are listed in a table under encoding-values (see help encoding-values). Similar thing also works for ++ff, so that you can reopen file with Windows/Unix line ends if you get it wrong for the first time (see help ff).

Solution 20 - Unix

imap jj <esc>

Solution 21 - Unix

Let's see some pretty little IDE editor do column transposition.

:%s/\(.*\)^I\(.*\)/\2^I\1/

Explanation

\( and \) is how to remember stuff in regex-land. And \1, \2 etc is how to retrieve the remembered stuff.

>>> \(.*\)^I\(.*\)

Remember everything followed by ^I (tab) followed by everything.

>>> \2^I\1

Replace the above stuff with "2nd stuff you remembered" followed by "1st stuff you remembered" - essentially doing a transpose.

Solution 22 - Unix

Not exactly a dark secret, but I like to put the following mapping into my .vimrc file, so I can hit "-" (minus) anytime to open the file explorer to show files adjacent to the one I just edit. In the file explorer, I can hit another "-" to move up one directory, providing seamless browsing of a complex directory structures (like the ones used by the MVC frameworks nowadays):

map - :Explore<cr>

These may be also useful for somebody. I like to scroll the screen and advance the cursor at the same time:

map <c-j> j<c-e>
map <c-k> k<c-y>

Tab navigation - I love tabs and I need to move easily between them:

map <c-l> :tabnext<enter>
map <c-h> :tabprevious<enter>

Only on Mac OS X: Safari-like tab navigation:

map <S-D-Right> :tabnext<cr>
map <S-D-Left> :tabprevious<cr>

Solution 23 - Unix

Often, I like changing current directories while editing - so I have to specify paths less.

cd %:h

Solution 24 - Unix

I like to use 'sudo bash', and my sysadmin hates this. He locked down 'sudo' so it could only be used with a handful of commands (ls, chmod, chown, vi, etc), but I was able to use vim to get a root shell anyway:

bash$ sudo vi +'silent !bash' +q
Password: ******
root#

Solution 25 - Unix

I often use many windows when I work on a project and sometimes I need to resize them. Here's what I use:

map + <C-W>+
map - <C-W>-

These mappings allow to increase and decrease the size of the current window. It's quite simple but it's fast.

Solution 26 - Unix

:r! <command>

pastes the output of an external command into the buffer.

Do some math and get the result directly in the text:

:r! echo $((3 + 5 + 8))

Get the list of files to compile when writing a Makefile:

:r! ls *.c

Don't look up that fact you read on wikipedia, have it directly pasted into the document you are writing:

:r! lynx -dump http://en.wikipedia.org/wiki/Whatever

Solution 27 - Unix

Not an obscure feature, but very useful and time saving.

If you want to save a session of your open buffers, tabs, markers and other settings, you can issue the following:

mksession session.vim

You can open your session using:

vim -S session.vim

Solution 28 - Unix

Map F5 to quickly ROT13 your buffer:

map <F5> ggg?G``

You can use it as a boss key :).

Solution 29 - Unix

I use vim for just about any text editing I do, so I often times use copy and paste. The problem is that vim by default will often times distort imported text via paste. The way to stop this is to use

:set paste

before pasting in your data. This will keep it from messing up.

Note that you will have to issue :set nopaste to recover auto-indentation. Alternative ways of pasting pre-formatted text are the clipboard registers (* and +), and :r!cat (you will have to end the pasted fragment with ^D).

It is also sometimes helpful to turn on a high contrast color scheme. This can be done with

:color blue

I've noticed that it does not work on all the versions of vim I use but it does on most.

Solution 30 - Unix

I just found this one today via NSFAQ:

Comment blocks of code.

Enter Blockwise Visual mode by hitting CTRL-V.

Mark the block you wish to comment.

Hit I (capital I) and enter your comment string at the beginning of the line. (// for C++)

Hit ESC and all lines selected will have // prepended to the front of the line.

Solution 31 - Unix

Ctrl-n while in insert mode will auto complete whatever word you're typing based on all the words that are in open buffers. If there is more than one match it will give you a list of possible words that you can cycle through using ctrl-n and ctrl-p.

Solution 32 - Unix

Here's something not obvious. If you have a lot of custom plugins / extensions in your $HOME and you need to work from su / sudo / ... sometimes, then this might be useful.

In your ~/.bashrc:

export VIMINIT=":so $HOME/.vimrc"

In your ~/.vimrc:

if $HOME=='/root'
if $USER=='root'
if isdirectory('/home/your_typical_username')
let rtuser = 'your_typical_username'
elseif isdirectory('/home/your_other_username')
let rtuser = 'your_other_username'
endif
else
let rtuser = $USER
endif
let &runtimepath = substitute(&runtimepath, $HOME, '/home/'.rtuser, 'g')
endif

It will allow your local plugins to load - whatever way you use to change the user.

You might also like to take the *.swp files out of your current path and into ~/vimtmp (this goes into .vimrc):

if ! isdirectory(expand('/vimtmp'))
call mkdir(expand('/vimtmp'))
endif
if isdirectory(expand('/vimtmp'))
set directory=/vimtmp
else
set directory=.,/var/tmp,/tmp
endif

Also, some mappings I use to make editing easier - makes ctrl+s work like escape and ctrl+h/l switch the tabs:

inoremap <C-s> <ESC>
vnoremap <C-s> <ESC>
noremap <C-l> gt
noremap <C-h> gT

Solution 33 - Unix

Want an IDE?

:make will run the makefile in the current directory, parse the compiler output, you can then use :cn and :cp to step through the compiler errors opening each file and seeking to the line number in question.

:syntax on turns on vim's syntax highlighting.

Solution 34 - Unix

gg=G

Corrects indentation for entire file. I was missing my trusty <C-a><C-i> in Eclipse but just found out vim handles it nicely.

Solution 35 - Unix

Ability to run Vim on a client/server based modes.

For example, suppose you're working on a project with a lot of buffers, tabs and other info saved on a session file called session.vim.

You can open your session and create a server by issuing the following command:

vim --servername SAMPLESERVER -S session.vim

Note that you can open regular text files if you want to create a server and it doesn't have to be necessarily a session.

Now, suppose you're in another terminal and need to open another file. If you open it regularly by issuing:

vim new_file.txt

Your file would be opened in a separate Vim buffer, which is hard to do interactions with the files on your session. In order to open new_file.txt in a new tab on your server use this command:

vim --servername SAMPLESERVER --remote-tab-silent new_file.txt

If there's no server running, this file will be opened just like a regular file.

Since providing those flags every time you want to run them is very tedious, you can create a separate alias for creating client and server.

I placed the followings on my bashrc file:

alias vims='vim --servername SAMPLESERVER'
alias vimc='vim --servername SAMPLESERVER --remote-tab-silent'

You can find more information about this at: http://vimdoc.sourceforge.net/htmldoc/remote.html

Solution 36 - Unix

Variation of sudo write:

into .vimrc

cmap w!! w !sudo tee % >/dev/null

After reload vim you can do "sudo save" as

:w!!

Solution 37 - Unix

I often want to highlight a particular word/function name, but don't want to search to the next instance of it yet:

map m* *#

Solution 38 - Unix

HOWTO: Auto-complete Ctags when using Vim in Bash. For anyone else who uses Vim and Ctags, I've written a small auto-completer function for Bash. Add the following into your ~/.bash_completion file (create it if it does not exist):

Thanks go to stylishpants for his many fixes and improvements.

_vim_ctags() {
    local cur prev

    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    case "${prev}" in
        -t)
            # Avoid the complaint message when no tags file exists
            if [ ! -r ./tags ]
            then
                return
            fi

            # Escape slashes to avoid confusing awk
            cur=${cur////\\/}

            COMPREPLY=( $(compgen -W "`awk -vORS=" "  "/^${cur}/ { print \\$1 }" tags`" ) )
            ;;
        *)
            _filedir_xspec
            ;;
    esac
}

# Files matching this pattern are excluded
excludelist='*.@(o|O|so|SO|so.!(conf)|SO.!(CONF)|a|A|rpm|RPM|deb|DEB|gif|GIF|jp?(e)g|JP?(E)G|mp3|MP3|mp?(e)g|MP?(E)G|avi|AVI|asf|ASF|ogg|OGG|class|CLASS)'

complete -F _vim_ctags -f -X "${excludelist}" vi vim gvim rvim view rview rgvim rgview gview

Once you restart your Bash session (or create a new one) you can type:

Code:

~$ vim -t MyC<tab key>

and it will auto-complete the tag the same way it does for files and directories:

Code:

MyClass MyClassFactory
~$ vim -t MyC

I find it really useful when I'm jumping into a quick bug fix.

Solution 39 - Unix

% is also good when you want to diff files across two different copies of a project without wearing out the pinkies (from root of project1):

:vert diffs /project2/root/%

Solution 40 - Unix

I use Vim for everything. When I'm editing an e-mail message, I use:

gqap (or gwap)

extensively to easily and correctly reformat on a paragraph-by-paragraph basis, even with quote leadin characters. In order to achieve this functionality, I also add:

-c 'set fo=tcrq' -c 'set tw=76'

to the command to invoke the editor externally. One noteworthy addition would be to add 'a' to the fo (formatoptions) parameter. This will automatically reformat the paragraph as you type and navigate the content, but may interfere or cause problems with errant or odd formatting contained in the message.

Solution 41 - Unix

> :setlocal autoread

Auto reloads the current buffer..especially useful while viewing log files and it almost serves the functionality of "tail" program in unix from within vim.

Checking for compile errors from within vim. set the makeprg variable depending on the language let's say for perl

> :setlocal makeprg = perl\ -c \ %

For PHP > set makeprg=php\ -l\ %
> set errorformat=%m\ in\ %f\ on\ line\ %l

Issuing ":make" runs the associated makeprg and displays the compilation errors/warnings in quickfix window and can easily navigate to the corresponding line numbers.

Solution 42 - Unix

Input a character from its hexadecimal value (insert mode):

<C-Q>x[type the hexadecimal byte]

Solution 43 - Unix

Put this in your .vimrc to have a command to pretty-print xml:

function FormatXml()
    %s:\(\S\)\(<[^/]\)\|\(>\)\(</\):\1\3\r\2\4:g
    set filetype=xml
    normal gg=G
endfunction

command FormatXml :call FormatXml()

Solution 44 - Unix

I was sure someone would have posted this already, but here goes.

Take any build system you please; make, mvn, ant, whatever. In the root of the project directory, create a file of the commands you use all the time, like this:

mvn install
mvn clean install
... and so forth

To do a build, put the cursor on the line and type !!sh. I.e. filter that line; write it to a shell and replace with the results.

The build log replaces the line, ready to scroll, search, whatever.

When you're done viewing the log, type u to undo and you're back to your file of commands.

Solution 45 - Unix

In normal mode

gf ................ open file under cursor in same window --> see :h path Ctrl-w f .......... open file under cursor in new window Ctrl-w q .......... close current window Ctrl-w 6 .......... open alternate file --> see :h # gi ................ init insert mode in last insertion position '0 ................ place the cursor where it was when the file was last edited

Solution 46 - Unix

Due to the latency and lack of colors (I love color schemes :) I don't like programming on remote machines in PuTTY. So I developed this trick to work around this problem. I use it on Windows.

You will need

  • 1x gVim
  • 1x rsync on remote and local machines
  • 1x SSH private key auth to the remote machine so you don't need to type the password
  • 1x Pageant
  • 1x PuTTY

Setting up remote machine

Configure rsync to make your working directory accessible. I use an SSH tunnel and only allow connections from the tunnel:

address = 127.0.0.1
hosts allow = 127.0.0.1
port = 40000
use chroot = false
[bledge_ce]
    path = /home/xplasil/divine/bledge_ce
    read only = false

Then start rsyncd: rsync --daemon --config=rsyncd.conf

Setting up local machine

Install rsync from Cygwin. Start Pageant and load your private key for the remote machine. If you're using SSH tunelling, start PuTTY to create the tunnel. Create a batch file push.bat in your working directory which will upload changed files to the remote machine using rsync:

rsync --blocking-io *.cc *.h SConstruct rsync://localhost:40001/bledge_ce

SConstruct is a build file for scons. Modify the list of files to suit your needs. Replace localhost with the name of remote machine if you don't use SSH tunelling.

Configuring Vim That is now easy. We will use the quickfix feature (:make and error list), but the compilation will run on the remote machine. So we need to set makeprg:

set makeprg=push\ &&\ plink\ -batch\ [email protected]\ \"cd\ /home/xplasil/divine/bledge_ce\ &&\ scons\ -j\ 2\"

This will first start the push.bat task to upload the files and then execute the commands on remote machine using SSH (Plink from the PuTTY suite). The command first changes directory to the working dir and then starts build (I use scons).

The results of build will show conviniently in your local gVim errors list.

Solution 47 - Unix

A few useful ones:

:set nu # displays lines
:44     # go to line 44
'.      # go to last modification line

My favourite: Ctrl + n WORD COMPLETION!

Solution 48 - Unix

set colorcolumn=+1 or set cc=+1 for vim 7.3

Solution 49 - Unix

:sp %:h - directory listing / file-chooser using the current file's directory

(belongs as a comment under rampion's cd tip, but I don't have commenting-rights yet)

Solution 50 - Unix

Just before copying and pasting to stackoverflow:

:retab 1
:% s/^I/ /g
:% s/^/    /

Now copy and paste code.

As requested in the comments:

retab 1. This sets the tab size to one. But it also goes through the code and adds extra tabs and spaces so that the formatting does not move any of the actual text (ie the text looks the same after ratab).

% s/^I/ /g: Note the ^I is tthe result of hitting tab. This searches for all tabs and replaces them with a single space. Since we just did a retab this should not cause the formatting to change but since putting tabs into a website is hit and miss it is good to remove them.

% s/^/    /: Replace the beginning of the line with four spaces. Since you cant actually replace the beginning of the line with anything it inserts four spaces at the beging of the line (this is needed by SO formatting to make the code stand out).

Solution 51 - Unix

When working on a project where the build process is slow I always build in the background and pipe the output to a file called errors.err (something like make debug 2>&1 | tee errors.err). This makes it possible for me to continue editing or reviewing the source code during the build process. When it is ready (using pynotify on GTK to inform me that it is complete) I can look at the result in vim using quickfix. Start by issuing :cf[ile] which reads the error file and jumps to the first error. I personally like to use cwindow to get the build result in a separate window.

Solution 52 - Unix

I love :ls command.

Solution 53 - Unix

For making vim a little more like an IDE editor:

  • set nu - for line numbers in the left margin.
  • set cul - highlights the line containing the cursor.

Solution 54 - Unix

Neither of the following is really diehard, but I find it extremely useful.

Trivial bindings, but I just can't live without. It enables hjkl-style movement in insert mode (using the ctrl key). In normal mode: ctrl-k/j scrolls half a screen up/down and ctrl-l/h goes to the next/previous buffer. The µ and ù mappings are especially for an AZERTY-keyboard and go to the next/previous make error.

imap <c-j> <Down>
imap <c-k> <Up>
imap <c-h> <Left>
imap <c-l> <Right>
nmap <c-j> <c-d>
nmap <c-k> <c-u>
nmap <c-h> <c-left>
nmap <c-l> <c-right>

nmap ù :cp<RETURN>
nmap µ :cn<RETURN>

A small function I wrote to highlight functions, globals, macro's, structs and typedefs. (Might be slow on very large files). Each type gets different highlighting (see ":help group-name" to get an idea of your current colortheme's settings) Usage: save the file with ww (default "\ww"). You need ctags for this.

nmap <Leader>ww :call SaveCtagsHighlight()<CR>

"Based on: http://stackoverflow.com/questions/736701/class-function-names-highlighting-in-vim
function SaveCtagsHighlight()
	write

	let extension = expand("%:e")
	if extension!="c" && extension!="cpp" && extension!="h" && extension!="hpp"
		return
	endif

	silent !ctags --fields=+KS *
	redraw!

	let list = taglist('.*')
	for item in list
		let kind = item.kind

		if     kind == 'member'
			let kw = 'Identifier'
		elseif kind == 'function'
			let kw = 'Function'
		elseif kind == 'macro'
			let kw = 'Macro'
		elseif kind == 'struct'
			let kw = 'Structure'
		elseif kind == 'typedef'
			let kw = 'Typedef'
		else
			continue
		endif

		let name = item.name
		if name != 'operator=' && name != 'operator ='
			exec 'syntax keyword '.kw.' '.name
		endif
	endfor
	echo expand("%")." written, tags updated"
endfunction

I have the habit of writing lots of code and functions and I don't like to write prototypes for them. So I made some function to generate a list of prototypes within a C-style sourcefile. It comes in two flavors: one that removes the formal parameter's name and one that preserves it. I just refresh the entire list every time I need to update the prototypes. It avoids having out of sync prototypes and function definitions. Also needs ctags.

"Usage: in normal mode, where you want the prototypes to be pasted:
":call GenerateProptotypes()
function GeneratePrototypes()
	execute "silent !ctags --fields=+KS ".expand("%")
	redraw!
	let list = taglist('.*')
	let line = line(".")
	for item in list
		if item.kind == "function"  &&  item.name != "main"
			let name = item.name
			let retType = item.cmd
			let retType = substitute( retType, '^/\^\s*','','' )
			let retType = substitute( retType, '\s*'.name.'.*', '', '' ) 

			if has_key( item, 'signature' )
				let sig = item.signature
				let sig = substitute( sig, '\s*\w\+\s*,',        ',', 	'g')
				let sig = substitute( sig, '\s*\w\+\(\s)\)', '\1', '' )
			else
				let sig = '()'
			endif
			let proto = retType . "\t" . name . sig . ';'
			call append( line, proto )
			let line = line + 1
		endif
	endfor
endfunction


function GeneratePrototypesFullSignature()
	"execute "silent !ctags --fields=+KS ".expand("%")
	let dir = expand("%:p:h");
	execute "silent !ctags --fields=+KSi --extra=+q".dir."/* "
	redraw!
	let list = taglist('.*')
	let line = line(".")
	for item in list
		if item.kind == "function"  &&  item.name != "main"
			let name = item.name
			let retType = item.cmd
			let retType = substitute( retType, '^/\^\s*','','' )
			let retType = substitute( retType, '\s*'.name.'.*', '', '' ) 

			if has_key( item, 'signature' )
				let sig = item.signature
			else
				let sig = '(void)'
			endif
			let proto = retType . "\t" . name . sig . ';'
			call append( line, proto )
			let line = line + 1
		endif
	endfor
endfunction

Solution 55 - Unix

Reuse

Motions to mix with other commands, more here.

tx
fx
Fx

Use your favorite tools in Vim.

:r !python anything you want or awk or Y something

Repeat in visual mode, powerful when combined with tips above.

;

Solution 56 - Unix

map macros

I rather often find it useful to on-the-fly define some key mapping just like one would define a macro. The twist here is, that the mapping is recursive and is executed until it fails.

Example:

enum ProcStats
{
        ps_pid,
        ps_comm,
        ps_state,
        ps_ppid,
        ps_pgrp,
:map X /ps_<CR>3xixy<Esc>X

Gives:

enum ProcStats
{
        xypid,
        xycomm,
        xystate,
        xyppid,
        xypgrp,

Just an silly example :).

I am completely aware of all the downsides - it just so happens that I found it rather useful in some occasions. Also it can be interesting to watch it at work ;).

Solution 57 - Unix

In insert mode, ctrl+x, ctrl+p will complete (with menu of possible completions if that's how you like it) the current long identifier that you are typing.

if (SomeCall(LONG_ID_ <-- type c-x c-p here
            [LONG_ID_I_CANT_POSSIBLY_REMEMBER]
             LONG_ID_BUT_I_NEW_IT_WASNT_THIS_ONE
             LONG_ID_GOSH_FORGOT_THIS
             LONG_ID_ETC
             ∶

Solution 58 - Unix

In Insert mode 
<C-A>   - Increments the number under cursor 
<C-X>   - Decrements the number under cursor

It will be very useful if we want to generate sequential numbers in vim
Lets say if we want to insert lines 1-10 with numbers from 1 to 10 [like "1" on 1st line,"2" on 2nd line..]
insert "0" on the first line and copy the line and past 9 times So that all lines will show "0".

Run the following Ex command

:g/^/exe "norm " . line(".") . "\<C-A>"

Solution 59 - Unix

Use the right mouse key to toggle insert mode in gVim with the following settings in ~/.gvimrc :

"
"------------------------------------------------------------------
" toggle insert mode <--> 'normal mode with the <RightMouse>-key
"------------------------------------------------------------------
nnoremap  <RightMouse> <Insert>
inoremap  <RightMouse> <ESC>
"

Solution 60 - Unix

Replace all

  :%s/oldtext/newtext/igc

Give a to replace all :)

Solution 61 - Unix

Try using perltidy for formatting by = normal-mode command

:set equalprg=perltidy

Solution 62 - Unix

I collected these over the years.

" Pasting in normal mode should append to the right of cursor
nmap <C-V>      a<C-V><ESC>
" Saving
imap <C-S>      <C-o>:up<CR>
nmap <C-S>      :up<CR>
" Insert mode control delete
imap <C-Backspace> <C-W>
imap <C-Delete> <C-O>dw
nmap    <Leader>o       o<ESC>k
nmap    <Leader>O       O<ESC>j
" tired of my typo
nmap :W     :w

Solution 63 - Unix

Create a function to execute the current buffer using it's shebang (assuming one is set) and call it with crtl-x.

map <C-X> :call CallInterpreter()<CR>

au BufEnter *
\ if match (getline(1) , '^\#!') == 0 |
\   execute("let b:interpreter = getline(1)[2:]") |
\ endif

fun! CallInterpreter()
    if exists("b:interpreter")
        exec("! ".b:interpreter." %")
    endif
endfun

Solution 64 - Unix

In order to copy a text from Vim to your clipboard for other application to use, select the text you want to copy in visual mode, and then press "+y. This way, you can easily paste your text to other applications.

This is particularly useful, if you have splitted the window vertically and you want to copy something from the right window. Using set mouse=r, won't help you with this situation, since it will select everything on the left window as well.

Note that your vim has to be compiled with xterm support.

Solution 65 - Unix

Some of my must-haves are:

cscope + ctags + vim, which can be found on the web.

Some abreviations for quickly starting new code files such as:

ab cpph #include <iostream><CR>#include <string><CR>#include <cstdlib><CR>#include <cassert><CR>#include <vector><CR>#include <
stdexcept><CR>using namespace std;<CR>int main(int argc, char *argv[]) {
ab perlh #!/usr/bin/perl<CR>use strict;<CR>use warnings;<CR>
ab chdr #include <stdio.h><CR>#include <sys/types.h><CR>#include <unistd.h><CR>#include <stdlib.h><CR>#include <sys/stat.h><CR>
#include <sys/wait.h><CR>#include <string.h><CR>int main(int argc, char *argv[]) {
ab xhtmlhdr <?xml version="1.0" encoding="UTF-8"?><CR><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.o
rg/TR/xhtml1/DTD/xhtml1-strict.dtd"><CR><html xmlns="http://www.w3.org/1999/xhtml"><CR>  <head><CR>  <title></title><CR><link h
ref="style.css" rel="STYLESHEET" type="text/css"><CR></head>

For example cpph will insert a basic skeleton of a main.cc file

There is also my mapping of the function keys:

map <F1> <Esc>:w<CR>:perl $e = `./error.pl`; my ($f,$l,@w) = split(":",$e); my $w=join(":",@w); $curwin->Cursor($l,0); VIM::Msg($w);<CR>
map <F2> :wincmd w<CR>
map <F3> :wincmd s<CR>
map <F4> :wincmd v<CR>
map <F5> :wincmd o<CR>
map <F6> :sball<CR>
map <F7> :wq<CR>
map <F8> :wincmd q<CR>
map <F9> :wincmd -<CR>
map <F10> :wincmd +<CR>
map <F11> :wincmd <<CR>
map <F12> :wincmd ><CR>

In this case my F1 is mapped to put the cursor over the next error that needs to be corrected for a source code migration.

map _ ebi"^[ea"^[

This map would make _ quote a string

Solution 66 - Unix

Mappings to make movements operate on the current screen line in wrap mode. I discovered this in a comment for a Vim tip some time ago, and it has proven quite handy.

function! ScreenMovement(movement)
  if &wrap
    return "g" . a:movement
  else
    return a:movement
  endif
endfunction
onoremap <silent> <expr> j ScreenMovement("j")
onoremap <silent> <expr> k ScreenMovement("k")
onoremap <silent> <expr> 0 ScreenMovement("0")
onoremap <silent> <expr> ^ ScreenMovement("^")
onoremap <silent> <expr> $ ScreenMovement("$")
nnoremap <silent> <expr> j ScreenMovement("j")
nnoremap <silent> <expr> k ScreenMovement("k")
nnoremap <silent> <expr> 0 ScreenMovement("0")
nnoremap <silent> <expr> ^ ScreenMovement("^")
nnoremap <silent> <expr> $ ScreenMovement("$")

Solution 67 - Unix

per this thread

To prefix a set of lines I use one of two different approaches:

One approach is the block select (mentioned by sth). In general, you can select a rectangular region with ctrl-V followed by cursor-movement. Once you've highlighted a rectangle, pressing shift-I will insert characters on the left side of the rectangle, or shift-A will append them on the right side of the rectangle. So you can use this technique to make a rectangle that includes the left-most column of the lines you want to prefix, hit shift-I, type the prefix, and then hit escape.

The other approach is to use a substitution (as mentioned by Brian Agnew). Brian's substitution will affect the entire file (the % in the command means "all lines"). To affect just a few lines the easiest approach is to hit shift-V (which enables visual-line mode) while on the first/last line, and then move to the last/first line. Then type:

:s/^/YOUR PREFIX/

The ^ is a regex (in this case, the beginning of the line). By typing this in visual line mode you'll see '<,'> inserted before the s automatically. This means the range of the substitution will be the visual selection.

Extra tip: if your prefix contains slashes, you can either escape them with backslash, or you can use a different punctuation character as the separator in the command. For example, to add C++ line comments, I usually write:

:s:^:// :

For adding a suffix the substitution approach is generally easier unless all of your lines are exactly the same length. Just use $ for the pattern instead of ^ and your string will be appended instead of pre-pended.

If you want to add a prefix and a suffix simultaneously, you can do something like this:

:s/.*/PREFIX & SUFFIX/

The .* matches the whole line. The & in the replacement puts the matched text (the whole line) back, but now it'll have your prefix and suffix added.

BTW: when commenting out code you'll probably want to uncomment it later. You can use visual-block (ctrl-V) to select the slashes and then hit d to delete them, or you can use a substitution (probably with a visual line selection, made with shift-V) to remove the leading slashes like this:

:s:// ::

Solution 68 - Unix

Mine is using macros instead of searches - combining a macro with visual mode is sometimes more efficient.

Solution 69 - Unix

My favourite recipe to switch back and forth between windows:

function! SwitchPrevWin()
    let l:winnr_index = winnr()
    if l:winnr_index > 1
       let l:winnr_index -= 1
    else
       "set winnr_index to max window open
        let l:winnr_index = winnr('$')
    endif
    exe l:winnr_index . "wincmd w" 
endfunction

nmap <M-z> :call SwitchPrevWin()
imap <M-z> <ESC>:call SwitchPrevWin()

nmap <C-z> :wincmd w
imap <C-z> <ESC>:wincmd w

Solution 70 - Unix

I'd like to arrange some of my own config files in after-directory. It's especially useful for ftplugin.

You can avoid to write a long list of augroup in your .vimrc file instead of separate files for each type.

But, obviously, .vim/ftplugin directory do the same thing as .vim/after/ftplugin, but I'd prefer to leave .vim directory to vim plugins.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSashaView Question on Stackoverflow
Solution 1 - UnixskinpView Answer on Stackoverflow
Solution 2 - UnixChad BirchView Answer on Stackoverflow
Solution 3 - UnixJeffrey KnightView Answer on Stackoverflow
Solution 4 - UnixdbrView Answer on Stackoverflow
Solution 5 - UnixultramanView Answer on Stackoverflow
Solution 6 - UnixXavier GuardiolaView Answer on Stackoverflow
Solution 7 - UnixBill LynchView Answer on Stackoverflow
Solution 8 - UnixAaronSView Answer on Stackoverflow
Solution 9 - UnixLaurence GonsalvesView Answer on Stackoverflow
Solution 10 - UnixsjhView Answer on Stackoverflow
Solution 11 - UnixN 1.1View Answer on Stackoverflow
Solution 12 - UnixMikeyBView Answer on Stackoverflow
Solution 13 - UnixCercerillaView Answer on Stackoverflow
Solution 14 - Unixspence91View Answer on Stackoverflow
Solution 15 - UnixdimbaView Answer on Stackoverflow
Solution 16 - UnixBrian CarperView Answer on Stackoverflow
Solution 17 - UnixKimball RobinsonView Answer on Stackoverflow
Solution 18 - UnixSergioAraujoView Answer on Stackoverflow
Solution 19 - UnixzoulView Answer on Stackoverflow
Solution 20 - UnixSir Rippov the MapleView Answer on Stackoverflow
Solution 21 - UnixchaosView Answer on Stackoverflow
Solution 22 - UnixKKovacsView Answer on Stackoverflow
Solution 23 - UnixrampionView Answer on Stackoverflow
Solution 24 - Unixtoo much phpView Answer on Stackoverflow
Solution 25 - UnixTaurus OlsonView Answer on Stackoverflow
Solution 26 - UnixRoberto BonvalletView Answer on Stackoverflow
Solution 27 - Unixmohi666View Answer on Stackoverflow
Solution 28 - UnixjqnoView Answer on Stackoverflow
Solution 29 - UnixIan HView Answer on Stackoverflow
Solution 30 - UnixGrant LimbergView Answer on Stackoverflow
Solution 31 - UnixNiki YoshiuchiView Answer on Stackoverflow
Solution 32 - UnixviraptorView Answer on Stackoverflow
Solution 33 - UnixcaskeyView Answer on Stackoverflow
Solution 34 - UnixdaltonbView Answer on Stackoverflow
Solution 35 - Unixmohi666View Answer on Stackoverflow
Solution 36 - Unixjm666View Answer on Stackoverflow
Solution 37 - UnixScotty AllenView Answer on Stackoverflow
Solution 38 - UnixmichaelView Answer on Stackoverflow
Solution 39 - UnixBenView Answer on Stackoverflow
Solution 40 - UnixGary ChambersView Answer on Stackoverflow
Solution 41 - UnixNaga KiranView Answer on Stackoverflow
Solution 42 - UnixLuper RouchView Answer on Stackoverflow
Solution 43 - UnixSir Rippov the MapleView Answer on Stackoverflow
Solution 44 - UnixBrad CoxView Answer on Stackoverflow
Solution 45 - UnixSergioAraujoView Answer on Stackoverflow
Solution 46 - UnixRoman PlášilView Answer on Stackoverflow
Solution 47 - UnixdfensView Answer on Stackoverflow
Solution 48 - UnixquabugView Answer on Stackoverflow
Solution 49 - UnixsearleaView Answer on Stackoverflow
Solution 50 - UnixMartin YorkView Answer on Stackoverflow
Solution 51 - UnixAnders HolmbergView Answer on Stackoverflow
Solution 52 - UnixPuzzleCrackerView Answer on Stackoverflow
Solution 53 - UnixmpeView Answer on Stackoverflow
Solution 54 - UnixRoaldFreView Answer on Stackoverflow
Solution 55 - UnixhhhView Answer on Stackoverflow
Solution 56 - UnixMarcus BorkenhagenView Answer on Stackoverflow
Solution 57 - UnixbobbogoView Answer on Stackoverflow
Solution 58 - UnixNaga KiranView Answer on Stackoverflow
Solution 59 - UnixFritz G. MehnerView Answer on Stackoverflow
Solution 60 - UnixAIBView Answer on Stackoverflow
Solution 61 - Unixc9sView Answer on Stackoverflow
Solution 62 - UnixYadaView Answer on Stackoverflow
Solution 63 - UnixJ.C. YamokoskiView Answer on Stackoverflow
Solution 64 - Unixmohi666View Answer on Stackoverflow
Solution 65 - UnixpiotrView Answer on Stackoverflow
Solution 66 - UnixMark42View Answer on Stackoverflow
Solution 67 - UnixvehomzzzView Answer on Stackoverflow
Solution 68 - UnixlukaszkoreckiView Answer on Stackoverflow
Solution 69 - UnixkenView Answer on Stackoverflow
Solution 70 - UnixquabugView Answer on Stackoverflow