0

I would like to map F5 to format the current buffer using xmllint --format and return to the same line. It's easy to do just the formatting.

autocmd FileType xml map <F5> :w<CR>:silent %!xmllint --format -<CR>

I played around with returning to the same line for a while, and from the below snipped it should be obvious I don't know what I'm doing (doesn't work at all).

fun! XmlFormat()
  let @`\" = line(".")
  w<CR>
  silent %!xmllint --format -<CR>
  normal! g`\"
endfun
autocmd FileType xml map <F5> :call XmlFormat()<CR>

Do I need to store the present line in a buffer, or can I use a variable? How can I execute an external command within a function? Lastly, what's the best way to jump to a line number that is stored in a variable?

ib.
  • 27,830
  • 11
  • 80
  • 100
schmmd
  • 18,650
  • 16
  • 58
  • 102
  • Rather than using xmllint, which squeezes blank newlines, I would suggest trying the [vim-sensible](https://github.com/tpope/vim-sensible) settings, which make equals (=) work out of the box to indent XML. See also http://stackoverflow.com/a/28365920/1207769 – ctrueden Feb 06 '15 at 12:35

1 Answers1

4

You could use a mapping like:

nnoremap <f5> mmgg=G`m

It uses a mark motion and the = filter command. You could use xmllint setting the equalprg option. I wrote an article about this mapping here if you want a more detailed description.

lucapette
  • 20,564
  • 6
  • 65
  • 59
  • You don't need `map` here, you need `nnoremap`. – ZyX Oct 28 '11 at 18:28
  • 3
    One can take advantage of the fact that Vim automatically saves the position before the latest jump, to simplify the command and avoid modification of marks: `:nnoremap gg=G\`\``. – ib. Oct 29 '11 at 01:24
  • @ib oh yes. I love vim for that. I learn at least one thing a day – lucapette Oct 29 '11 at 07:42