" Vim plugin for formatting XML
-" Last Change: 2020 Jan 06
+" Last Change: 2023 March 15th
" Version: 0.3
" Author: Christian Brabandt <cb@256bit.org>
" Repository: https://github.com/chrisbra/vim-xml-ftplugin
" Keep empty input lines?
if empty(line)
call add(result, '')
+ let current += 1
continue
elseif line !~# '<[/]\?[^>]*>'
- let nextmatch = match(list, '<[/]\?[^>]*>', current)
- if nextmatch > -1
- let line .= ' '. join(list[(current + 1):(nextmatch-1)], " ")
- call remove(list, current+1, nextmatch-1)
+ let nextmatch = match(list, '^\s*$\|<[/]\?[^>]*>', current)
+ if nextmatch > -1
+ let lineEnd = nextmatch
+ else
+ let lineEnd = len(list)
endif
+ let line .= ' '. join(list[(current + 1):(lineEnd-1)], " ")
+ call remove(list, current+1, lineEnd-1)
endif
" split on `>`, but don't split on very first opening <
" this means, items can be like ['<tag>', 'tag content</tag>']
if s:EndTag(t[1])
call s:DecreaseIndent()
endif
- "for y in t[1:]
- let result+=s:FormatContent(t[1:])
- "endfor
+ let result+=s:FormatContent(t[1:])
+ if s:IsTag(t[1])
+ let lastitem = t[1]
+ continue
+ endif
+ elseif s:IsComment(item)
+ let result+=s:FormatContent([item])
else
call add(result, s:Indent(item))
endif
if !empty(result)
let lastprevline = getline(v:lnum + count_orig)
let delete_lastline = v:lnum + count_orig - 1 == line('$')
- exe v:lnum. ",". (v:lnum + count_orig - 1). 'd'
+ exe 'silent ' .. v:lnum. ",". (v:lnum + count_orig - 1). 'd'
call append(v:lnum - 1, result)
" Might need to remove the last line, if it became empty because of the
" append() call
" Vim filetype plugin file
" Language: xml
" Maintainer: Christian Brabandt <cb@256bit.org>
-" Last Changed: Dec 07th, 2018
-" 2024 Jan 14 by Vim Project (browsefilter)
-" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
-" Repository: https://github.com/chrisbra/vim-xml-ftplugin
-" Previous Maintainer: Dan Sharp
-" URL: http://dwsharp.users.sourceforge.net/vim/ftplugin
+" Last Changed: 2024 May 24
+" Repository: https://github.com/chrisbra/vim-xml-ftplugin
+" Previously
+" Maintainer: Dan Sharp <dwsharp at users dot sourceforge dot net>
+" URL: http://dwsharp.users.sourceforge.net/vim/ftplugin
if exists("b:did_ftplugin") | finish | endif
let b:did_ftplugin = 1
if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
let b:browsefilter="XML Files (*.xml)\t*.xml\n" .
\ "DTD Files (*.dtd)\t*.dtd\n" .
- \ "XSD Files (*.xsd)\t*.xsd\n"
- if has("win32")
- let b:browsefilter .= "All Files (*.*)\t*\n"
- else
- let b:browsefilter .= "All Files (*)\t*\n"
- endif
+ \ "XSD Files (*.xsd)\t*.xsd\n" .
+ \ "All Files (*.*)\t*.*\n"
endif
" Undo the stuff we changed.
" [-- return the sum of indents of a:lnum --]
fun! <SID>XmlIndentSum(line, style, add)
- if <SID>IsXMLContinuation(a:line) && a:style == 0 && !<SID>IsXMLEmptyClosingTag(a:line)
+ if <SID>IsXMLContinuation(a:line) &&
+ \ a:style == 0 &&
+ \ !<SID>IsXMLEmptyClosingTag(a:line)
" no complete tag, add one additional indent level
" but only for the current line
return a:add + shiftwidth()
" no extra indent, looks like a text continuation line
return pind
endif
+ elseif empty(syn_name_start) && syn_name_end =~? 'xmlTag'
+ " Special case: such a line, shouldn't be indented, just because it
+ " ends with a tag
+ " 'foobar <i>inline tags</i>'
+ if (match(curline, '<\([:a-zA-Z_]\+\)[^>]*>.*</\1>') > -1)
+ return pind
+ endif
+ endif
+
+ if curline =~ '^\s*</[a-zA-Z_]>'
+ return <SID>ReturnIndentForMatchingTag(curline)
endif
" Get indent from previous tag line
return a:line =~? '<[^>]*/>\s*$'
endfunc
+func! <SID>ReturnIndentForMatchingTag(line)
+ " For a line with just a simple closing tag
+ " get the indent from a matching opening tag
+ if a:line =~? '^\s*</[a-z_]*>'
+ let _c = getcursorpos()
+ let pat = matchstr(a:line, '^\s*</\zs[a-z_]\+\ze>')
+ " position cursor before the opening tag
+ norm! 0
+ " get the indent from the matching opening tag
+ let match_line = searchpair('<' .. pat .. '>', '', '</' .. pat .. '>', 'bn')
+ call setpos('.', _c)
+ return indent(match_line)
+ endif
+endfunc
+
" return indent for a commented line,
" the middle part might be indented one additional level
func! <SID>XmlIndentComment(lnum)