I have some boilerplate code in one of my vimscript functions:

" Save register 'a' so we don't clobber it
let savereg = @a

" Yank the current WORD into register 'a' and save it to 'input'
normal "ayiW
let input = @a

" Restore register 'a' so we don't clobber it
let @a = l:savereg

" ... Do work on 'l:input'

Is there a better way to do what I want? That is, to operate on a WORD (or any text object, really) without clobbering a register?

  • If I knew how to operate on the range '<,'> then my problem would be solved, I believe. But I'm not sure how to get text from between 2 marks. I'm reading the documentation but I'm quite lost... I am looking for a starting point or a hint. Jan 29, 2020 at 6:41
  • 1
    yes, but it is clumsy. Use the getline() functions and in combination with the cursor position, select the needed part of the line Jan 29, 2020 at 7:03
  • 1
    @AriSweedler Since you sound eager to learn but maybe not grokking the help docs this is a widely praised route to enlightenment: Learn Vimscript the Hard Way (Not for newbies but doesn't look like that's you. At the very least bookmark it for the future.)
    – B Layer
    Jan 29, 2020 at 20:37

2 Answers 2


First, if your script runs from a mapping than you probably should support v:register - let the user decide what to use.

Next, if your operation is a sort of "visual replacement" (get selection, modify and put it back) it makes sense to model it after :h v_p (maybe even end it with gvp or such).

In this case either @- (for "less-than-a-line" selection) or @9 (for a multiline selection) will be overwritten anyway, so you can make use of one of them in your script.

Otherwise, I prefer simply to clobber @0 as it seems like a natural choice. Anyway, it gets overwritten quite often, and it could also be a good idea to spare "original input" for the user.

  • Thank you for the tips about best practice! I consider that invaluable. What I am really trying to accomplish a macro that reads a WORD under the cursor and does work on it. Specifically, I want to be able to append "(due in 5 days)" with a single keystroke when my cursor is over a date that's 5 days in the future. That wouldn't be a very good question to ask here, tho. What I wrote can be found here, if you're curious: github.com/AriSweedler/dotfiles/blob/master/.vim/plugin/due.vim Jan 29, 2020 at 7:40
  • 4
    @AriSweedler In your specific case it's probably sufficient to do simply expand('<cWORD>')
    – Matt
    Jan 29, 2020 at 7:44
  • I am so stoked to be learning this stuff. You are right, and thank you for the improvement. Jan 29, 2020 at 7:58

Is there a better way to do what I want? That is, to operate on a WORD (or any text object, really) without clobbering a register?

If you want the current WORD in specific, then this works:

let input = expand('<cWORD>')

It's not a general solution, but it seems to fit what you're after in this particular instance.

  • 3
    Matt have this answer as a comment already, but this is the best answer. I won’t change who I gave the green check to, but this answer should stay here as it definitely adds value Jan 29, 2020 at 16:17
  • 2
    Agreed. I did notice the comment but I thought this definitely deserved to be an answer. Matt does a great job at addressing the general case of any text object or visual region.
    – filbranden
    Jan 29, 2020 at 16:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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