This shows you the differences between two versions of the page.
— |
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! |