{"action":"created","issue":{"url":"https://api.github.com/repos/JetBrains/ideavim/issues/87","labels_url":"https://api.github.com/repos/JetBrains/ideavim/issues/87/labels{/name}","comments_url":"https://api.github.com/repos/JetBrains/ideavim/issues/87/comments","events_url":"https://api.github.com/repos/JetBrains/ideavim/issues/87/events","html_url":"https://github.com/JetBrains/ideavim/pull/87","id":70959979,"number":87,"title":"VIM-769 Support for vim-surround","user":{"login":"dhleong","id":816150,"avatar_url":"https://avatars.githubusercontent.com/u/816150?v=3","gravatar_id":"","url":"https://api.github.com/users/dhleong","html_url":"https://github.com/dhleong","followers_url":"https://api.github.com/users/dhleong/followers","following_url":"https://api.github.com/users/dhleong/following{/other_user}","gists_url":"https://api.github.com/users/dhleong/gists{/gist_id}","starred_url":"https://api.github.com/users/dhleong/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dhleong/subscriptions","organizations_url":"https://api.github.com/users/dhleong/orgs","repos_url":"https://api.github.com/users/dhleong/repos","events_url":"https://api.github.com/users/dhleong/events{/privacy}","received_events_url":"https://api.github.com/users/dhleong/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":16,"created_at":"2015-04-25T19:49:57Z","updated_at":"2015-09-15T13:29:25Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/JetBrains/ideavim/pulls/87","html_url":"https://github.com/JetBrains/ideavim/pull/87","diff_url":"https://github.com/JetBrains/ideavim/pull/87.diff","patch_url":"https://github.com/JetBrains/ideavim/pull/87.patch"},"body":"This is an initial stab at defining semantics for replicating vim plugin behavior within IdeaVim, with some preliminary support for tpope's excellent [vim-surround](https://github.com/tpope/vim-surround) plugin.\r\n\r\nI'm not sure if there's a more idiomatic way of doing stuff like this, but since I didn't hear back on my request for guidance I just went ahead and made something up.\r\n\r\nI created a `Plugin` interface which contains a `Registrar` in which plugins register. Each plugin has an \"option name\" which is used to enable the plugin using the vim options syntax, eg:\r\n\r\n```vim\r\n  set surround\r\n```\r\n\r\nPlugins can be activated at runtime using this syntax, but I wasn't sure how to go about disabling them (I think we'd need a hook to register and de-register actions, or perhaps make a subclass of VimCommandAction that won't be automatically registered at init). I'm not sure that's a huge concern, though, as generally you set up your plugins once in your vimrc and just go.\r\n\r\nSince plugin bindings are optional and are enabled after init via .ideavimrc, I slightly refactored `ParentNode` to be able to correctly handle adding new `BranchNode` onto a `BranchNode` that already has an `ArgumentNode`. This way, plugins can override built-in bindings as expected, as well as expand on them.\r\n\r\nThe included vim-surround port supports most of the core surroundings, but currently leaves xml/html tag support to future work, as well as (I'm sure) a few more obscure features that I wasn't aware of, but I wanted to get this PR up and get some feedback on the approach before I try to figure that one out.\r\n\r\nSince the `ys` and `cs` motions take more than just a motion, I mimicked vim-surround's implementation and added a `getChar()` command to `KeyHandler`. While necessarily asynchronous, taking a callback, this does block other vim input processing, as expected. If there's a better way to deal with this sort of thing I'd love to hear it, but this seemed like it would prove helpful in porting other vim plugins in the future.\r\n\r\nUPDATE: Repeat support via `.` for `cs` and `ys` is achieved by subclassing `Argument` and storing our extra arguments in it (ie, the `SurroundPair` object). I think this is the simplest way to support the more complex surrounds, such as that achieved by `ysiwtdiv>` to surround the inner word with `<div></div>` tags (which is not yet implemented, but I'm thinking ahead for when we figure that out)."},"comment":{"url":"https://api.github.com/repos/JetBrains/ideavim/issues/comments/140393792","html_url":"https://github.com/JetBrains/ideavim/pull/87#issuecomment-140393792","issue_url":"https://api.github.com/repos/JetBrains/ideavim/issues/87","id":140393792,"user":{"login":"dhleong","id":816150,"avatar_url":"https://avatars.githubusercontent.com/u/816150?v=3","gravatar_id":"","url":"https://api.github.com/users/dhleong","html_url":"https://github.com/dhleong","followers_url":"https://api.github.com/users/dhleong/followers","following_url":"https://api.github.com/users/dhleong/following{/other_user}","gists_url":"https://api.github.com/users/dhleong/gists{/gist_id}","starred_url":"https://api.github.com/users/dhleong/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dhleong/subscriptions","organizations_url":"https://api.github.com/users/dhleong/orgs","repos_url":"https://api.github.com/users/dhleong/repos","events_url":"https://api.github.com/users/dhleong/events{/privacy}","received_events_url":"https://api.github.com/users/dhleong/received_events","type":"User","site_admin":false},"created_at":"2015-09-15T13:29:25Z","updated_at":"2015-09-15T13:29:25Z","body":"@vlasovskikh I think the biggest reason for requiring plugins be enable/disable-able is to be able to handle such plugins that override default bindings. vim-surround is innocuous enough, but something like [vim-sneak](https://github.com/justinmk/vim-sneak), for example, steals your `s`-key by default. I suppose for such plugins we could instead add support for `<Plug>FUNCTION` things and expose plugin functionality that way, but that might be a bit much to deal with. The `set` syntax, at least, mimics that of plugin managers like vim-plug. \r\n\r\nThis doesn't address how plugins are declared in code, but perhaps we might prefer supporting the syntax from Vundle or vim-plug with the same github artifacts? That way any plugins a user might have in their .vimrc (if sourced as mentioned in the README) will be automatically enabled. Doesn't help pathogen users, of course, and there might be confusion if there's any difference between the vim plugin and the ideavim plugin (which I suspect there would be).... Just a thought."}}