0

Is there a simple way to surround text, I know about this plugin

But too much keys.

I tried my approach

vmap ' <D-x>i'<esc><D-v>i'
vmap " <D-x>i"<esc><D-v>i"

But this does not work. Anyway if this way is fixed how could I extract this behaviour to a function that allows me this:

  1. I select any text (I think this would be visual mode)
  2. I enter any symbol in a given set for "symmetric" surround (for example ', ", `, |, /, , *, -), or for "asymmetric" surround (for example <>, {}, [], ())
  3. selected text gets surrounded by the symbol.
  4. Maybe would be good to detec if selected word is already surrounded and toggle symbol.

Any recommended reading on how to do this?

sites
  • 21,417
  • 17
  • 87
  • 146

3 Answers3

6

s' and s" are "too much keys"? Really?

Surround is the way to go.

You won't get far with a mapping (and one that uses the Cmd key). If you want a "smart" command that toggles quotes you can't really skip vimscript and, from there, it's probably a better idea to just use Surround which is one of the greatest Vim plugins.

Anyway, this could be a (quick and not thoroughly tested) basis:

function! SurroundWithDoubleQuotes()
  let old_n = @n
  normal! gv
  normal! "nd
  let @n = "\"" . @n . "\""
  normal! "nP
  let @n = old_n
endfunction

You would need to find a way to enter the desired character and test for the presence of that character at both ends of the @n register.

:h functions will definitely help you if you want to go that way.

Here is how I would do with a mapping:

vnoremap " <Esc>`>a"<Esc>`<i"<Esc>

`> marks the end of the visual selection
`< marks its beginning

but be careful with your mappings. In visual mode, (){}[] have meanings that you don't want to overload.

romainl
  • 186,200
  • 21
  • 280
  • 313
3

If you like the surround plugin, but prefer shorter mappings, you can just make your own:

:vmap ' S'
:vmap " S"

(Here, you have to use :vmap over the preferred :vnoremap, because you want the plugin's mappings to apply. Alternatively, you can directly map to the plugin's <Plug> mappings: :vmap ' <Plug>VSurround')

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • With `'VSurround'` you still have to use `vmap`. The only reason why you should prefer this is that when customizing surround mappings you won’t need customizing all other mappings that use surround as well. – ZyX Feb 14 '13 at 18:54
1

This is what I would do:

:vmap ' s''<esc>P
Tassos
  • 3,158
  • 24
  • 29