" 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( \ ":%s %d,%d s/\\V%s%s%s/%s/g%s", \ a:do_enter ? "silent!" : "", \ lnum0, \ lnum1, \ a:do_enter ? "\\<" : "", \ escape(@", '/\'), \ a:do_enter ? "\\>" : "", \ escape(@., '/\'), \ a:do_enter ? "\n" : "")) endfunction