I have a mapping where I can select text and type (leader)av to ack for my visual selection with Ack.vim:
" Visual ack, used to ack for highlighted text
function! s:VAck()
let old = @"
norm! gvy
let @z = substitute(escape(@", '\'), '\n', '\\n', 'g')
let @" = old
endfunction
" Ack for visual selection
vnoremap <Leader>av :<C-u>call <SID>VAck()<CR>:exe "Ack! ".@z.""<CR>
However, I will frequently want to re-ack for the last thing I searched for, so I type :up to search backwards through my command history for it. Problem is, this method doesn't populate the history!
My question is how can I do one of the following:
I am fully aware of the the :copen and :colder commands to open and browse to an older quickfix list (which Ack.vim populates), but I would like to know how to solve my above problem because I want to re-ack for the same thing when I know parts of my source code have changed.
When they are part of a mapping, commands are not added to the command history.
Adding an item to a specific history is done with the histadd() function:
call histadd("cmd", "e $MYVIMRC")
See :help histadd().
You could start by making your function return the search pattern instead of clobbering your registers:
function! VAck()
let old = @"
norm! gvy
let pat = substitute(escape(@", '\'), '\n', '\\n', 'g')
let @" = old
return pat
endfunction
which would allow you to simplify your base mapping:
vnoremap <Leader>av :<C-u>exe "Ack! " . VAck()<CR>
that we now could modify to add the command to the history:
vnoremap <Leader>av :<C-u>let cmd = "Ack! " . VAck() <bar> call histadd("cmd", cmd) <bar> execute cmd<CR>
where you:
build your command, let cmd = "Ack! " . VAck()
add that command to the history, call histadd("cmd", cmd)
execute the command, execute cmd.
The end result is exactly the same as if you had actually typed :Ack! foo.
A few comments…
I think that's a good idea, I'll change my config (I already have similar functions and mappings) accordingly.
You should use xnoremap instead of vnoremap to restrain your mapping to actual visual mode.
In VAck(), yanking to the unnamed register will clobber your system clipboard if you have something like clipboard=unnamed in your config. You should use a specific register instead:
function! VAck()
let old = @z
norm! gv"zy
let pat = substitute(escape(@z, '\'), '\n', '\\n', 'g')
let @z = old
return pat
endfunction
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With