" Vim indent file " Language: Mako " Author: Scott Torborg " Version: 0.4 " License: Do What The Fuck You Want To Public License (WTFPL) " " --------------------------------------------------------------------------- " " DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE " Version 2, December 2004 " " Copyright (C) 2004 Sam Hocevar " " Everyone is permitted to copy and distribute verbatim or modified " copies of this license document, and changing it is allowed as long " as the name is changed. " " DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE " TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION " " 0. You just DO WHAT THE FUCK YOU WANT TO. " " --------------------------------------------------------------------------- " " This script does more useful indenting for Mako HTML templates. It indents " inside of control blocks, defs, etc. Note that this indenting style will " sacrifice readability of the output text for the sake of readability of the " template. " " We'll use HTML indenting globally, python inside <% %> blocks. Inspired by " the excellent PHP + HTML indentation files such as php.vim by Pim Snel. " " Changelog: " 0.4 - 5 March 2010 " - Added license information " 0.3 - 15 September 2009 " - Added explicit indenting for ## comments, fixed unindenting count, " thanks to Mike Lewis (@MikeRLewis) for this " 0.2 - 15 June 2009 " - Fixed issue where opening and closing mako tags on the same line " would cause incorrect indenting " 0.1 - 06 June 2009 " - Initial public release of mako indent file if exists("b:did_indent") finish endif let b:did_indent = 1 setlocal nosmartindent setlocal noautoindent setlocal nocindent setlocal nolisp setlocal expandtab setlocal softtabstop=2 setlocal shiftwidth=2 setlocal indentexpr=GetMakoIndent() setlocal indentkeys+=*,<>>,,end,: " Only define the function once. if exists("*GetMakoIndent") finish endif if exists('g:html_indent_tags') unlet g:html_indent_tags endif function IsInsidePythonBlock(startline) " Loop until we get a line that's either <% or %> let lnum = a:startline while getline(lnum) !~ '\(%>\|<%\)$' && lnum > 0 let lnum = lnum - 1 endwhile " lnum points to the last control. If it's a <% then we're inside an " embedded python block, otherwise we're not. return getline(lnum) =~ '<%$' endfunction function GetMakoIndent() " Find a non-empty line above the current line let lnum = prevnonblank(v:lnum - 1) " Hit the start of the file, use zero indent. if lnum == 0 return 0 endif let line = getline(lnum) " last line let cline = getline(v:lnum) " current line let pline = getline(lnum - 1) " previous to last line let ind = indent(lnum) if line =~ '^\s*##' return indent(lnum) end let restore_ic=&ic let &ic=1 " ignore case let ind = HtmlIndentSum(lnum, -1) let ind = HtmlIndentSum(lnum, -1) let ind = ind + HtmlIndentSum(v:lnum, 0) let &ic=restore_ic let ind = indent(lnum) + (&sw * ind) " Indent after %anything: or <%anything NOT ending in /> if line =~ '^\s*%.*:\s*$' let ind = ind + &sw endif " Unindent before %end* or $' let scanlnum = lnum " Scan backwards until we find the beginning of this python block. while getline(scanlnum) !~ '<%$' && scanlnum > 0 let scanlnum = scanlnum - 1 endwhile let ind = indent(scanlnum) endif " If we're inside a python block and the previous line ends in a colon, " indent. if IsInsidePythonBlock(lnum - 1) " Indent after : if line =~ '\:$' let ind = ind + &sw endif endif return ind endfunction " [-- helper function to assemble tag list --] fun! HtmlIndentPush(tag) if exists('g:html_indent_tags') let g:html_indent_tags = g:html_indent_tags.'\|'.a:tag else let g:html_indent_tags = a:tag endif endfun fun! MakoIndentPush(tag) if exists('g:mako_indent_tags') let g:mako_indent_tags = g:mako_indent_tags.'\|'.a:tag else let g:mako_indent_tags = a:tag endif endfun " [-- --] call HtmlIndentPush('a') call HtmlIndentPush('abbr') call HtmlIndentPush('acronym') call HtmlIndentPush('address') call HtmlIndentPush('b') call HtmlIndentPush('bdo') call HtmlIndentPush('big') call HtmlIndentPush('blockquote') call HtmlIndentPush('button') call HtmlIndentPush('caption') call HtmlIndentPush('center') call HtmlIndentPush('cite') call HtmlIndentPush('code') call HtmlIndentPush('colgroup') call HtmlIndentPush('del') call HtmlIndentPush('dfn') call HtmlIndentPush('dir') call HtmlIndentPush('div') call HtmlIndentPush('dl') call HtmlIndentPush('em') call HtmlIndentPush('fieldset') call HtmlIndentPush('font') call HtmlIndentPush('form') call HtmlIndentPush('frameset') call HtmlIndentPush('h1') call HtmlIndentPush('h2') call HtmlIndentPush('h3') call HtmlIndentPush('h4') call HtmlIndentPush('h5') call HtmlIndentPush('h6') call HtmlIndentPush('i') call HtmlIndentPush('iframe') call HtmlIndentPush('ins') call HtmlIndentPush('kbd') call HtmlIndentPush('label') call HtmlIndentPush('legend') call HtmlIndentPush('map') call HtmlIndentPush('menu') call HtmlIndentPush('noframes') call HtmlIndentPush('noscript') call HtmlIndentPush('object') call HtmlIndentPush('ol') call HtmlIndentPush('optgroup') call HtmlIndentPush('pre') call HtmlIndentPush('q') call HtmlIndentPush('s') call HtmlIndentPush('samp') call HtmlIndentPush('script') call HtmlIndentPush('select') call HtmlIndentPush('small') call HtmlIndentPush('span') call HtmlIndentPush('strong') call HtmlIndentPush('style') call HtmlIndentPush('sub') call HtmlIndentPush('sup') call HtmlIndentPush('table') call HtmlIndentPush('textarea') call HtmlIndentPush('title') call HtmlIndentPush('tt') call HtmlIndentPush('u') call HtmlIndentPush('ul') call HtmlIndentPush('var') " For some reason the default HTML indentation script doesn't consider these " elements to be worthy of indentation. call HtmlIndentPush('p') call HtmlIndentPush('dt') call HtmlIndentPush('dd') " [-- --] if !exists('g:html_indent_strict') call HtmlIndentPush('body') call HtmlIndentPush('head') call HtmlIndentPush('html') call HtmlIndentPush('tbody') endif " [-- --] if !exists('g:html_indent_strict_table') call HtmlIndentPush('th') call HtmlIndentPush('td') call HtmlIndentPush('tr') call HtmlIndentPush('tfoot') call HtmlIndentPush('thead') endif " [-- --] call MakoIndentPush('%def') call MakoIndentPush('%block') call MakoIndentPush('%call') call MakoIndentPush('%doc') call MakoIndentPush('%text') call MakoIndentPush('%.\+:.\+') delfun HtmlIndentPush delfun MakoIndentPush set cpo-=C " [-- get number of regex matches in a string --] fun! MatchCount(expr, pat) let mpos = 0 let mcount = 0 let expr = a:expr while (mpos > -1) let mend = matchend(expr, a:pat) if mend > -1 let mcount = mcount + 1 endif if mend == mpos let mpos = mpos + 1 else let mpos = mend endif let expr = strpart(expr, mpos) endwhile return mcount endfun " [-- count indent-increasing tags of line a:lnum --] fun! HtmlIndentOpen(lnum) let s = substitute('x'.getline(a:lnum), \ '.\{-}\(\(<\)\('.g:html_indent_tags.'\)\>\)', "\1", 'g') let s = substitute(s, "[^\1].*$", '', '') return strlen(s) endfun " [-- count indent-decreasing tags of line a:lnum --] fun! HtmlIndentClose(lnum) let s = substitute('x'.getline(a:lnum), \ '.\{-}\(\(<\)/\('.g:html_indent_tags.'\)\>>\)', "\1", 'g') let s = substitute(s, "[^\1].*$", '', '') return strlen(s) endfun " [-- count indent-increasing mako tags of line a:lnum --] fun! MakoIndentOpen(lnum) let s = substitute('x'.getline(a:lnum), \ '.\{-}\(\(<\)\('.g:mako_indent_tags.'\)\>\)', "\1", 'g') let s = substitute(s, "[^\1].*$", '', '') return strlen(s) endfun " [-- count indent-decreasing mako tags of line a:lnum --] fun! MakoIndentClose(lnum) let mcount = MatchCount(getline(a:lnum), '') let mcount = mcount + MatchCount(getline(a:lnum), '<\('.g:mako_indent_tags.'\)[^>]*/>') return mcount endfun " [-- count indent-increasing '{' of (java|css) line a:lnum --] fun! HtmlIndentOpenAlt(lnum) return strlen(substitute(getline(a:lnum), '[^{]\+', '', 'g')) endfun " [-- count indent-decreasing '}' of (java|css) line a:lnum --] fun! HtmlIndentCloseAlt(lnum) return strlen(substitute(getline(a:lnum), '[^}]\+', '', 'g')) endfun " [-- return the sum of indents respecting the syntax of a:lnum --] fun! HtmlIndentSum(lnum, style) let open = HtmlIndentOpen(a:lnum) + MakoIndentOpen(a:lnum) let close = HtmlIndentClose(a:lnum) + MakoIndentClose(a:lnum) if a:style == match(getline(a:lnum), '^\s*HtmlIndentOpenAlt(a:lnum) - HtmlIndentCloseAlt(a:lnum) endif endif return 0 endfun " vim: set ts=4 sw=4: