Vim notes

From raju

Note:- This page will be migrated to http://www.kamaraju.xyz/dk/vim_notes. Once the migration is done, it will be deleted.

Tips

download gvim

Official:

or

https://www.vim.org/ -> click on the Download link in the left pane -> click on "PC: MS-DOS and MS-Windows" link -> click on gvim81.exe link

alternate websites:

Once you download the executable, compare its md5sum with that listed in http://ftp.vim.org/pub/vim/pc/MD5SUMS

tags | checksum

Move a file from vim to gvim

Say you are editing a file in vim and would like to open it in a gvim window of its own

 :execute 'bdelete | silent !gvim' shellescape(expand('%:p'), 1) | redraw!

To launch a gvim instance from vim

 :execute 'silent !gvim' | redraw!

See also:

  • http://malayamaarutham.blogspot.com/2008/10/open-new-gvim-window-from-gvim.html
  • http://stackoverflow.com/questions/19553342/gvim-move-tab-to-new-window

search for files in predefined directories

Add something like this to ~/.vimrc

set path+=/home/rajulocal/bin
" By default the files at depth=1 are searched. The ** makes the search recursive.
set path+=/home/rajulocal/work/python/**

and launch gvim as follows.

% gvim -c ":find hello_world.py"

Select text when nowrap option is set

When nowrap option is on, by definition, gvim will only show a part of the long line. In such cases, using the mouse to select a string such that

start of selection is visible on the screen
end of selection is off-screen to the right

does not work. When the mouse selection hits the edge of the screen, the window is not scrolled automatically and the selection stops. I found the following work around useful in this type of situations

:set sidescrolloff=999

Then select text by using

  1. keyboard in the visual mode
  2. or by using the mouse
  3. or a mixture of both. For example first select some text by by mouse and then use the keyboard to extend/reduce the selection or select by keyboard first and then extend/reduce the selection by right click and dragging the mouse.

Ref:-

select and replace

Select text using mouse and press 'y' to yank it.
Now select the text that needs to be replaced and press 'p'. This replaces the latter selection with the former.

Diff against a file that is already opened

Open the first file either by "gvim file1.txt" or by first launching gvim and then using

:e file1.txt

To diff this against another file

:vert diffsplit file2.txt

tags | split and diff

Open the current file in new tab

Say you have two files open in a split window (vim -O2 file1.txt file2.txt) and want to open the current file in a new tab

    :tabe %<CR>
    

This will create a new tab for the current file and leave the original tab unchanged. If, instead you want to remove it from the original tab, use

    <CTRL-W>T
    

See:

    :help Ctrl-W_T
    :help Ctrl-W
    

Open a file in a vertically split readonly window

Open the first file either by "gvim file1.txt" or by first launching gvim and then using

:e file1.txt

To vertically split the window and open another file in a readonly mode

:vert sv file2.txt

where sv is a shortcut for "splitview" which is same as :split, but sets 'readonly' option for this buffer.

open files with different extensions

% file=foo.txt; gvim /path/to/dir1/${file:t:r}.dat /path/to/dir2/${file} -p

will open /path/to/dir1/foo.dat, /path/to/dir2/foo.txt in different tabs of gvim.

Open the gvim window on the second monitor

Add this to the ~/.gvimrc

winpos 1920 0

The X and Y positions may need to be changed depending on the monitor configuration.

Use a vertical window when opening text files

Normally gvim opens with 25 rows and 80 columns. But to open all the txt files in a long vertical window, use this autocmd.

au GUIEnter *.txt set lines=50 columns=80

increase gvim window size when splitting

I use set columns=80 in ~/.gvimrc. This works great when only a single file is opened. However, if I do a vertical split (:vs) to open another file in this window, then each file only gets 40 columns since the original gvim window size remains constant at 80 columns. To get around this use

    :set columns+=81 | vs new_file

This will first increment the number of columns and then opens the file in a vertical split.

Note:- the columns are incremented by 81 instead of 80 since the separator takes up a column of its own.

Other related commands

    :set columns+=81 | vert sf new_file

Further reading:- https://groups.google.com/forum/#!topic/vim_use/R4gg-YdPHJM

debugging vim problems

When facing a problem with vim, try reproducing it with vim -u NONE -U NONE -i NONE -N

If you suspect the problem is with a plugin, use "vim -u NONE -N" to have a working vim immdediately.

Start vimdiff with number and wrap set

gvimdiff junk3 junk4 -c "windo set nu wrap"

This will set nu, wrap options in both the diff windows.

Join all lines in a paragraph

Use the visual mode: vipJ

Join lines without an added space

Use gJ

gvim ctags new tab

To open the current tag in a new tab in gvim

<C-w><C-]><C-w>T

Ref:- http://stackoverflow.com/questions/6069279/vim-open-tag-in-new-tab/6069388#6069388

map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>

Ref:- http://stackoverflow.com/questions/563616/vim-and-ctags-tips-and-tricks

vim ctags vertically split window

To open the current tag in a vertically split window

map <A-]> :vsp <CR>:exec("tag ".expand("<cword>"))<CR>

Ref:- http://stackoverflow.com/questions/563616/vim-and-ctags-tips-and-tricks

vim copy line numbers

save and restore vim sessions

move tabs across using mouse in gvim

There are two ways to do this.

  • recompile vim by applying this patch from Ken Takata. Here are the instructions to apply a patch and recompile vim in Debian
  • The second approach is to add the following line to ~/.gvimrc
set guioptions-=e

Ref:- https://groups.google.com/forum/#!topic/vim_use/CfwgkVRm1jY

Input control characters

Use ^Vnnn where nnn is the character value and 0 <= nnn <= 255. For example, ctrl-v65 will give A. For more details see http://vim.wikia.com/wiki/Entering_special_characters

Select and search for a string

  1. Visually select the text you want to search
  2. yq/p
  3. Enter
Ref
  • http://stackoverflow.com/questions/363111/search-for-selection-in-vim

Double click and search for a string

Add this to the ~/.vimrc

nnoremap <silent> <2-LeftMouse> :let @/='\V'.escape(expand('<cword>'), '\').''<cr>:set hls<cr>

This is better than

noremap <2-LeftMouse> *#

and related tricks since (1) it does not mess up with the search history. So if you do /<UP> , previously searched string comes up instead of the double clicked word. (2) The screen does not jump between searches due to consecutive use of * and #. (3) Does not move the line with the current word to the center.

Ref

See also comments in

When multiple files are opened in multiple gvim windows

Add this to ~/.vimrc

" if a file is already open, bring that window up
source $VIMRUNTIME/macros/editexisting.vim

Run a shell script before starting gvim

To run a shell script before starting gvim, add the following lines to ~/.zshrc

gvim() {
    source ~$USER/bin/custom_script.zsh
    /usr/bin/gvim "$@"
}

I use this hack to correctly set the DISPLAY variable before launching the gvim application.

open recently edited files

:browse oldfiles

This pops up a menu and you can enter the number corresponding to a file you want to edit.

switch between horizontally split window and vertically split window

 ctrl-W L    change horizontally split window to vertically split window
 ctrl-W J    change vertically split window to horizontally split window

In fact ctrl-W followed by H, J, K, L will move the current window to the far left, bottom, top, right respectively like normal cursor navigation. The lower case equivalents move focus instead of moving the window.

Ref:- http://stackoverflow.com/questions/1269603/to-switch-from-vertical-split-to-horizontal-split-fast-in-vim

Move current window to its own tab

 crtl-W T

See :help CTRL-W_T for more information.

Using vim as pager

fold only functions in C++ programs

While editing C++ program, if you want to fold only functions but nothing in between (ex:- no folding of if/else clasues)

    :set foldmethod=syntax foldnestmax=1
    

split and edit a new file

    :new        - Create a new window and start editing an empty file in it.
    :vnew       - like :new, but splits vertically
    :set splitright  -  When on, splitting a window will put the new window right of the current one
    :set splitbelow  -  When on, splitting a window will put the new window below the current one
    

Options

:set cursorline - hightlight current line

Plugins

Some useful vim plugins

NrrwRgn

A Narrow Region Plugin for vim (like Emacs Narrow Region). The development version is at https://github.com/chrisbra/NrrwRgn . The stable version can be found at http://www.vim.org/scripts/script.php?script_id=3075.

Using the stable version 32, I encountered some problems with highlighting - https://groups.google.com/forum/#!topic/vim_use/WFheSJa8_Wo (Last checked 2014-12-21). The issue is present even in the development version but I am unable to reproduce it (last checked 2015-01-24). It is suggested to upgrade to vim 7.4 in order to use the dev version.

LogiPat

Useful to find a word but not another.

For example, to search for the word conv but exclude conversion, you would do

:LP "cond" & !"conversion"
   - http://vim.sourceforge.net/scripts/script.php?script_id=1290
   - http://vim.1045645.n5.nabble.com/search-for-one-word-and-exclude-another-td1160607.html

Other sample use cases

:LP !"RCMP" && !"QEII" && !"SPCA" && "[A-Z]\{4,\}"

StlShowFunc

Use this plugin to display the function name in the status line for C++ programs. Supports other programming languages as well.

Links

- download from - http://www.drchip.org/astronaut/vim/vbafiles/StlShowFunc.vba.gz
- listed in - http://www.drchip.org/astronaut/vim/index.html#STLSHOWFUNC

You may want to use ":set laststatus=2" to display the status line even when there is only one file opened.

Help

cd "%:p:h" vim

what does “%:p:h” mean in VIM?

:p = full path of the file name
:h = header of the file name

Ref:-

difference between plugin and ftplugin directories

shortcuts to fold text

at cursor, one fold at cursor, all folds whole buffer, one fold whole buffer, all folds
open zo zO zr zR
close zc zC zm zM
toggle za zA

formatting text

command what it does
gq1j format current and one line below

Synatx

Searching

  • use \~\/x to search for ~/x

search and replace

  • To change all instances of ~/work with ~raju/work
%s!\~/work/!\~raju/work/!gc
  • To change all the occurences of ~/x with ~/tmp/x
%s!\~\/x!\~/tmp/x!gc

Missing Features

  1. Currently (2015-03-07) the patch to move tabs using mouse is not included in gvim by default.

Tested this on gvim 7.2 (Red Hat Enterprise Linux Server release 6.5), on gvim 7.4 (Debian Jessie/testing)
Ref:- https://groups.google.com/forum/#!topic/vim_use/CfwgkVRm1jY

  1. Ability to search for different strings in different windows

This is currently not possible

Ref:- https://groups.google.com/forum/#!topic/vim_use/VORqYNb-d4E

Check if these features are possible

  1. How to fold all functions belonging to a class in a .cpp file?

My rc files

My ~/.vimrc file

set bs=2
set is ic hls
set si ai sm

" Keep the cursor in the same position when doing PgUp or PgDown
set nostartofline

" smooth scroll across line endings and beginnings
set whichwrap+=<,>,[,]

" By default vim dows not show the status line when only one file is opened.
" To always show it, use
set laststatus=2

set history=20000
set undolevels=1000    " use many muchos levels of undo
" ignore some file extensions when completing names by pressing tab
set wildignore=*.swp,*.bak,*.pyc,*.class

set novisualbell    " do not blink the screen on error
set noerrorbells    " do not beep

" The following trick is a really small one, but a super-efficient one, since
" it strips off two full keystrokes from almost every vim command.
" For example, to save a file, you type :w which normally involves
" 1. Press and hold shift
" 2. Press :
" 3. Release the shift key
" 4. Press w
" 5. Press Return
" This trick strips off steps 1 and 3 for each vim command.
nnoremap ; :

" If you like long lines with line wrapping enabled, this solves the problem
" that pressing down jumps your cursor over the current line to the next
" line. It changes behaviour so that it jumps to the next row in the editor
" (much more natural):
nnoremap j gj
nnoremap k gk

" to recognize file names
set isk+=/
set isk+=~

" to recognize numbers with decimal points
set isk+=.

" Double click and search for a string
"
" The original mapping I saw on internet is
" nnoremap <silent> <2-LeftMouse> :let @/='\V\<'.escape(expand('<cword>'), '\').'\>'<cr>:set hls<cr>
"
" But this has a drawback. Say '.' is included in the iskeyword list, Then
" double clicking on params will not hightlight params in params.model
" or in params. To get around this, I am using
nnoremap <silent> <2-LeftMouse> :let @/='\V'.escape(expand('<cword>'), '\').''<cr>:set hls<cr>

" Tired of clearing highlighted searches by searching for ldsfhjkhgakjks? Use
" this:
nmap <silent> ,/ :nohlsearch<CR>

" when you forgot to sudo before editing a file that requires root privileges
" (typically /etc/hosts). This lets you use w!! to do that after you opened
" the file already:
cmap w!! w !sudo tee % >/dev/null

" When you are using another application and select to go back to Vim by
" clicking inside Vim's text area, it not only switches application focus to
" Vim, but it also moves the cursor to that location. If you don't want the
" cursor to move, put the following in your vimrc:
augroup NO_CURSOR_MOVE_ON_FOCUS
  au!
  au FocusLost * let g:oldmouse=&mouse | set mouse=
  au FocusGained * if exists('g:oldmouse') | let &mouse=g:oldmouse | unlet g:oldmouse | endif
augroup END

augroup filetypedetect
  au! BufRead,BufNewFile *.sh  setfiletype zsh
augroup END


" This mapping is suggested in http://ctags.sourceforge.net/faq.html to
" generate tags from within vim
nmap ,t :!(cd %:p:h;ctags *.[chCH])&
set tags=./tags,tags,~/dev/tags

" Ref:- http://stackoverflow.com/questions/563616/vim-and-ctags-tips-and-tricks
" open a tag definition in a new tab
map <C-\> :tab split<CR>:exec("tag ".expand("<cword>"))<CR>
" open a tag definition in a vertical split
map <A-]> :vsp <CR>:exec("tag ".expand("<cword>"))<CR>


filetype plugin indent on

" see :help smartindent as to why this is needed.
inoremap # X�#


" The following command abbreviation allows typing :tabv myfile.txt to view
" the specified file in a new tab; the buffer is read-only and nomodifiable so
" you cannot accidentally change it. 
cabbrev tabv tab sview +setlocal\ nomodifiable

" get bash like tab completion
set wildmode=list:longest
set wildmenu
set wildignore=*.o,*.obj,*.so,*.png,*.jpg,*.gif,*.pyc,*.dll,*.exe

" always show the status bar (even when there is only one file open)
set laststatus=2

" file-specific autocommands
if has("autocmd")
    " exceptions
    au FileType helpfile set nonumber               " turn off line numbering for help
endif

" google search | vim gf = sign, vim gf equal to sign
set isfname-==

set paste

" if a file is already open, bring that window up
source $VIMRUNTIME/macros/editexisting.vim

" when splitting open the new files to the right and below.
set splitright splitbelow

" enable folding in perl.
let perl_fold=1

set ru

syn on

My ~/.gvimrc file

set bg=light

set guifont=DejaVu\ Sans\ Mono\ 9

" account for numbers column when 'nu' is set
set lines=25 columns=85

" copied this from http://vim.wikia.com/wiki/Start_with_a_wide_window_for_diff
if &diff
    " double the width up to a reasonable maximum
    " Add an extra 1 for vertical separator.
    let &columns = 170 + 2*&foldcolumn + 1
    let &lines = ((&lines*2 > 50) ? 50 : &lines*2)
endif

" When opening a txt file use a vertical window
au GUIEnter *.txt set lines=50 columns=85

" open the gvim window on the first montior
winpos 0 0

" copied this from http://vim.wikia.com/wiki/Show_tab_number_in_your_tab_line
" to show tab number in the tab list.
set showtabline=2 " always show tabs in gvim, but not vim
" set up tab labels with tab number, buffer name, number of windows
function! GuiTabLabel()
  let label = ''
  let bufnrlist = tabpagebuflist(v:lnum)
  " Add '+' if one of the buffers in the tab page is modified
  for bufnr in bufnrlist
    if getbufvar(bufnr, "&modified")
      let label = '+'
      break
    endif
  endfor
  " Append the tab number
  let label .= v:lnum.': '
  " Append the buffer name
  let name = bufname(bufnrlist[tabpagewinnr(v:lnum) - 1])
  if name == ''
    " give a name to no-name documents
    if &buftype=='quickfix'
      let name = '[Quickfix List]'
    else
      let name = '[No Name]'
    endif
  else
    " get only the file name
    let name = fnamemodify(name,":t")
  endif
  let label .= name
  " Append the number of windows in the tab page
  let wincount = tabpagewinnr(v:lnum, '$')
  return label . '  [' . wincount . ']'
endfunction
set guitablabel=%{GuiTabLabel()}

" copied this from http://vim.wikia.com/wiki/Show_tab_number_in_your_tab_line
" to show a tool tip for each tab displaying the list of files opened in that
" tab
function! GuiTabToolTip()
  let tip = ''
  let bufnrlist = tabpagebuflist(v:lnum)
  for bufnr in bufnrlist
    " separate buffer entries
    if tip!=''
      let tip .= " \n "
    endif
    " Add name of buffer
    let name=bufname(bufnr)
    if name == ''
      " give a name to no name documents
      if getbufvar(bufnr,'&buftype')=='quickfix'
        let name = '[Quickfix List]'
      else
        let name = '[No Name]'
      endif
    endif
    let tip.=name
    " add modified/modifiable flags
    if getbufvar(bufnr, "&modified")
      let tip .= ' [+]'
    endif
    if getbufvar(bufnr, "&modifiable")==0
      let tip .= ' [-]'
    endif
  endfor
  return tip
endfunction
set guitabtooltip=%{GuiTabToolTip()}

inoremap <C-F> <C-O>:promptrepl<CR>

My ~/.vim/ftplugin/cpp.vim

" Vim filetype plugin file
" Language:     C++
" Maintainer:   Kamaraju S. Kusumanchi <kamaraju@gmail.com>
" Last Change:  2016 Jan 19

" Only do this when not done yet for this buffer
if exists("b:did_cpp_raju_ftplugin")
  finish
endif
let b:did_cpp_raju_ftplugin = 1

" See http://vim.wikia.com/wiki/VimTip630 for more information
inoremap <expr> ' strpart(getline('.'), col('.')-1, 1) == "\'" ? "\<Right>" : "\'\'\<Left>"
inoremap <expr> " strpart(getline('.'), col('.')-1, 1) == "\"" ? "\<Right>" : "\"\"\<Left>"

inoremap ( ()<Left>
inoremap [ []<Left>
inoremap <expr> )  strpart(getline('.'), col('.')-1, 1) == ")" ? "\<Right>" : ")"
inoremap <expr> ]  strpart(getline('.'), col('.')-1, 1) == "]" ? "\<Right>" : "]"

inoremap { {<CR>}<ESC>%a

noremap z{ [[V%zF

My ~/.vim/ftplugin/perl.vim

" Vim filetype plugin file
" Language:     Perl
" Maintainer:   Kamaraju S. Kusumanchi <kamaraju@gmail.com>
" Last Change:  2016 Jan 19

" Only do this when not done yet for this buffer
if exists("b:did_perl_raju_ftplugin")
  finish
endif
let b:did_perl_raju_ftplugin = 1

inoremap " ""<Left>
inoremap ( ()<Left>
inoremap [ []<Left>
inoremap { {}<ESC>%a

dummy

dummy

location of vimrc in windows

Q. Where does vim look for vimrc in windows? A. https://superuser.com/a/892065/679081

vimrc in windows

    $cat ~/_vimrc
    " This will source C:\Program Files (x86)\Vim\_vimrc
    source $VIM\_vimrc
    
    " The "//" at the end of the directory means that file names will be built from
    " the absolute file name with all path separators substituted with percent
    " "%" sign. This will ensure file name uniqueness in the backup directory.
    set backupdir=~/.vim/tmp//,.,~/tmp,~/
    set directory=~/.vim/tmp//,.,~/tmp,/var/tmp,/tmp
    

Using this with the following settings in ~/.bashrc

    $grep PATH ~/.bashrc | grep vim | grep -v '^#'
    export PATH="/c/Program Files (x86)/Vim/vim80":$PATH
    
    $which vim       
    /c/Program Files (x86)/Vim/vim80/vim
    
    $which gvim
    /c/Program Files (x86)/Vim/vim80/gvim
    

vim version = 8.0-586

search for spaces

  • / * - zero or more spaces
  • / \+ - one or more spaces
  • / {0,n} - 0 to n spaces (where n <math>\in</math> N)

links on the net