I want to write a command that works with a visual selection, so I wrote something like this:

command! -range Foo
    \ exec "norm \"ay" |
    \ echo "[" . @a . "]"

hoping that it would take the visual selection and put it into the @a register, then I could use the @a register as normal, but there's never anything in the @a register. How do I get the visual selection into a variable? It should work with block mode visual selection as well as the normal mode.

  • If I use yank a it seems like it just yanks the first line of the visual selection into the register, I want all of the lines.
    – Jake
    Jan 7, 2022 at 2:08
  • 1
    Oh, yes, you need something like command! -range Foo <line1>,<line2>yank a ... (I'm not in front of the right computer ... my folks don't have Vim LOL ... so I can't test but it's something like that.) I think this only works for linewise selections, though.
    – B Layer
    Jan 7, 2022 at 2:13

1 Answer 1


I see now the :normal command will exit the visual selection mode temporarily, so if you wanted to get the visual selection, you have to reselect it in the command by using gv, as in :execute "normal gv\"ay".

This would require the command be used when there's a visual selection active; if you used it with the default range, it would select the previous visual selection, which might not be what the user was expecting. Instead it should use the <line1> and <line2> replacements the command defines for you; however, these do not work with visual block mode.

  • You could have your command simply ignore the range and use gv unconditionally... But it seems a Visual mode mapping using xnoremap is probably more appropriate here.
    – filbranden
    Jan 7, 2022 at 2:37

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.