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] (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)