====== VIM snippets ====== ===== Redirect Command output ===== '':help :redir'' ===== Align columns in ASCII-art table (ala wiki syntax) ===== '<,'>v/^|[^|]\+\%27v|/ s/\(^|[^|]\+\)|/\1 |/ 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. '<,'> 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. ===== A complete function for aligning ASCII-art tables ===== To use: source this into Vim (":source "), and then invoke AlignTable() over the range of the table. EG Visually select table and then "%%'<,'>call AlignTable()%%" " 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 ===== 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. " 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\_.*# end=## fold transparent keepend extend " └───┬┘ " Closing tag of same name ┘ syn match XMLCData "" 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 (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 or ''gf'' to them. You can fix this with: set isfname=@,48-57,/,\\,.,-,_,+,,,#,$,%,{,},[,],:,@-@,!,~,= ===== 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: " ~/.vim/colors/desert256.vim "Pmenu call X("Pmenu", "ffffff", "cc00cc", "") call X("PmenuSel", "ffffff", "990044", "") call X("PmenuSbar", "ffffff", "550077", "") call X("PmenuThumb", "ffffff", "440088", "") 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!