wincent / scalpel

🔪 Fast within-file word replacement for Vim
MIT License
118 stars 4 forks source link

make visual mode edit more intuitive #12

Closed pkfm closed 1 year ago

pkfm commented 4 years ago

adds <Plug>(ScalpelVisualSelection) which yanks the visual selection into scalpel's pattern field. also adds <Plug>(ScalpelVisualSmart) which mixes ScalpelVisual and ScalpelVisualSelection behaviour, using the latter in most cases, and the former when the selection is only one 'non-special' character.

this behavior was mentioned in issue #3.

auto selection of the word under the cursor doesn't make sense in visual mode as the point of visual mode is visual selection of text, which is unnecessary when selection is automatic (or rather a matter of positioning) as it is with the current visual mode behavior. why would you move to visual mode and begin a selection only to disregard the selection?

this behavior might make sense in a two stage process where you first select the range, and then select the word, but then a range is probably not of great use with scalpel always invoking interactive replacement. (chrisbra/NrrwRgn is a plugin that accomplishes this)

the scalpel precision analogy makes more sense with the behavior here as visual mode allows you to make a more precise selection over and/or within the word boundary. consider some example selections. '[...]' denotes visual selection.

some 'selection' text    " original
some '[select]ion' text  " select root word
some ['selection'] text  " include surrounding characters
some ['sel]ection' text  " select 'prefix' and opening punctation
[some 'selection'] text  " select across whitespace
aCamel[Case]Var          " select tag components
a_[snake_case]_var       " select tag components

this only supports selections within a single line. selections beyond line breaks would be useful, especially when performing substitutions on comments, but this is what i've got so far.

the 'smart' variant assumes selection is deliberate unless its a single character. if the character is loosely a valid variable/method name character (w.r.t. many languages), then it falls back on scalpel#cword i.e. the original behavior. this provides an easy way to change basically 'non-word' symbols, like for example, changing several strings with single quotes to strings with double quotes. here we can skip over the escaped quotes with scalpel, which would be equivalent to :%s/'/"/gc, but it's nice to be able to do everything with the same (<leader>e) motion.

'foo bar' 'foo\'s bar' 'bar's foo' 'bar foo'

this also provides a way to get both behaviors in most cases from a single map with a little user awareness. an option like g:ScalpelVisualSmartFallbackChars might be in order if this all seems reasonable to you.

sorry this is more wordy than the actual diff and thank you for this valuable plugin.

pkfm commented 3 years ago

woops. I didn't mean to push a remap. It should be reverted now. I agree that the smart mode isn't very useful and I haven't used it much since the initial PR so I removed it. I also made an attempt at documentation. I'm not sure what default map to suggest, and since there is only one additional command I'm also not sure that it is necessary to use @mapping annotations. I also couldn't find anything about them in the docs, so I went ahead and added them in addition to amending the doc text, which is slightly re-organized for config/maps sections. lmk if that is appropriate or not at all what you meant.

pkfm commented 3 years ago

I just now realized you've written a documentation generator. I suppose the proposed <Plug> command should use an @command annotation instead.

wincent commented 3 years ago

Yeah, don't worry about the doc generator (it's a pain to install); wherever you want to stick the docs I can just copy-paste them into the right place and massage them until they look right.