From 17703b92b44e5afd12e4bca418f61cadb50ac91d Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Mon, 22 Aug 2022 13:44:02 -0600 Subject: Add command motion and make some changes to substitute. --- plugin/command.vim | 14 ++++++++++++ plugin/substitute.vim | 59 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 plugin/command.vim diff --git a/plugin/command.vim b/plugin/command.vim new file mode 100644 index 0000000..51633b5 --- /dev/null +++ b/plugin/command.vim @@ -0,0 +1,14 @@ +" g: is a command to run a vim command around a text object. +" +" For example, to do a substitution inside the current block, one can do: +" +" g:iBs/foo/bar/g + +noremap g: :set operatorfunc=do_command_aroundg@ + +function! s:do_command_around(str) abort + let [_, lnum0, _, _] = getpos("'[") + let [_, lnum1, _, _] = getpos("']") + + call feedkeys(printf(":%d,%d ", lnum0, lnum1)) +endfunction diff --git a/plugin/substitute.vim b/plugin/substitute.vim index 2c08310..982a76b 100644 --- a/plugin/substitute.vim +++ b/plugin/substitute.vim @@ -1,7 +1,56 @@ -" C-s in normal mode will replace all the occurences of the last register with -" what was typed in the provided body. -noremap :set operatorfunc=DoSubstitutiong@ -function DoSubstitution(str) abort - exec printf(":'[,']s/%s/%s/g", @", @.) +" gs will create a substitution command to replace the last yanked string with +" the last inserted string over a motion. +" +" This is useful when renaming a variable for example, one can place the cursor +" over the varibale to rename and type: +" +" ciwnew_variable_namegsiB +" +" and this will replace that variable name with 'new_variable_name' inside the +" Body. + +noremap gs :set operatorfunc=do_subst_enterg@ +vnoremap gs :call v_do_subst_enter() + +" gS is like gs, except it: +" +" * doesn't feed a newline at the end +" * doesn't wrap the string to substitue in word boundaries. +noremap gS :set operatorfunc=do_subst_no_enterg@ +vnoremap gS :call v_do_subst_no_enter() + +function! s:do_subst_enter(...) abort + call s:do_subst_priv("'[", "']", v:true) +endfunction + +function! s:do_subst_no_enter(...) abort + call s:do_subst_priv("'[", "']", v:false) +endfunction + +function! s:v_do_subst_enter(...) abort + call s:do_subst_priv("'<", "'>", v:true) + +endfunction + +function! s:v_do_subst_no_enter(...) abort + call s:do_subst_priv("'<", "'>", v:false) +endfunction + +function! s:do_subst_priv(m0, m1, do_enter) abort + let [_, lnum0, _, _] = getpos(a:m0) + let [_, lnum1, _, _] = getpos(a:m1) + + " Need to call feedkeys() because @. may contain special characters like + " backspace. + call feedkeys( + \ printf( + \ ":%d,%d s/\\V%s%s%s/%s/g%s", + \ lnum0, + \ lnum1, + \ a:do_enter ? "\\<" : "", + \ escape(@", '/\'), + \ a:do_enter ? "\\>" : "", + \ escape(@., '/\'), + \ a:do_enter ? "\n" : "")) endfunction -- cgit