On Friday, October 2, 2015 at 4:38:39 PM UTC+2, glts wrote:
> one popular implementation of a 'search for the current visual
> selection' mapping looks like this:
> 
>     function! s:VSetSearch(cmdtype)
>       let temp = @s
>       norm! gv"sy
>       let @/ = '\V' . substitute(escape(@s, a:cmdtype.'\'), '\n', '\\n', 'g')
>       let @s = temp
>     endfunction
> 
>     xnoremap * :<C-u>call <SID>VSetSearch('/')<CR>/<C-R>=@/<CR><CR>
>     xnoremap # :<C-u>call <SID>VSetSearch('?')<CR>?<C-R>=@/<CR><CR>
> 
> It does have a couple of problems though, such as not restoring the
> register type of the s register, and not handling null bytes properly.
> 
> I was wondering if anybody can point me to a small, robust
> implementation that handles all the edge cases properly and doesn't have
> side effects, before I try to write one myself.

Phew, and down the rabbit hole I went.

Thanks everybody, but I'm not sure the approach based on yanking into a
register can be made to work with null bytes.

I sat down to write my own definitive version of this. It handles the
edge cases I'm aware of, multiple lines, pattern metacharacters,
multi-byte and combining characters, and control characters including
NUL. It leaves the registers alone, too. Hopefully that covers it.

    " Search for the current Visual selection.
    function! s:GetVisualSelectionPattern(searchtype) abort
      let l:lines = getline(line("'<"), line("'>"))
      let l:startcol = col("'<") - 1
      let l:endcol = col("'>") - 1
      if l:endcol >= strlen(l:lines[-1])
        call add(l:lines, '')
      else
        let l:endcol += strlen(matchstr(l:lines[-1][l:endcol : ], '.')) - 1
      endif
      let l:lines[-1] = l:lines[-1][ : l:endcol]
      let l:lines[0] = l:lines[0][l:startcol : ]
      return '\V' . join(map(l:lines, 'escape(v:val, a:searchtype . "\\")'), 
'\n')
    endfunction

    xnoremap * <Esc>/<C-R><C-R>=<SID>GetVisualSelectionPattern('/')<CR><CR>
    xnoremap # <Esc>?<C-R><C-R>=<SID>GetVisualSelectionPattern('?')<CR><CR>

Let me know if you find a shorter version that works equally well.


-- 
David

-- 
-- 
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to