machakann / vim-sandwich

Set of operators and textobjects to search/select/edit sandwiched texts.
1.44k stars 37 forks source link

Is there a way to control the cursor position after a surround #122

Closed jeetsukumaran closed 3 years ago

jeetsukumaran commented 3 years ago

It would be nice, for e.g,. to use sa<motion/obj>( to have the cursor end at the beginning of the object and sa<motion/obj>) at the end. So, if ^ indicates the cursor position below, then starting with:

quick
  ^

the sequence saiw( would result in:

 (quick)
^

while saiw) would result in:

(quick)
       ^

Currently, the behavior is to place the cursor just inside the surround:

(quick)
 ^

which to me is a strange place.

If it's too difficult or not possible to set the cursor differently based on whether the surround open or close is used, then it would be nice to at least have the cursor position outside the element one way or another:

 (quick)
^

or

(quick)
       ^

Reasoning being that typically once I surround something I rarely need to edit the thing itself, but rather edit things around it, e.g., adding function fn( before or : after.

machakann commented 3 years ago

You may be interested in this option.

In short, the behavior what you mention above can be achieved by

let g:sandwich#recipes  = deepcopy(g:sandwich#default_recipes)
let g:sandwich#recipes += [
\   {'buns': ['(', ')'], 'nesting': 1, 'cursor': 'head', 'input': ['(']},
\   {'buns': ['(', ')'], 'nesting': 1, 'cursor': 'tail', 'input': [')']},
\ ]

If you want to change globally,

call operator#sandwich#set('add', 'all', 'cursor', 'head')
jeetsukumaran commented 3 years ago

THANK YOU!

Very nicely designed!!

The above works perfectly fine in Neovim, but strangely gives me this error in Vim:

E117: Unknown function: operator#sandwich#set

What makes it even stranger is that Vim can find and understand vim-sandwich, as I get the buns with all my key-mappings even with the error.

machakann commented 3 years ago

Maybe, timing problem? If you are using Vim's default packages feature all plugins are not recognized (included in runtimepath) until executing :packloadall. In principle, plugin managers also need such kinds of tricks. For example, vim-plug make vim recognize plugins after call plug#end(). If you are using lazy-loading, it would make it more complicated. The function operator#sandwich#set will be available after one of those tricks.

Or the following lines also work equally.

let g:operator#sandwich#options.add.char.cursor = 'head'
let g:operator#sandwich#options.add.line.cursor = 'head'
let g:operator#sandwich#options.add.block.cursor = 'head'
jeetsukumaran commented 3 years ago

Interesting. You are definitely correct in that :packadd solves (BTW, I'm not using any third-party package manager).

Strangely, I also get:

E121: Undefined variable: g:operator#sandwich#options

when I try the above approach without explicitly running :packadd.

But I do NOT with, for e.g., let g:jedi#use_splits_not_buffers = "left" and I don't even have Jedi installed anymore!

Anyway, for now I can just use :packadd if needed.

Thanks!

machakann commented 3 years ago

Good to hear :tada: