1

I'm trying to make it easier to refactor stuff by running a single command that "performs the last rename interactively".

I have a binding for doing this that sort of works, but I'm curious whether there's a way to prevent it from ever getting "out of sync" by replacing an old substitution with a recent edit.


so far the best I've been able to find is this, which clobbers a register and a marker and the user to manually "wrap" commands so that they populate the contents of the p register. It's also very easy for <leader>, to pick up a new edit and there's absolutely no indication that this has happened.

nnoremap ciw mP"pyiw`Pciw

nnoremap <silent> <leader>, :%s/<c-r>p/<c-r>./gc<cr>

I'd like to be able to start with a file that looks like this:

AAAA       (instant 1)
AAAA
AAAA
AAAA

run the following commands gg0ciwBBBBBBB<esc>, get the following buffer

BBBBBBB    (instant 2)
AAAA
AAAA
AAAA

since ciw has been remapped, running <leader>, causes the buffer to look like this

BBBBBBB    (instant 3)
BBBBBBB
BBBBBBB
BBBBBBB

This is correct behavior. If, however, I performed I inserted and then deleted some text after (instant 2). By performing 0ia<esc> and then x

aBBBBBBB    (instant 2.1 -- alternate)
AAAA
AAAA
AAAA

BBBBBBB     (instant 2.2 -- alternate)
AAAA
AAAA
AAAA

then performing <leader>, will result in the following buffer

BBBBBBB     (instant 3 -- alternate)
a
a
a

the correct identifier AAAA was targeted, but the contents of the . register has changed. I'd like a solution where performing a mismatched substitution is simply impossible.

  • 1
    What about a mapping like nnoremap {key} :%s/<c-r><c-w>//gc<left><left><left>? maybe add <c-f> to bring up the command-line window? Would that be sufficient? – Peter Rincker Mar 21 '19 at 17:21
  • The thing I'm trying to do is repeat a pseudo-substitution performed by ciw + entering text as an action that targets the substituted text. Ideally what I'd like to do is set up ciw in such a way that the subsequent edit is stored in a particular register (say o) so p and o are always in sync. – Gregory Nisbet Mar 21 '19 at 17:29
  • You provided example of what happens. You also need to provide examples of what you want to happen. – klaus Mar 21 '19 at 17:45
  • @Klaus ... what happens is what I want to happen. It's just that the way that I implemented it is not robust since it will apply whatever text was inserted last and it's inappropriate for a plugin because it claims at least one register. I added an example showing my partial solution's drawbacks. – Gregory Nisbet Mar 21 '19 at 17:48
  • Okay. That makes sense. But I don't understand what you actually want to do. As far as I can understand, you want to change all instances of a word. Oh I get it, you used the term refactoring. Like you already have a source file with a variable name which you want to change, but change for the whole file. But you don't want to do it with a single :%s substitution. In other words, you want to make it interactive. I'm guessing you are writing a plugin. I don't have any idea though. You should look at established plugins that use this type of features. – klaus Mar 21 '19 at 17:55
2

You can use InsertLeave to capture @@ and @. then use those values in your substitution mapping.

nnoremap <expr> ciw <SID>replacer()
nnoremap gs :<c-u>%s/<c-r>=get(g:, 'replacer_pat')<cr>/<c-r>=get(g:, 'replacer_str')<cr>/gc

function s:replacer()
  augroup replacer
    autocmd!
    autocmd InsertLeave * execute "autocmd! replacer" |
          \ let [g:replacer_pat, g:replacer_str] = [getreg(v:register), @.]
  augroup END
  return 'ciw'
endfunction

Note: InsertLeave will not fire if you use <c-c>. It might also act incorrectly when using <c-o>.

| improve this answer | |
1

I recently added this little snippet to my vimrc, which accomplishes a similar but different effect:

nnoremap <Leader>cw :let @/=expand('<cword>')<CR>cgn

With this, I can do <Leader>cw, insert some text, and use n to go to instances of the old name and . to instantly change the next one wherever it is (see :help gn). This provides me with a selective renaming tool.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.