vim-sandwich vs. vim-surround

January 07, 2019

I was reading a thread on /r/vim and encountered a name I hadn’t seen before… vim-sandwich. I have been a long-time user of vim-surround, and was curious whether this was an heir apparent… we shall see.

It seems like sandwich is some fanciness on top of surround, suitable for those who really want to tweak or have a problem with surround’s defaults.

Here are some scattered thoughts from playing with it and reading the docs.

What I like:

Highlights and UI

Here I show a couple highlights as I decide what I need to delete.

This is something I didn’t know I needed… but it is rather wonderful. Many times while working with surround in a nested function, I’ll inadvertently grab the wrong level or delete too far because a parentheses is unmatched. Having the little search-highlight appear as I’m working on it reminds me of what I’ve seen of kakoune, and feels natural without being unobtrusive.

Insert Mode

Using the insert magic char, I’m able to convert these keyword lists to maps!

While in the keyword list, I can press srbi%{<CR>}<CR>.

The “insert mode” replacement… I can use this for a short-hand change a keyword list to a map in elixir… and it is repeatable by the . operator!

That’s pretty neat!

Similar Interface

Just like vim-surround, vim-sandwich provides some “magic” commands like f for function and t for tag.

I thought that surround allows for the jumping to the next match which I have become accustomed… but it turns out that’s part of targets.vim and is still present without surround. :P It’s just that the interfaced used by vim-surround is consistent with targets.vim.

Extensibility: text-objects, file-types, surroundings…

If the above use case is something I do often, I could define a new recipe with a magic character specific to the elixir filetype… that’s pretty neat. I could even define a superset of { that was able to delete the leading “%” if it existed…

vim-sandwich provides a lot of functionality for creating “sandwich recipes”, almost crazy levels of customization, allowing you to create or tweak how sandwich handles spaces, evaluates the context of the surround, etc.

What I don’t like:

New Interface

I’ve been using vim-surround for nearly half a decade… It’s going to be hard to try something new. The author of vim-sandwich provides a configuration that follows the old vim-surround bindings, which does go to show how customizable this plugin is.

In addition, I was used to surround allowing for out of the box selection between (foo) and ( foo ). It’s nice… but in sandwich’s defense I almost always want the former and not the latter. If you want to add this, there are directions in the wiki.

Docs are nice, but community is new

It’s just a factor of the new-ness of the plugin, but searching for “vim surround” on stack overflow yields 400+ results, and “vim sandwich” yields 4.

The actual docs on github are nice and complete, but a little difficult if you don’t speak vimscript that well.

No Nice Ruby-ish defaults

Combined with ragtag.vim, vim-surround provides some nice defaults. I think I may miss those… but we will see. You could absolutely manually create some filetype specific sandwich recipes for these, but as a user who just wants to work on ruby/elixir templates, it’s a little sad.

(Full disclosure… while I did use the ragtag bindings to create those surround objects, I didn’t till just now know about the corresponding surround objects… but now that I know they exist, I want them.)


Using `srff` I can rename a function from wherever my cursor is…

I don’t mind the change, I’m going to keep at it for a week or two. If you see my dotfiles switch back… don’t be surprised, but I think I’m encouraged enough to give this a go, especially by the power of being able to change a function from anywhere in an elixir pattern match.


  • 2019-01-07 13:46:41 -0600

    Add mention of neat function rename

  • 2019-01-07 11:38:36 -0600

    Article: vim-sandwich vs. vim-surround