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:registeris 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 tosetreg()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:registeris only valid during the execution of an operator or normal-mode mapping; do not rely on it asynchronously- See also
v:countandv:count1for capturing a user-supplied count in the same way