" Author: Eric Van Dewoestine " " Description: {{{ " Xml indent file using IndentAnything. " " License: " " Copyright (C) 2005 - 2009 Eric Van Dewoestine " " This program is free software: you can redistribute it and/or modify " it under the terms of the GNU General Public License as published by " the Free Software Foundation, either version 3 of the License, or " (at your option) any later version. " " This program is distributed in the hope that it will be useful, " but WITHOUT ANY WARRANTY; without even the implied warranty of " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " GNU General Public License for more details. " " You should have received a copy of the GNU General Public License " along with this program. If not, see . " " }}} let b:did_indent = 1 if &indentexpr =~ 'EclimGetXmlIndent' || \ (!exists('b:disableOverride') && exists('g:EclimXmlIndentDisabled')) finish endif let b:disableOverride = 1 runtime! indent/dtd.vim setlocal indentexpr=EclimGetXmlIndent(v:lnum) setlocal indentkeys=o,O,*,<>>,<<>,/,{,} " EclimGetXmlIndent(lnum) {{{ function! EclimGetXmlIndent(lnum) let line = line('.') let col = line('.') let adj = 0 let doctypestart = search('', 'bcW') if doctypestart > 0 let doctypestart = search('\[', 'cW', doctypestart) let doctypeend = search('\]>', 'cW') endif call cursor(line, col) let cdatastart = search(' 0 let cdatastart = search('\[', 'cW', cdatastart) let cdataend = search('\]\]>', 'cW') endif call cursor(line, col) " Inside 0 && doctypestart < a:lnum && \ (doctypeend == 0 || (doctypeend > doctypestart && a:lnum <= doctypeend)) if a:lnum < doctypeend call DtdIndentAnythingSettings() return EclimGetDtdIndent(a:lnum) elseif a:lnum == doctypeend return indent(a:lnum) - &sw endif else " in a <[CDATA[ section if cdatastart > 0 && cdatastart < a:lnum && \ (cdataend == 0 || (cdataend >= cdatastart && a:lnum <= cdataend)) " only indent if nested text looks like xml if getline(a:lnum) =~ '^\s*<' if a:lnum == cdatastart + 1 return indent(cdatastart) + &sw endif else return indent(a:lnum) endif " make sure the closing of the CDATA lines up with the opening. if a:lnum == cdataend return indent(cdatastart) endif " make sure that tag following close of CDATA is properly indented. elseif cdatastart > 0 && cdatastart < a:lnum && \ (cdataend >= cdatastart && prevnonblank(a:lnum - 1) == cdataend) return indent(cdatastart) - &sw endif call XmlIndentAnythingSettings() let adj = s:XmlIndentAttributeWrap(a:lnum) * &sw " handle case where previous line is a multi-line comment () on one " line. let prevline = prevnonblank(a:lnum - 1) if getline(prevline) =~ '^\s\+' let adj = indent(prevline) endif " handle case where comment end is on its own line. if getline(line) =~ '^\s*-->' let adj -= &sw endif endif return IndentAnything() + adj endfunction " }}} " XmlIndentAnythingSettings() {{{ function! XmlIndentAnythingSettings() " Syntax name REs for comments and strings. let b:blockCommentRE = 'xmlComment' let b:commentRE = b:blockCommentRE let b:lineCommentRE = 'xmlComment' let b:stringRE = 'xmlString' let b:singleQuoteStringRE = b:stringRE let b:doubleQuoteStringRE = b:stringRE setlocal comments=sr: let b:blockCommentStartRE = '' let b:blockCommentMiddleExtra = 2 " Indent another level for each non-closed element tag. let b:indentTrios = [ \ [ '<\w', '', '\%(/>\|XmlIndentAttributeWrap(lnum) let line = line('.') let col = col('.') let adj = 0 try " mover cursor to start of line to avoid matching start tag on first line " of nested content. call cursor(line, 1) let open = search('<\w\| 0 let close = search('>', 'cW') if open != close " continuation line if close == 0 || close >= a:lnum " first continuation line if a:lnum == open + 1 return 1 endif " additional continuation lines return 0 endif " line after last continuation line if close == prevnonblank(a:lnum - 1) " inner content return -1 endif endif endif finally call cursor(line, col) endtry endfunction " }}} " vim:ft=vim:fdm=marker