diff --git a/README.md b/README.md index f495d65..35d4912 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ Optionally download one of the [releases](https://github.com/sheerun/vim-polyglo - [latex](https://github.com/LaTeX-Box-Team/LaTeX-Box) (syntax, indent, ftplugin) - [less](https://github.com/groenewege/vim-less) (syntax, indent, ftplugin, ftdetect) - [liquid](https://github.com/tpope/vim-liquid) (syntax, indent, ftplugin, ftdetect) +- [mako](https://github.com/sophacles/vim-bundle-mako) (syntax, indent, ftplugin, ftdetect) - [markdown](https://github.com/tpope/vim-markdown) (syntax, ftplugin, ftdetect) - [nginx](https://github.com/nginx/nginx) (syntax, indent, ftdetect) - [nim](https://github.com/zah/nim.vim) (syntax, compiler, indent, ftdetect) diff --git a/build b/build index 8e9b00c..bf3627b 100755 --- a/build +++ b/build @@ -136,6 +136,7 @@ PACKS=" latex:LaTeX-Box-Team/LaTeX-Box less:groenewege/vim-less liquid:tpope/vim-liquid + mako:sophacles/vim-bundle-mako markdown:tpope/vim-markdown nginx:nginx/nginx::/contrib/vim/ nim:zah/nim.vim:_BASIC diff --git a/ftdetect/polyglot.vim b/ftdetect/polyglot.vim index 5f30e46..160c164 100644 --- a/ftdetect/polyglot.vim +++ b/ftdetect/polyglot.vim @@ -270,6 +270,10 @@ au BufNewFile,BufRead */templates/**.liquid,*/layout/**.liquid,*/snippets/**.liq \ let b:liquid_subtype = 'html' | \ set ft=liquid | endif +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'mako') == -1 + +au BufRead,BufNewFile *.mako set filetype=mako +endif if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'markdown') == -1 autocmd BufNewFile,BufRead *.markdown,*.md,*.mdown,*.mkd,*.mkdn diff --git a/ftplugin/mako.vim b/ftplugin/mako.vim new file mode 100644 index 0000000..cd8cd53 --- /dev/null +++ b/ftplugin/mako.vim @@ -0,0 +1,15 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'mako') == -1 + +" Vim filetype plugin file +" Language: Mako +" Maintainer: Randy Stauner +" Last Change: 2014-02-07 +" Version: 0.1 + +if exists("b:did_ftplugin") | finish | endif +let b:did_ftplugin = 1 + +setlocal comments=:## +setlocal commentstring=##%s + +endif diff --git a/indent/mako.vim b/indent/mako.vim new file mode 100644 index 0000000..bd6120a --- /dev/null +++ b/indent/mako.vim @@ -0,0 +1,358 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'mako') == -1 + +" 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 + +let sw=2 " default shiftwidth of 2 spaces + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal nosmartindent +setlocal noautoindent +setlocal nocindent +setlocal nolisp + +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: + +endif diff --git a/syntax/mako.vim b/syntax/mako.vim new file mode 100644 index 0000000..7a9eb65 --- /dev/null +++ b/syntax/mako.vim @@ -0,0 +1,96 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'mako') == -1 + +" Vim syntax file +" Language: Mako +" Maintainer: Armin Ronacher +" URL: http://lucumr.pocoo.org/ +" Last Change: 2013-05-01 +" Version: 0.6.1+ +" +" Thanks to Brine Rue who noticed a bug in the +" delimiter handling. +" +" Known Limitations +" the <%text> block does not have correct attributes + +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +if !exists("main_syntax") + let main_syntax = "html" +endif + +"Source the html syntax file +ru! syntax/html.vim +unlet b:current_syntax + +" tell html.vim what syntax groups should take precedence (see :help html.vim) +syn cluster htmlPreproc add=makoLine,makoVariable,makoTag,makoDocComment,makoDefEnd,makoText,makoDelim,makoEnd,makoComment,makoEscape + +"Put the python syntax file in @pythonTop +syn include @pythonTop syntax/python.vim + +" End keywords +syn keyword makoEnd contained endfor endwhile endif endtry enddef + +" Block rules +syn region makoLine matchgroup=makoDelim start=#^\s*%# end=#$# keepend contains=@pythonTop,makoEnd +syn region makoBlock matchgroup=makoDelim start=#<%!\?# end=#%># keepend contains=@pythonTop,makoEnd + +" Variables +syn region makoNested start="{" end="}" transparent display contained contains=makoNested,@pythonTop +syn region makoVariable matchgroup=makoDelim start=#\${# end=#}# contains=makoNested,@pythonTop + +" Comments +syn region makoComment start="^\s*##" end="$" +syn region makoDocComment matchgroup=makoDelim start="<%doc>" end="" keepend + +" Literal Blocks +syn region makoText matchgroup=makoDelim start="<%text[^>]*>" end="" + +" Attribute Sublexing +syn match makoAttributeKey containedin=makoTag contained "[a-zA-Z_][a-zA-Z0-9_]*=" +syn region makoAttributeValue containedin=makoTag contained start=/"/ skip=/\\"/ end=/"/ +syn region makoAttributeValue containedin=MakoTag contained start=/'/ skip=/\\'/ end=/'/ + +" Tags +syn region makoTag matchgroup=makoDelim start="<%\(def\|call\|page\|include\|namespace\|inherit\|block\|[a-zA-Z_][a-zA-Z0-9_]*:[a-zA-Z_][a-zA-Z0-9_]*\)\>" end="/\?>" +syn match makoDelim "" + +syn region makoJavaScript matchgroup=makoDelim start=+<%block .*js.*>+ keepend end=++ contains=@htmlJavaScript,htmlCssStyleComment,htmlScriptTag,@htmlPreproc,makoLine,makoBlock,makoVariable +syn region makoCssStyle matchgroup=makoDelim start=+<%block .*css.*>+ keepend end=++ contains=@htmlCss,htmlTag,htmlEndTag,htmlCssStyleComment,@htmlPreproc,makoLine,makoBlock,makoVariable + +" Newline Escapes +syn match makoEscape /\\$/ + +" Default highlighting links +if version >= 508 || !exists("did_mako_syn_inits") + if version < 508 + let did_mako_syn_inits = 1 + com -nargs=+ HiLink hi link + else + com -nargs=+ HiLink hi def link + endif + + HiLink makoDocComment makoComment + HiLink makoDefEnd makoDelim + + HiLink makoAttributeKey Type + HiLink makoAttributeValue String + HiLink makoText Normal + HiLink makoDelim Preproc + HiLink makoEnd Keyword + HiLink makoComment Comment + HiLink makoEscape Special + + delc HiLink +endif + +let b:current_syntax = "html" + +endif