xmlformat.vim: patch runtime/autoload to 96f45c0b6

vim/vim@96f45c0b6f
This commit is contained in:
adrian5
2020-11-22 18:00:23 +01:00
parent 978857e0c2
commit 67612b1766

View File

@@ -1,6 +1,6 @@
" Vim plugin for formatting XML " Vim plugin for formatting XML
" Last Change: Thu, 07 Dec 2018 " Last Change: 2019 Oct 24
" Version: 0.1 " Version: 0.2
" Author: Christian Brabandt <cb@256bit.org> " Author: Christian Brabandt <cb@256bit.org>
" Repository: https://github.com/chrisbra/vim-xml-ftplugin " Repository: https://github.com/chrisbra/vim-xml-ftplugin
" License: VIM License " License: VIM License
@@ -22,14 +22,30 @@ func! xmlformat#Format()
" do not fall back to internal formatting " do not fall back to internal formatting
return 0 return 0
endif endif
let count_orig = v:count
let sw = shiftwidth() let sw = shiftwidth()
let prev = prevnonblank(v:lnum-1) let prev = prevnonblank(v:lnum-1)
let s:indent = indent(prev)/sw let s:indent = indent(prev)/sw
let result = [] let result = []
let lastitem = prev ? getline(prev) : '' let lastitem = prev ? getline(prev) : ''
let is_xml_decl = 0 let is_xml_decl = 0
" split on `<`, but don't split on very first opening < " go through every line, but don't join all content together and join it
for item in split(join(getline(v:lnum, (v:lnum + v:count - 1))), '.\@<=[>]\zs') " back. We might lose empty lines
let list = getline(v:lnum, (v:lnum + count_orig - 1))
let current = 0
for line in list
" Keep empty input lines?
if empty(line)
call add(result, '')
continue
elseif line !~# '<[/]\?[^>]*>'
let nextmatch = match(list, '<[/]\?[^>]*>', current)
let line .= join(list[(current + 1):(nextmatch-1)], "\n")
call remove(list, current+1, nextmatch-1)
endif
" split on `>`, but don't split on very first opening <
" this means, items can be like ['<tag>', 'tag content</tag>']
for item in split(line, '.\@<=[>]\zs')
if s:EndTag(item) if s:EndTag(item)
let s:indent = s:DecreaseIndent() let s:indent = s:DecreaseIndent()
call add(result, s:Indent(item)) call add(result, s:Indent(item))
@@ -40,26 +56,39 @@ func! xmlformat#Format()
call add(result, s:Indent(item)) call add(result, s:Indent(item))
else else
if !s:IsTag(item) if !s:IsTag(item)
" Simply split on '<' " Simply split on '<', if there is one,
" but reformat according to &textwidth
let t=split(item, '.<\@=\zs') let t=split(item, '.<\@=\zs')
" t should only contain 2 items, but just be safe here
if s:IsTag(lastitem)
let s:indent+=1 let s:indent+=1
call add(result, s:Indent(t[0])) endif
let result+=s:FormatContent([t[0]])
if s:EndTag(t[1])
let s:indent = s:DecreaseIndent() let s:indent = s:DecreaseIndent()
call add(result, s:Indent(t[1])) endif
"for y in t[1:]
let result+=s:FormatContent(t[1:])
"endfor
else else
call add(result, s:Indent(item)) call add(result, s:Indent(item))
endif endif
endif endif
let lastitem = item let lastitem = item
endfor endfor
let current += 1
endfor
if !empty(result) if !empty(result)
exe v:lnum. ",". (v:lnum + v:count - 1). 'd' 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'
call append(v:lnum - 1, result) call append(v:lnum - 1, result)
" Might need to remove the last line, if it became empty because of the " Might need to remove the last line, if it became empty because of the
" append() call " append() call
let last = v:lnum + len(result) let last = v:lnum + len(result)
if getline(last) is '' " do not use empty(), it returns true for `empty(0)`
if getline(last) is '' && lastprevline is '' && delete_lastline
exe last. 'd' exe last. 'd'
endif endif
endif endif
@@ -88,6 +117,7 @@ func! s:StartTag(tag)
let is_comment = s:IsComment(a:tag) let is_comment = s:IsComment(a:tag)
return a:tag =~? '^\s*<[^/?]' && !is_comment return a:tag =~? '^\s*<[^/?]' && !is_comment
endfunc endfunc
" Check if tag is a Comment start {{{1
func! s:IsComment(tag) func! s:IsComment(tag)
return a:tag =~? '<!--' return a:tag =~? '<!--'
endfunc endfunc
@@ -108,6 +138,43 @@ endfunc
func! s:EmptyTag(tag) func! s:EmptyTag(tag)
return a:tag =~ '/>\s*$' return a:tag =~ '/>\s*$'
endfunc endfunc
" Format input line according to textwidth {{{1
func! s:FormatContent(list)
let result=[]
let limit = 80
if &textwidth > 0
let limit = &textwidth
endif
let column=0
let idx = -1
let add_indent = 0
let cnt = 0
for item in a:list
for word in split(item, '\s\+\S\+\zs')
let column += strdisplaywidth(word, column)
if match(word, "^\\s*\n\\+\\s*$") > -1
call add(result, '')
let idx += 1
let column = 0
let add_indent = 1
elseif column > limit || cnt == 0
let add = s:Indent(s:Trim(word))
call add(result, add)
let column = strdisplaywidth(add)
let idx += 1
else
if add_indent
let result[idx] = s:Indent(s:Trim(word))
else
let result[idx] .= ' '. s:Trim(word)
endif
let add_indent = 0
endif
let cnt += 1
endfor
endfor
return result
endfunc
" Restoration And Modelines: {{{1 " Restoration And Modelines: {{{1
let &cpo= s:keepcpo let &cpo= s:keepcpo
unlet s:keepcpo unlet s:keepcpo