vimtricks.wiki Concise Vim tricks, one at a time.

How do I detect which register was specified before executing a custom mapping in Vim?

Answer

v:register

Explanation

When writing custom mappings or operator functions, v:register gives you the register name that the user prefixed the mapping with. If the user types "amapping, then inside the mapping v:register equals 'a'. If no register was given, it falls back to '"' (the unnamed register). This lets you write register-aware functions that behave exactly like built-in Vim operators.

How it works

  • v:register is a special Vim variable that captures the register name typed before the current normal-mode command
  • It is only meaningful inside a mapping or operatorfunc — its value persists for the duration of the mapping execution
  • The value is '"' (unnamed register) when the user gives no explicit register
  • Combine with getreg() to read the register contents, or pass the name to setreg() to write back

Example

A register-aware custom operator that transforms text:

function! UpperCaseOp(type) abort
  let reg = v:register
  let saved = getreg(reg)
  execute 'normal! `[v`]"' . reg . 'y'
  call setreg(reg, toupper(getreg(reg)), getregtype(reg))
  execute 'normal! `[v`]"' . reg . 'p'
  call setreg(reg, saved)
endfunction

nnoremap <silent> <leader>U :set opfunc=UpperCaseOp<CR>g@

Now "a<leader>Uiw uppercases the inner word and stores the result in register a, just like a built-in operator would.

Tips

  • Always check v:register ==# '"' to test for the default/unnamed register (case-sensitive comparison avoids surprises)
  • v:register is only valid during the execution of an operator or normal-mode mapping; do not rely on it asynchronously
  • See also v:count and v:count1 for capturing a user-supplied count in the same way

Next

How do I reformat a paragraph or motion to fit within the text width without moving my cursor?