Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vimscript: Get visual mode selection text in mapping

Tags:

vim

So I'm trying to have a binding that runs lvimgrep on the currently selected text.

  fun! s:get_visual_selection()
       let l=getline("'<")
       let [line1,col1] = getpos("'<")[1:2]
       let [line2,col2] = getpos("'>")[1:2]
       return l[col1 - 1: col2 - 1]
 endfun

 vnoremap <expr> <script><leader>* ":lvimgrep /" .  <SID>get_visual_selection()  . "/j **/*." .  expand("%:e") . " \|lopen"

The function's from the comment on the question: How to get visually selected text in VimScript

Thing is that it is behaving really weird: Most of the times the text returned by the function doesn't match the visual selection and more often than not, it is the text of the last visual selection - not the current one.

Have gone through tons of posts around getting visual selection text in vimscript but can't get it to work.

I have also tried https://stackoverflow.com/a/1534347/287085 without success (copying selection to register) - get an error when called from my binding.

like image 498
Raghu Avatar asked Oct 03 '22 11:10

Raghu


1 Answers

The problem is that the '<,'> marks are not set until after the current selection has been left (either by executing a command on it, or through <Esc>). Here, your expression mapping makes it more complex to prepend an <Esc> to leave visual mode first, so it's easier to insert the expression with :help i_CTRL-R and the expression register =:

:vnoremap <script> <leader>* <Esc>:lvimgrep /<C-R><C-R>=<SID>get_visual_selection()<CR>/j **/*.<C-R><C-R>=expand("%:e")<CR>\|lopen

If you don't mind clobbering the default register, you could also just yank the selection:

:vnoremap <leader>* y:lvimgrep /<C-R><C-R>"/j **/*.<C-R><C-R>=expand("%:e")<CR>\|lopen
like image 139
Ingo Karkat Avatar answered Oct 13 '22 12:10

Ingo Karkat