6

I'm using vim to maintain a weblog of what I do through the day (what commands I used to generate output, etc..), and sometimes I need to copy-paste strings that have special html characters in them. Is there a way to make an "html-paste" mode that will (for instance) convert < to &lt;?

PerilousApricot
  • 633
  • 1
  • 7
  • 19

3 Answers3

7

There are a few small functions here if someone feels like modifying them to accept a range, then provide a mapping which passes the [ and ] marks to act on the last pasted text.


Actually, after looking a bit, you don't need to modify the functions from the vim tip at all. If a function doesn't explicitly pass the range option, the function is called once for each line of the given range. This means that all you need to do is call the function with a range.

A couple useful examples are below. The first calls HtmlEscape() for each line in the last pasted text, the second does the same but for each line in a visually selected block. Add this to your .vimrc:

nnoremap <Leader>h :'[,']call HtmlEscape()<CR>
vnoremap <Leader>h :call HtmlEscape()<CR>

function HtmlEscape()
  silent s/&/\&amp;/eg
  silent s/</\&lt;/eg
  silent s/>/\&gt;/eg
endfunction

Obviously if you want more things replaced you'd have to add them; there are many on the linked wiki page.

Randy Morris
  • 39,631
  • 8
  • 69
  • 76
  • Works great ! Additionally a litte explanation of http://stackoverflow.com/questions/1764263/what-is-the-leader-in-a-vimrc-file – Christian Michael Sep 21 '14 at 08:42
  • Just curious, Why `\&` instead of `&` in the substitution? – rox Aug 15 '16 at 02:33
  • @rox See `:help sub-replace-special`. It all depends on what your vim settings are, but by default `&` gets substituted with the entire matched string. – Randy Morris Aug 15 '16 at 11:46
7

For simple XML encoding I use Tim Pope's unimpaired.vim.

  • [x followed by a motion
  • visually select the text then [x
  • [xx to encode the current line

To encode the just pasted text:

`[[x`]

Explanation:

  • `[ and `] are marks set by the boundaries of a change or a yank. `[ at the beginning and `] at the end.
  • First move to the start of the just pasted text with `[
  • Next execute [x to encode the following motion
  • By using `] the motion will be all the text between the current cursor location to the end of the pasted text.

Optionally you can wrap this up into a mapping

nmap <leader>x `[[x`]

More information:

:h mark-motion
:h `[
Peter Rincker
  • 43,539
  • 9
  • 74
  • 101
3

You can use a mapping that will convert register value and then paste it:

python import xmlrpclib, vim
function! EscapeHTML(str)
    try " Force any error to be an exception "
        let d={}
        python vim.eval("extend(d, {'xml': '"+xmlrpclib.escape(vim.eval("a:str")).replace("'", "''")+"'})")
        return d.xml
    endtry
endfunction
function! s:PasteHTML()
    return "\"=EscapeHTML(getreg(".string(v:register)."))\np"
endfunction
nnoremap <expr> ,p <SID>PasteHTML()

Requires vim with python support and python installed. xmlrpclib packages comes with python. If you don't want python, replace EscapeHTML function. With this script ,p will work just as p except for converting its input.

ZyX
  • 52,536
  • 7
  • 114
  • 135