3

I want to create a macro that will take a word logThis, which is selected in visual mode, and turn it into this:

console.log 'printing logThis'
console.log JSON.stringify(logThis, undefined, 2)

I realize that I can get my macro to remember logThis by copying it with yw or some other register, but I might be using that register for something else, and I don't want the macro to wipe out that register's contents.

Is it possible to use logThis twice inside this macro without taking up a register?

1
  • I do something similar with a mapping. My version clobbers the default register, but we could clobber a different register, e.g. l by using "ly instead of y and <C-R>l instead of <C-R>". Jul 30, 2015 at 0:14

2 Answers 2

8

You could include this command at the beginning of your macro to save the current value of register a:

let old_a = getreg(a)

yank the highlighted word to register a:

"ay

and reset register a once you are done:

call setreg("a", old_a)

Macros are great but there's always a point where they become too complex to maintain. You should probably consider a proper function instead:

function! MyFunction()
    let old_a = getreg("a")
    normal! gv"ay
    let my_word = getreg("a")
    call setreg("a", old_a)
    " use my_word here
endfunction

xnoremap <key> :call MyFunction()<CR>
2
  • 7
    Here we go again: don't use assignments to save and restore registers, you'll lose all information about the registers' types. Use getreg(), getregtype(), and setreg() instead.
    – lcd047
    Jul 20, 2015 at 7:47
  • 1
    I've never run into a circumstance where the mode/type of a register mattered but for those interested see :help setreg() for info on how to use these functions and what 'mode' means (getreg/setreg pairs are insufficient). Feb 16, 2016 at 21:05
6

Why a macro? You could very well use a snippet instead. For example (with NeoSnippet):

Create a new global snippet with :NeoSnippetEdit _ (replace _ with a filetype if you want a dedicated snippet) and add this content:

snippet log
    console.log 'printing ${1:TARGET}'
    console.log JSON.stringify($1, ${2:undefined}, 2)${0}

Save and exit the file.

Usage:

Visually select your text, hit Tab (or the key you have configured to trigger a snippet) and you will be asked for the snippet name to be inserted: write 'log', Enter and the above code will be inserted, with cursor on 1st position and the TARGET replaced by your selected text, in both positions. Hit Tab again to accept the text and jump to the second marker (undefined) - you can edit it, or not, and if you hit Tab again, the cursor will be placed at the end of the construct ( position 0).

Now, because this is a snippet, you can also use it ... before you have the text to be logged: you write log and hit Tab, and the snippet will be expanded: write logThis (or whatever text you want to log), hit Tab, accept undefined or change it, hit Tab again and ... that's it.

If you prefer using UltiSnips instead, see this link.

Your Answer

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

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