diff runtime/autoload/xmlformat.vim @ 19574:d4deb2e50667

Update runtime files Commit: https://github.com/vim/vim/commit/eab6dff19f387469a200011bc6cf3508f5e43a4a Author: Bram Moolenaar <Bram@vim.org> Date: Sun Mar 1 19:06:45 2020 +0100 Update runtime files
author Bram Moolenaar <Bram@vim.org>
date Sun, 01 Mar 2020 19:15:04 +0100
parents 6d11fc4aa683
children
line wrap: on
line diff
--- a/runtime/autoload/xmlformat.vim
+++ b/runtime/autoload/xmlformat.vim
@@ -1,6 +1,6 @@
 " Vim plugin for formatting XML
-" Last Change: 2019 Oct 24
-"     Version: 0.2
+" Last Change: 2020 Jan 06
+"     Version: 0.3
 "      Author: Christian Brabandt <cb@256bit.org>
 "  Repository: https://github.com/chrisbra/vim-xml-ftplugin
 "     License: VIM License
@@ -15,7 +15,7 @@ let s:keepcpo       = &cpo
 set cpo&vim
 
 " Main function: Format the input {{{1
-func! xmlformat#Format()
+func! xmlformat#Format() abort
   " only allow reformatting through the gq command
   " (e.g. Vim is in normal mode)
   if mode() != 'n'
@@ -40,14 +40,16 @@ func! xmlformat#Format()
       continue
     elseif line !~# '<[/]\?[^>]*>'
       let nextmatch = match(list, '<[/]\?[^>]*>', current)
-      let line .= join(list[(current + 1):(nextmatch-1)], "\n")
-      call remove(list, current+1, nextmatch-1)
+      if nextmatch > -1 
+        let line .= ' '. join(list[(current + 1):(nextmatch-1)], " ")
+        call remove(list, current+1, nextmatch-1)
+      endif
     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)
-        let s:indent = s:DecreaseIndent()
+        call s:DecreaseIndent()
         call add(result, s:Indent(item))
       elseif s:EmptyTag(lastitem)
         call add(result, s:Indent(item))
@@ -59,13 +61,23 @@ func! xmlformat#Format()
           " Simply split on '<', if there is one,
           " but reformat according to &textwidth
           let t=split(item, '.<\@=\zs')
+
+          " if the content fits well within a single line, add it there
+          " so that the output looks like this:
+          "
+          " <foobar>1</foobar>
+          if s:TagContent(lastitem) is# s:TagContent(t[1]) && strlen(result[-1]) + strlen(item) <= s:Textwidth()
+            let result[-1] .= item
+            let lastitem = t[1]
+            continue
+          endif
           " t should only contain 2 items, but just be safe here
           if s:IsTag(lastitem)
             let s:indent+=1
           endif
           let result+=s:FormatContent([t[0]])
           if s:EndTag(t[1])
-            let s:indent = s:DecreaseIndent()
+            call s:DecreaseIndent()
           endif
           "for y in t[1:]
             let result+=s:FormatContent(t[1:])
@@ -97,15 +109,15 @@ func! xmlformat#Format()
   return 0
 endfunc
 " Check if given tag is XML Declaration header {{{1
-func! s:IsXMLDecl(tag)
+func! s:IsXMLDecl(tag) abort
   return a:tag =~? '^\s*<?xml\s\?\%(version="[^"]*"\)\?\s\?\%(encoding="[^"]*"\)\? ?>\s*$'
 endfunc
 " Return tag indented by current level {{{1
-func! s:Indent(item)
+func! s:Indent(item) abort
   return repeat(' ', shiftwidth()*s:indent). s:Trim(a:item)
 endfu
 " Return item trimmed from leading whitespace {{{1
-func! s:Trim(item)
+func! s:Trim(item) abort
   if exists('*trim')
     return trim(a:item)
   else
@@ -113,44 +125,53 @@ func! s:Trim(item)
   endif
 endfunc
 " Check if tag is a new opening tag <tag> {{{1
-func! s:StartTag(tag)
+func! s:StartTag(tag) abort
   let is_comment = s:IsComment(a:tag)
   return a:tag =~? '^\s*<[^/?]' && !is_comment
 endfunc
 " Check if tag is a Comment start {{{1
-func! s:IsComment(tag)
+func! s:IsComment(tag) abort
   return a:tag =~? '<!--'
 endfunc
 " Remove one level of indentation {{{1
-func! s:DecreaseIndent()
-  return (s:indent > 0 ? s:indent - 1 : 0)
+func! s:DecreaseIndent() abort
+  let s:indent = (s:indent > 0 ? s:indent - 1 : 0)
 endfunc
 " Check if tag is a closing tag </tag> {{{1
-func! s:EndTag(tag)
+func! s:EndTag(tag) abort
   return a:tag =~? '^\s*</'
 endfunc
 " Check that the tag is actually a tag and not {{{1
 " something like "foobar</foobar>"
-func! s:IsTag(tag)
+func! s:IsTag(tag) abort
   return s:Trim(a:tag)[0] == '<'
 endfunc
 " Check if tag is empty <tag/> {{{1
-func! s:EmptyTag(tag)
+func! s:EmptyTag(tag) abort
   return a:tag =~ '/>\s*$'
 endfunc
+func! s:TagContent(tag) abort "{{{1
+  " Return content of a tag
+  return substitute(a:tag, '^\s*<[/]\?\([^>]*\)>\s*$', '\1', '')
+endfunc
+func! s:Textwidth() abort "{{{1
+  " return textwidth (or 80 if not set)
+  return &textwidth == 0 ? 80 : &textwidth
+endfunc
 " Format input line according to textwidth {{{1
-func! s:FormatContent(list)
+func! s:FormatContent(list) abort
   let result=[]
-  let limit = 80
-  if &textwidth > 0
-    let limit = &textwidth
-  endif
+  let limit = s:Textwidth()
   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') 
+      if match(word, '^\s\+$') > -1
+        " skip empty words
+        continue
+      endif
       let column += strdisplaywidth(word, column)
       if match(word, "^\\s*\n\\+\\s*$") > -1
         call add(result, '')