vim-sandwich not surround.vim
Time
and
time
again people praise surround.vim for
what it can do. I don’t think this is out of any sort of evangelism, just that
they’re unaware of the alternatives offered ¹.
vim-sandwich is our alternative in
this case. It boasts the feature set of surround.vim and more!
Why vim-sandwich?
1) Can operate on all text-objects and motions
Whereas surround.vim can operate on a few motions (w
, W
, s
) on targets,
vim-sandwich correctly operates on the entire vim vocabulary and can also take a
count. Doing sa2}"
will surround the next two paragraphs in double quotes for
example.
This is by far the biggest advantage vim-sandwich has over surround.vim. Read
the
docs
(:help sandwich.txt
) or better yet, install it and see for yourself.
2) Well tested
Seriously, look at the amount of
tests this thing
has. Regressions in code are very hard to make happen in well tested code.
3) Is repeatable with ‘.’ without an extra plugin
surround.vim is repeatable however it relies on tpope’s repeat.vim plugin being
installed, vim-sandwich has built-in support for repeatability.
4) Has a generic ‘b’ mapping, to target the outer block
Instead of being specific and having to say sr'"
to replace single quotes with
double quotes, we can use b
which means “the outer block”. sr'"
then becomes
srb"
. I know it doesn’t seem like a big deal but you’ll quickly find this
slipping into your day-to-day use of vim-sandwich. surround.vim has something
similar though not as generic, b
stands for (
, B
, stands for {
.
5) Does HTML/XML tags in a nice way
The t
command after a motion or text object tells vim-sandwich that you want
to add a tag. At that point, it will bring a prompt up and you can enter
whatever you want.
To surround a paragraph in p
tags you would do sa}tp
(and of course you
could delete these with sdb
).
You can also add HTML attributes. For example if we have:
Some text here
and do (assuming the cursor is at beginning of the line)
sa$tdiv.body#main-content
then we get
<div class="body" id="main-content">Some text here</div>
6) Visual feedback
When using vim-sandwich, there is unobtrusive visual feedback every step of the
way. sr'"
will highlight the single quotes until you have pressed the
replacement character. sa}tp
will highlight the paragraph ({
) until you have
added in the rest of your command. Having this available makes me much less
clumsy and more confident in what I’m doing.
7) Your own surroundings
If that’s not enough, vim-sandwich boasts a thing called ‘recipes’ which are
your own surroundings that you can write in vimscript. I’ve never dug this far
in, my needs are quite basic but some users may find this useful.
8) A whole lot more
There’s a load of other stuff in the documentation I’ve omitted that I recommend
reading (:help sandwich.txt
).
Why surround.vim?
After all that, why should you stick with surround?
One of the biggest issues with vim-sandwich is that it messes with the s
substitute binding, I never used this anyway so I don’t miss it. Apart from
that, I would say surround.vim has more intuitive mappings but the author of
vim-sandwich has made this possible
anyway.
A syntax comparison
Changing ‘ to “
# surround.vim
cs'"
# vim-sandwich
sr'"
or
srb"
Surrounding something with tags
# surround.vim
ysiw<em>
# vim-sandwich
saiwtem
Deleting surrounding quotes
# surround.vim
ds"
# vim-sandwich
sd"
or
sdb
You failed to mention [X] and that surround.vim can do [Y]
Cool, bring it up in this
thread
and I’ll update this section.
It looks cool, but a little intimidating with all those options (yes I realise
what subreddit I’m in). Just tried it, don’t dig the highlighting thingy and it
doesn’t seem to be optional. I’ll try to hack it off.
You can turn it off with:
operator#sandwich#set('all', 'all', 'highlight', 0)
It mentions it messes with the s key for substitute but vim-sneak also uses s
and I personally couldn’t make that trade.
In your case you have two options:
1) vim-sneak allows you to specify a different mapping
2) vim-sandwich also allows different mappings. Have a read of the docs. They
will allow you to use surround.vim mappings but also leverage the features of
vim-sandwich
I don’t use it because it substitutes some of vim’s default motions. I don’t
like that kind of plugin.
In that case you can use vim-sandwich with surround.vim keymappings. add the
following line to your vimrc:
runtime macros/sandwich/keymap/surround.vim
vim-sandwich looks great, and I’d be curious to try it, but it doesn’t seem to
support one particular feature of vim-surround that I use quite often: With
vim-surround, you can change hello to {hello} with csiw}
, or change it to {
hello } with csiw{
. I could be wrong about vim-sandwich not supporting this,
but I couldn’t find anything about it in the repo.
User /u/vimdiesel gave this link
which addresses the issue.
Surround does that, too [HTML/XML tags in a nice way], and in a more semantic
way, IMO: ysip<p<CR>, optionally letting you add attributes and stuff.
You can add HTML attributes through vim-sandwich too, for example
If we have:
Some text here
and do (assuming the cursor is at beginning of the line)
sa$tdiv.body#main-content
then we get
<div class="body" id="main-content">Some text here</div>
Just because it’s the most popular doesn’t mean it’s the best choice
There are many great smaller vim plugins around and unfortunately, you really
have to search for them. A lot of the time they trump the competition but the
competition got there first and/or already have a name for themselves.
I’d always suggest looking around for the plugin you want instead of settling on
the plugin that’s offered, it’s not always the best choice.
References & Footnotes
surround.vim
vim-sandwich
¹ I too have felt the pain of the tpope monopoly when
dadbod crushed my sql plugin’s
popularity :(