Vsvim: Consider implementing tpope/vim-surround

Created on 29 Oct 2014  Â·  26Comments  Â·  Source: VsVim/VsVim

This plugin tpope/surround is as about as standard as the rest of vim at this point.

Will personally buy the implementor a beer (or 6) :beer:

vim plugin

Most helpful comment

I'd like surround as a builtin too, but the above bindings are a pretty good substitute. The only real short-coming is where branching or other logic is required. I modified the above a little to increase your options, to simplify the delete bindings, and to add a visual tag-surround to match the tag text object. I also switched the brace direction since I used the other variant in Surround, here's my version:

" Surround simulating bindings
nnoremap s) ciw(<C-r>")<Esc>
nnoremap s] ciw[<C-r>"]<Esc>
nnoremap s} ciw{<C-r>"}<Esc>
nnoremap s> ciw<lt><C-r>"><Esc>
nnoremap s" ciw"<C-r>""<Esc>
nnoremap s' ciw'<C-r>"'<Esc>
nnoremap sw) ciW(<C-r>")<Esc>
nnoremap sw] ciW[<C-r>"]<Esc>
nnoremap sw} ciW{<C-r>"}<Esc>
nnoremap sw> ciW<lt><C-r>"><Esc>
nnoremap sw" ciW"<C-r>""<Esc>
nnoremap sw' ciW'<C-r>"'<Esc>

" Surround delete bindings
nnoremap ds) vi(dvhp
nnoremap ds] vi[dvhp
nnoremap ds} vi{dvhp
nnoremap ds> vi<dvhp
nnoremap ds" vi"dvhp
nnoremap ds' vi'dvhp

" Surround change bindings
nnoremap cs"' vi"oh<Esc>msvi"l<Esc>cl'<Esc>`scl'<Esc>
nnoremap cs'" vi'oh<Esc>msvi'l<Esc>cl"<Esc>`scl"<Esc>

" Surround visual selected text
vnoremap S" c"<C-r>""<Esc>
vnoremap S' c"<C-r>"'<Esc>
vnoremap S) c(<C-r>")<Esc>
vnoremap S] c[<C-r>"]<Esc>
vnoremap S} c{<C-r>"}<Esc>
vnoremap S> c<lt><C-r>"><Esc>
vnoremap S* c/*<C-r>"*/<Esc>
"vnoremap St c<lt>div><CR><C-r>"<Esc>
" Surround in div tag and edit tag
vnoremap St c<lt>div><CR><C-r>"<Esc>`<lt>lcw

All 26 comments

Some of my changes have been with an eye toward getting closer to supporting some plugins. Maybe this is a good benchmark for first one to support. I've added :execute support and enhanced expression support precisely with a view toward being closer to being able to support plugins. I say that merely to point out that we are already closer to supporting this plugin than we were several months ago. Maybe I will comb through the source and see what I could work on next. I personally think it would be better to just enhance the VimScript support than to re-implement this. What do you think, @jaredpar?

One thing I have been thinking of is by beginning to support calling built-in functions... some of the code is there, but it just reaches a "not implemented" dead end. However, if I do that, I'm going to need some serious design advice from Jared.

I skeptical that vim script support can ever really get to a point to support general purpose plugins. This used to be a real goal for me but as I moved forward with the implementation I've grown very pessimistic about it. There are a couple of reasons for this

  1. vimscript is actually a fairly complex language that is filled with endless special cases
  2. There is a fundamental difference between how Vim and Visual Studio represents documents, buffer and windows and the ways in which they can be manipulated. Many plugins out there rely on the vim behavior and there is no feasible way to represent it on top of Visual Studio
  3. Many plugins out there rely on manipulating window layout (vertical and horizontal split). Visual Studio is incredibly limited in how it can manipulate windows and can never support the more popular plugins that exist.

It's all really frustrating because VsVim and the underlying editor don't have any of these limitations (and hence VsVim doesn't either). It's a limitation of the host in this case Visual Studio.

For popular plugins I've been thinking along different lines. Just implement the behavior directly in VsVim via extensibility mechanisms and then have an option to turn it on / off. I've yet to try this out on a real plugin though.

+1 on the above. Most vim plugins don't even make sense in VsVim anyway. The only plugins that make sense are "editing" plugins. Those should be simple enough to implement in VsVim.

@rgrinberg Well, I have wished I had Fugitive. But that's a pipe dream. :)

@jaredpar Are you still interesting in implementing :call, at least for built-in functions? I am sure you are right that we will never be able to have full VimScript support. However, for editing plugins, I find it conceivable that we could support enough of it.

On the other hand, if it's easier to just implement the behavior of that plugin, I'm certainly not opposed to that.

@Kazark i'm not opposed to implementing really any portion of vimscript. The more the better.

I just think that the idea that one day VsVim will have a completely compatible implementation isn't really achievable.

@jaredpar Gotcha, and I think you're right about that. The more I dig into the interface betwen the Vim parts of VsVim and the VS parts of it, the more I understand what you're talking about, too. :)

@jaredpar I would like to try to implement a function, say, exists(). One thing I have not learned in functional code (or in VsVim) is how to properly modularize my code, but I feel that there should be some sort of functions module or something. Do you have an advice or guidance for me if I were to try it?

@Kazark for the built-in functions I would just have a type within the interpreter that holds their implementation. Something like BuiltinFunctions.

It's the full fledged plugins that I would move out to an extensbility point. For those I usually create a new subdirectory under Implementation and do all of the work there. The idea is that folders under Implementation should never directly reference each other, instead if they need to communicate define an interface in the root folder to talk through. This helps keeps features separate with well defined boundaries

Okay, thanks. If I get some time I may play around with implementing some built-in functions, just to see what it would look like.

So it begins! I've stubbed some stuff out. https://github.com/Kazark/VsVim/tree/impl-exists-function

Great to see this being worked on as I was looking for a way to get surround.vim to work with VsVim today! I'd really like to contribute if possible. Are there any guidelines for contributing?

+1 for surround.vim, I find myself typing csiw... all the time in VS

@Kantis There are no formal guidelines on contributing. Mostly common sense items like

  • Please follow the coding style of the code base
  • Please make sure all unit test pass

For extensions like this I would like to have them outside the core vim engine. The logic being that vim built them on extensibility points hence if VsVim can't then the API is incomplete and probably points to other missing work.

Either put them after MefComponents.fs in VimCore or inside Implementation of VimWpf.

Thanks for the guidelines @jaredpar! Any chance to catch active contributors in some IRC-channel?

/Src/VsVim/VsVim.csproj won't load in my VS2013 Professional Update 3. Upgrading to Update 4 and trying again Edit: Hadn't installed the SDK. The shame. :(

Do u have the VS SDK installed? The solution should load fine in any
version of Visual Studio 2010 and higher if the SDK is installed.

If the error still persists whay error is jt giving?

On Friday, November 14, 2014, Emil Kantis [email protected] wrote:

Thanks for the guidelines @jaredpar https://github.com/jaredpar! Any
chance to catch active contributors in some IRC-channel?
/Src/VsVim/VsVim.csproj won't load in my VS2013 Pro, does it require 2010
or 2012?

—
Reply to this email directly or view it on GitHub
https://github.com/jaredpar/VsVim/issues/1474#issuecomment-63149979.

Jared Parsons
http://blog.paranoidcoding.com/
http://twitter.com/jaredpar

You're right :) The SDK was missing.

I'd find this super useful too.

If you have Visual Assist, you can do something like this

vnoremap s/ :vsc VAssistX.SelectionToggleLineComment
vnoremap s* :vsc VAssistX.SelectionToggleBlockComment
vnoremap s{ :vsc VAssistX.SurroundSelectionWithBraces
vnoremap s( :vsc VAssistX.SurroundSelectionWithParentheses
vnoremap s# :vsc VAssistX.SurroundSelectionWithIfdefOrRegion
vnoremap sc :vsc VAssistX.SurroundSelectionWithComment

It's not exactly the same as surround.vim, as it doesn't support motions. But this has worked reasonable well for me. One slightly annoying thing is if you have surrounded a word with a block comment, it's not enough to select the word to remove it, you also need to select the comment itself.

The SurroundSelectionWithComment command will either do a block comment or a line comment, depending on if you one or more complete lines selected or not.

It's been a year since this has been opened. Is this feature still missing?

Is this Surround.vim feature being implemented yet in VsVim?

Hello Vsvim'ers,
I tried to implement some of the functionality with regular mappings. The basic idea is this: to surround a text object (word/WORD/visual selected text), you

  • change it
  • insert beginning surround (e.g. [ or " )
  • get text back from unnamed register
  • insert closing surround
  • leave insert mode

I implemented some mappings like this. Notice that I choose word as "default", so s( surrounds the word under cursor. sw( surrounds a big WORD. I used "sw" instead of "sW" because that's faster to type.
What do you think of this?

" surround maps
nnoremap s( ciw(<C-r>")<Esc>
nnoremap s[ ciw[<C-r>"]<Esc>
nnoremap s" ciw"<C-r>""<Esc>
nnoremap s' ciw'<C-r>"'<Esc>
nnoremap sw( ciW(<C-r>")<Esc>
nnoremap sw[ ciW[<C-r>"]<Esc>
nnoremap sw" ciW"<C-r>""<Esc>
nnoremap sw' ciW'<C-r>"'<Esc>

" surround visual selected text
vnoremap s" c"<C-r>""<Esc>
vnoremap s' c"<C-r>"'<Esc>
vnoremap s( c(<C-r>")<Esc>
vnoremap s* c/*<C-r>"*/<Esc>
vnoremap s{ c{<C-r>"}<Esc>

" change surround. tricky / experimental
nnoremap s'" di'h"_2s"<C-r>""<Esc>
nnoremap s"' di"h"_2s'<C-r>"'<Esc>

To add on to the mappings @sqlkoala posted, these cover the functions I personally use often:

nnoremap ds( vi(oh<Esc>msvi(l<Esc>x`sx
nnoremap ds[ vi[oh<Esc>msvi[l<Esc>x`sx
nnoremap ds{ vi{oh<Esc>msvi{l<Esc>x`sx
nnoremap ds< vi<oh<Esc>msvi<l<Esc>x`sx
nnoremap ds" vi"oh<Esc>msvi"l<Esc>x`sx
nnoremap ds' vi'oh<Esc>msvi'l<Esc>x`sx

nnoremap cs"' vi"oh<Esc>msvi"l<Esc>cl'<Esc>`scl'<Esc>
nnoremap cs'" vi'oh<Esc>msvi'l<Esc>cl"<Esc>`scl"<Esc>

I can't believe this function hasn't been implemented yet... I thought vs exists long enough to have a good ecosystem, but even vscode vim emulator has this function.

I'd like surround as a builtin too, but the above bindings are a pretty good substitute. The only real short-coming is where branching or other logic is required. I modified the above a little to increase your options, to simplify the delete bindings, and to add a visual tag-surround to match the tag text object. I also switched the brace direction since I used the other variant in Surround, here's my version:

" Surround simulating bindings
nnoremap s) ciw(<C-r>")<Esc>
nnoremap s] ciw[<C-r>"]<Esc>
nnoremap s} ciw{<C-r>"}<Esc>
nnoremap s> ciw<lt><C-r>"><Esc>
nnoremap s" ciw"<C-r>""<Esc>
nnoremap s' ciw'<C-r>"'<Esc>
nnoremap sw) ciW(<C-r>")<Esc>
nnoremap sw] ciW[<C-r>"]<Esc>
nnoremap sw} ciW{<C-r>"}<Esc>
nnoremap sw> ciW<lt><C-r>"><Esc>
nnoremap sw" ciW"<C-r>""<Esc>
nnoremap sw' ciW'<C-r>"'<Esc>

" Surround delete bindings
nnoremap ds) vi(dvhp
nnoremap ds] vi[dvhp
nnoremap ds} vi{dvhp
nnoremap ds> vi<dvhp
nnoremap ds" vi"dvhp
nnoremap ds' vi'dvhp

" Surround change bindings
nnoremap cs"' vi"oh<Esc>msvi"l<Esc>cl'<Esc>`scl'<Esc>
nnoremap cs'" vi'oh<Esc>msvi'l<Esc>cl"<Esc>`scl"<Esc>

" Surround visual selected text
vnoremap S" c"<C-r>""<Esc>
vnoremap S' c"<C-r>"'<Esc>
vnoremap S) c(<C-r>")<Esc>
vnoremap S] c[<C-r>"]<Esc>
vnoremap S} c{<C-r>"}<Esc>
vnoremap S> c<lt><C-r>"><Esc>
vnoremap S* c/*<C-r>"*/<Esc>
"vnoremap St c<lt>div><CR><C-r>"<Esc>
" Surround in div tag and edit tag
vnoremap St c<lt>div><CR><C-r>"<Esc>`<lt>lcw

Maybe we could implement it like they do in IdeaVim (https://github.com/JetBrains/ideavim#emulated-vim-plugins), the extension functionality is implemented as part of the vim plugin and just enabled by e.g. "set surround" or "set easymotion" inside the rc file.

A tiny update to the excellent solution from https://github.com/VsVim/VsVim/issues/1474#issuecomment-417782010 for C/C++ programmers which find handy while refactoring between C and C++ style casts

nnoremap cs(< vi(oh<Esc>msvi)l<Esc>cl><Esc>`scl<lt><Esc>
nnoremap cs<( vi<lt>oh<Esc>msvi>l<Esc>cl)<Esc>`scl(<Esc>
Was this page helpful?
0 / 5 - 0 ratings

Related issues

leemuro picture leemuro  Â·  25Comments

pckujawa picture pckujawa  Â·  11Comments

Ybalrid picture Ybalrid  Â·  10Comments

radutomy picture radutomy  Â·  13Comments

wiserfirst picture wiserfirst  Â·  30Comments