comparison runtime/autoload/xmlformat.vim @ 18456:6d11fc4aa683

Update runtime files Commit: https://github.com/vim/vim/commit/96f45c0b6fc9e9d404e6805593ed1e0e6795e470 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Oct 26 19:53:45 2019 +0200 Update runtime files
author Bram Moolenaar <Bram@vim.org>
date Sat, 26 Oct 2019 20:00:04 +0200
parents bc1a8d21c811
children d4deb2e50667
comparison
equal deleted inserted replaced
18455:3c98dfd2380c 18456:6d11fc4aa683
1 " Vim plugin for formatting XML 1 " Vim plugin for formatting XML
2 " Last Change: Thu, 07 Dec 2018 2 " Last Change: 2019 Oct 24
3 " Version: 0.1 3 " Version: 0.2
4 " Author: Christian Brabandt <cb@256bit.org> 4 " Author: Christian Brabandt <cb@256bit.org>
5 " Repository: https://github.com/chrisbra/vim-xml-ftplugin 5 " Repository: https://github.com/chrisbra/vim-xml-ftplugin
6 " License: VIM License 6 " License: VIM License
7 " Documentation: see :h xmlformat.txt (TODO!) 7 " Documentation: see :h xmlformat.txt (TODO!)
8 " --------------------------------------------------------------------- 8 " ---------------------------------------------------------------------
20 " (e.g. Vim is in normal mode) 20 " (e.g. Vim is in normal mode)
21 if mode() != 'n' 21 if mode() != 'n'
22 " do not fall back to internal formatting 22 " do not fall back to internal formatting
23 return 0 23 return 0
24 endif 24 endif
25 let count_orig = v:count
25 let sw = shiftwidth() 26 let sw = shiftwidth()
26 let prev = prevnonblank(v:lnum-1) 27 let prev = prevnonblank(v:lnum-1)
27 let s:indent = indent(prev)/sw 28 let s:indent = indent(prev)/sw
28 let result = [] 29 let result = []
29 let lastitem = prev ? getline(prev) : '' 30 let lastitem = prev ? getline(prev) : ''
30 let is_xml_decl = 0 31 let is_xml_decl = 0
31 " split on `<`, but don't split on very first opening < 32 " go through every line, but don't join all content together and join it
32 for item in split(join(getline(v:lnum, (v:lnum + v:count - 1))), '.\@<=[>]\zs') 33 " back. We might lose empty lines
33 if s:EndTag(item) 34 let list = getline(v:lnum, (v:lnum + count_orig - 1))
34 let s:indent = s:DecreaseIndent() 35 let current = 0
35 call add(result, s:Indent(item)) 36 for line in list
36 elseif s:EmptyTag(lastitem) 37 " Keep empty input lines?
37 call add(result, s:Indent(item)) 38 if empty(line)
38 elseif s:StartTag(lastitem) && s:IsTag(item) 39 call add(result, '')
39 let s:indent += 1 40 continue
40 call add(result, s:Indent(item)) 41 elseif line !~# '<[/]\?[^>]*>'
41 else 42 let nextmatch = match(list, '<[/]\?[^>]*>', current)
42 if !s:IsTag(item) 43 let line .= join(list[(current + 1):(nextmatch-1)], "\n")
43 " Simply split on '<' 44 call remove(list, current+1, nextmatch-1)
44 let t=split(item, '.<\@=\zs') 45 endif
45 let s:indent+=1 46 " split on `>`, but don't split on very first opening <
46 call add(result, s:Indent(t[0])) 47 " this means, items can be like ['<tag>', 'tag content</tag>']
47 let s:indent = s:DecreaseIndent() 48 for item in split(line, '.\@<=[>]\zs')
48 call add(result, s:Indent(t[1])) 49 if s:EndTag(item)
49 else 50 let s:indent = s:DecreaseIndent()
50 call add(result, s:Indent(item)) 51 call add(result, s:Indent(item))
52 elseif s:EmptyTag(lastitem)
53 call add(result, s:Indent(item))
54 elseif s:StartTag(lastitem) && s:IsTag(item)
55 let s:indent += 1
56 call add(result, s:Indent(item))
57 else
58 if !s:IsTag(item)
59 " Simply split on '<', if there is one,
60 " but reformat according to &textwidth
61 let t=split(item, '.<\@=\zs')
62 " t should only contain 2 items, but just be safe here
63 if s:IsTag(lastitem)
64 let s:indent+=1
65 endif
66 let result+=s:FormatContent([t[0]])
67 if s:EndTag(t[1])
68 let s:indent = s:DecreaseIndent()
69 endif
70 "for y in t[1:]
71 let result+=s:FormatContent(t[1:])
72 "endfor
73 else
74 call add(result, s:Indent(item))
75 endif
51 endif 76 endif
52 endif 77 let lastitem = item
53 let lastitem = item 78 endfor
54 endfor 79 let current += 1
80 endfor
55 81
56 if !empty(result) 82 if !empty(result)
57 exe v:lnum. ",". (v:lnum + v:count - 1). 'd' 83 let lastprevline = getline(v:lnum + count_orig)
84 let delete_lastline = v:lnum + count_orig - 1 == line('$')
85 exe v:lnum. ",". (v:lnum + count_orig - 1). 'd'
58 call append(v:lnum - 1, result) 86 call append(v:lnum - 1, result)
59 " Might need to remove the last line, if it became empty because of the 87 " Might need to remove the last line, if it became empty because of the
60 " append() call 88 " append() call
61 let last = v:lnum + len(result) 89 let last = v:lnum + len(result)
62 if getline(last) is '' 90 " do not use empty(), it returns true for `empty(0)`
91 if getline(last) is '' && lastprevline is '' && delete_lastline
63 exe last. 'd' 92 exe last. 'd'
64 endif 93 endif
65 endif 94 endif
66 95
67 " do not run internal formatter! 96 " do not run internal formatter!
86 " Check if tag is a new opening tag <tag> {{{1 115 " Check if tag is a new opening tag <tag> {{{1
87 func! s:StartTag(tag) 116 func! s:StartTag(tag)
88 let is_comment = s:IsComment(a:tag) 117 let is_comment = s:IsComment(a:tag)
89 return a:tag =~? '^\s*<[^/?]' && !is_comment 118 return a:tag =~? '^\s*<[^/?]' && !is_comment
90 endfunc 119 endfunc
120 " Check if tag is a Comment start {{{1
91 func! s:IsComment(tag) 121 func! s:IsComment(tag)
92 return a:tag =~? '<!--' 122 return a:tag =~? '<!--'
93 endfunc 123 endfunc
94 " Remove one level of indentation {{{1 124 " Remove one level of indentation {{{1
95 func! s:DecreaseIndent() 125 func! s:DecreaseIndent()
106 endfunc 136 endfunc
107 " Check if tag is empty <tag/> {{{1 137 " Check if tag is empty <tag/> {{{1
108 func! s:EmptyTag(tag) 138 func! s:EmptyTag(tag)
109 return a:tag =~ '/>\s*$' 139 return a:tag =~ '/>\s*$'
110 endfunc 140 endfunc
141 " Format input line according to textwidth {{{1
142 func! s:FormatContent(list)
143 let result=[]
144 let limit = 80
145 if &textwidth > 0
146 let limit = &textwidth
147 endif
148 let column=0
149 let idx = -1
150 let add_indent = 0
151 let cnt = 0
152 for item in a:list
153 for word in split(item, '\s\+\S\+\zs')
154 let column += strdisplaywidth(word, column)
155 if match(word, "^\\s*\n\\+\\s*$") > -1
156 call add(result, '')
157 let idx += 1
158 let column = 0
159 let add_indent = 1
160 elseif column > limit || cnt == 0
161 let add = s:Indent(s:Trim(word))
162 call add(result, add)
163 let column = strdisplaywidth(add)
164 let idx += 1
165 else
166 if add_indent
167 let result[idx] = s:Indent(s:Trim(word))
168 else
169 let result[idx] .= ' '. s:Trim(word)
170 endif
171 let add_indent = 0
172 endif
173 let cnt += 1
174 endfor
175 endfor
176 return result
177 endfunc
111 " Restoration And Modelines: {{{1 178 " Restoration And Modelines: {{{1
112 let &cpo= s:keepcpo 179 let &cpo= s:keepcpo
113 unlet s:keepcpo 180 unlet s:keepcpo
114 " Modeline {{{1 181 " Modeline {{{1
115 " vim: fdm=marker fdl=0 ts=2 et sw=0 sts=-1 182 " vim: fdm=marker fdl=0 ts=2 et sw=0 sts=-1