User Tools

Site Tools


vim

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

vim [2009/01/22 10:59]
vim [2009/01/22 10:59] (current)
Line 1: Line 1:
 +====== VIM snippets ======
 +===== Redirect Command output =====
 +'':help :redir''
  
 +===== Align columns in ASCII-art table (ala wiki syntax) =====
 +
 +<code>'<,'>v/^|[^|]\+\%27v|/ s/\(^|[^|]\+\)|/\1 |/</code>
 +
 +To repeat this command numerous times, record executing it as a macro, then use normal macro repetition.
 +
 +==== Wtf? ====
 +
 +The break down is below, but the gist is that we find lines of text which don't have a "|" in the column we want, and then use a substition to grab the text before the second "|" and add a space between them, hence pushing the "|" one column to the right. You then repeat this command until no substitions take place.
 +
 +<code>
 +'<,'>            From mark "<" to mark ">" execute the following command
 +
 +v/ --- /         Check each line against Regular Expression "---", if it
 +                 **doesn't** match do the following commands
 +
 +^|[^|]\+\%27v|   Match a vertical bar, followed by 1-or-more "not vertical bar"
 + characters ( [^|]\+ ), followed by an assertion at we're in
 +                 visual column 27 ( \%27v ), followed by a vertical bar
 +
 +s/ --- / ### /   Substitute text matching RegExp "---" with text in "###"
 +
 +\(^|[^|]\+\)|    (Match) Capture between \( and \) a vertical bar followed by 1
 + or more not-vertical-bars. This capture should be immediately
 +                 followed by a vertical bar
 +
 +\1 |             (Replacement) Put our first captured group back, followed by a
 +                 space, followed by a vertical bar.
 +</code>
 +
 +===== A complete function for aligning ASCII-art tables =====
 +
 +To use: source this into Vim (":source <filename>"), and then invoke AlignTable() over the range of the table. EG Visually select table and then "%%'<,'>call AlignTable()%%"
 +
 +<code vim>
 +" Align a single ASCII-art table column
 +" tcol: Which column of the table to align (i.e. first column = 1, second = 2 etc)
 +" vcol: Align table column to which virtual/visual column on the screen?
 +function! AlignTableColumn ( tcol, vcol ) range
 +    let i = a:vcol - a:tcol " Worst case
 +    while i
 + " Edge one screen column closer to desired location
 + execute 'silent! ' . a:firstline . ',' . a:lastline . 'v/^\(\(|[^|]*\)\{' . a:tcol . '}\)\%' . a:vcol . 'v|/ s/^\(\(|[^|]*\)\{' . a:tcol . '}\)|/\1 |/'
 + let i -= 1
 +    endwhile
 +endfunction
 +
 +" Align a whole ASCII-art table
 +" Tables are expected to be drawn using "|" characters, including the header
 +"
 +" Usage: Invoke this function with the range of lines the table occupies,
 +" including the header - which will be used as the "desired column location"
 +"
 +" TODO: Tally the maximum width for each column by scanning all rows, and use
 +" these values to calculate new column boundry locations
 +function! AlignTable() range
 +    let header = getline(a:firstline)
 +    let bars = 0
 +
 +    let i = 0
 +    " Count number of "|"s
 +    while i < strlen(header)
 + if header[i] == '|'
 +     let bars += 1
 + endif
 + let i += 1
 +    endwhile
 +    unlet i
 +    unlet header
 +
 +    " Now get column widths for each row, keeping the maximum in colwidth
 +    let colwidth = []
 +    let i = bars
 +    " Init list of correct length
 +    while i
 + let colwidth += [0]
 + let i -= 1
 +    endwhile
 +    unlet i
 +
 +    let i = a:firstline
 +    while i <= a:lastline
 + let row = getline(i)
 + let curbar = 0
 + let pos = 0
 + let poslist = []
 + while curbar < bars
 +     let pos = match(row, '|', pos)
 +     let poslist += [pos]
 +     let pos += 1 " Move past current match, ready for next
 +     if len(poslist) > 1
 + if colwidth[curbar] < ( poslist[curbar] - poslist[(curbar-1)] )
 +     let colwidth[curbar] = ( poslist[curbar] - poslist[(curbar-1)] )
 + endif
 +     endif
 +     let curbar += 1
 + endwhile
 + let i += 1
 +    endwhile
 +
 +    let poslist = [ match(getline(a:firstline), '|') ]
 +    call remove(colwidth, 0) " Strip first column (always width 0)
 +    for width in colwidth
 + let poslist += [ (poslist[(len(poslist)-1)] + width) ]
 +    endfor
 +
 +    " NB There is one more bar than there are cols, and we ignore the first
 +    " bar
 +    let i = 1
 +    call remove(poslist, 0)
 +    for vcol in poslist
 + " Note that every bar must be moved at least once to avoid bugs, hence
 + " the (vcol+1) below
 + execute (a:firstline).",".a:lastline."call AlignTableColumn(".i.", ".(vcol+1).")"
 + let i += 1
 +    endfor
 +endfunction
 +</code>
 +
 +===== XMLFolding =====
 +Adapted from [[http://www.vim.org/scripts/script.php?script_id=1438|XML Folding : Folds XML / HTML Tags, CDATA and comments]], by Thadeu Aparecido Coelho de Paula.
 +
 +<code vim>
 +" Basic vim commands for folding definition
 +syn sync fromstart
 +set foldmethod=syntax
 +
 +                                               ┌ Up to end-of-tag                                                      
 +                            Name of tag ╗      │      ┌ End-of-tag not preceeded by "/"                                
 +"External capture ("\z1" in end= param) ┐ ║      │      │   ┌ End-of-tag                                                 
 +           Normal capture ("\1")═╦════╪═╬════╗ │      │   │ ┌ End-of-match                                             
 +      Forbidden first chars ┐    ║ ┌──┴─╫──┐ ║ │      │   │ │  ┌ Assert that a matching closing tag occurs later   
 +           Start of tag ┐┌──┴───┐║ │  ╔═╩╗ │ ║┌┴────┐┌┴──┐│┌┴┐┌┴──────┐                                               
 +syn region XMLFold start=#<[/?!]\@!\(\z(\S\+\)\)\_[^>]*/\@<!>\ze\_.*</\1># end=#</\z1># fold transparent keepend extend
 +                                                                              └───┬┘                                  
 +                                                         Closing tag of same name ┘                                   
 +
 +syn match XMLCData "<!\[CDATA\[\_.\{-}\]\]>" fold transparent extend
 +syn match XMLCommentFold "<!--\_.\{-}-->" fold transparent extend 
 +
 +
 +" Label shown for folded lines
 +set foldtext=XMLFoldLabel()
 + fun! XMLFoldLabel()
 +  let getcontent = substitute(getline(v:foldstart), "^[[:space:]]*", "", 'g')
 + let linestart = substitute(v:folddashes, ".", '»', 'g')
 + return linestart . " " . getcontent
 +endfunction
 +</code>
 +(The line drawings were made with the excellent [[http://www.vim.org/scripts/script.php?script_id=173|BoxDraw]] vim plugin by Andrew Nikitin.)
 +
 +===== Win32 Paths =====
 +When under Cygwin, '''ifsname''' is set to the Unix default, which means that paths such as ''dir\to\file'' are broken up into sections when you try to <C-w><C-f> or ''gf'' to them.
 +
 +You can fix this with:
 +<code>
 +set isfname=@,48-57,/,\\,.,-,_,+,,,#,$,%,{,},[,],:,@-@,!,~,=
 +</code>
 +
 +<html><!-- vim: set tw=78 ts=4 sw=4 ft=dokuwiki: --></html>
 +
 +===== Pop-up menu colours =====
 +The default pop-up menu colour for auto-complete (e.g. ''^X^O'') is grey-on-pink, which is hard to read. So I added the following to my desert256 colour scheme:
 +
 +<code vim>
 +" ~/.vim/colors/desert256.vim
 +"Pmenu
 +call <SID>X("Pmenu", "ffffff", "cc00cc", "")
 +call <SID>X("PmenuSel", "ffffff", "990044", "")
 +call <SID>X("PmenuSbar", "ffffff", "550077", "")
 +call <SID>X("PmenuThumb", "ffffff", "440088", "")
 +</code>
 +
 +See also [[http://www.mail-archive.com/vim@vim.org/msg11890.html|this post]] and '':help Pmenu''.
 +
 +Here's how it looks:
 +
 +{{:vim_popupmenu.png|Screenshot showing VIM's popup menu}}
 +
 +I really like the function summary in the lower pane, and all this for a Python module I wrote myself! I'm amazed that vim can work out the type of ''jobtags'' and then parse the classes help!
vim.txt · Last modified: 2009/01/22 10:59 (external edit)