Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format/prettify xml #29

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions ftplugin/xml.vim
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,59 @@ if !exists("*s:MoveCursor")
endfunction
endif

" XML formatter
if !exists("*s:FormatXML")
function! s:FormatXML() range
" Save the file type
let l:origft = &ft

" Clean the file type
set ft=

" Add fake initial tag (so we can process multiple top-level elements)
exe ":let l:beforeFirstLine=" . a:firstline . "-1"
if l:beforeFirstLine < 0
let l:beforeFirstLine=0
endif
exe a:lastline . "put ='</PrettyXML>'"
exe l:beforeFirstLine . "put ='<PrettyXML>'"
exe ":let l:newLastLine=" . a:lastline . "+2"
if l:newLastLine > line('$')
let l:newLastLine=line('$')
endif

" Remove XML header
exe ":" . a:firstline . "," . a:lastline . "s/<\?xml\\_.*\?>\\_s*//e"

" Recalculate last line of the edited code
let l:newLastLine=search('</PrettyXML>')

" Execute external formatter
exe ":silent " . a:firstline . "," . l:newLastLine . "!xmllint --noblanks --format --recover -"

" Recalculate first and last lines of the edited code
let l:newFirstLine=search('<PrettyXML>')
let l:newLastLine=search('</PrettyXML>')

" Get inner range
let l:innerFirstLine=l:newFirstLine+1
let l:innerLastLine=l:newLastLine-1

" Remove extra unnecessary indentation
exe ":silent " . l:innerFirstLine . "," . l:innerLastLine "s/^ //e"

" Remove fake tag
exe l:newLastLine . "d"
exe l:newFirstLine . "d"

" Put the cursor at the first line of the edited code
exe ":" . l:newFirstLine

" Restore the file type
exe "set ft=" . l:origft
endfunction
endif

" Mappings and Settings. {{{1
" This makes the '%' jump between the start and end of a single tag.
setlocal matchpairs+=<:>
Expand Down Expand Up @@ -599,6 +652,10 @@ nnoremap <buffer> <LocalLeader>w :call <SID>ClearJumpMarks()<Cr>
" The syntax files clear out any predefined syntax definitions. Recreate
" this when ever a xml_jump_string is created. (in ParseTag)

" Format XML
nnoremap <buffer> <LocalLeader>x :call <SID>FormatXML()<Cr>
vnoremap <buffer> <LocalLeader>x <Esc>:call <SID>FormatXML()<Cr>

augroup xml
au!
au BufNewFile * call <SID>NewFileXML()
Expand Down