You can go back to the previous selection with gv. So after you type esc you can type gv and the old selection is active again. (see gv
)
To do this automatically is a little difficult. I did not find a full working solution right away. My basic idea was to map esc in command mode (see :cnoremap
).
A plain
cnoremap <esc> <esc>gv
does not really work well as it is always used the pressing esc in the command line. But I think it should only activate the last selection when you entered the command line from visual mode.
Now I thought about an expression mapping (see :map-expression
). But if I use mode()
like this it obviously doesn't work as we are always in command mode:
cnoremap <expr> <esc> mode()=='v' ? "\<esc>gv" : "\<esc>"
But if we can save the information that we have been in visual mode when pressing : in the first place we can use it to do the right thing when pressing esc later. For this we need two functions and two mappings:
let s:was_visual = 0
function! EnterCommandLineFromVisualMode()
let s:was_visual = 1
return ':'
endfunction
function! HandleEscapeInCommandLine()
if s:was_visual
let s:was_visual = 0
return "\<esc>gv"
endif
return "\<esc>"
endfunction
vnoremap <expr> : EnterCommandLineFromVisualMode()
cnoremap <expr> <esc> HandleEscapeInCommandLine()
Put this code into your vimrc or a new file in the plugin directory and it should work. The result might be inconsistent when you press CTRLC in the command line though as the s:was_visual
variable will not get updated. You will need an extra cmap
for this. Maybe there are other corner cases like this that I did not think of right now.