On Wednesday, August 1, 2012 1:26:04 AM UTC-5, Jeroen Budts wrote:
> >>> 
> 
> >>> Using f/F/t/T is nice because I can follow it up with ; or , if
> 
> >>> I didn't supply the right count, and I have a mapping which
> 
> >>> will highlight all the matching characters within the line so I
> 
> >>> can quickly get the count right on my second try if needed.
> 
> > 
> 
> >> Would you care to share this mapping? It seems very interesting.
> 
> > 
> 
> > it isn't Ben's exclusive mapping, it's everybody's -- see:
> 
> > 
> 
> > :h f
> 
> > 
> 
> > f is the linewise search command -- it is famous for the fact that 
> 
> > it searches current line only (and to the right only).
> 
> > 
> 
> 
> 
> I know about the f/F/t/T commands. What I was referring to was the
> 
> mapping to highlight all the matching characters: "...and I have a
> 
> mapping which will highlight all the matching characters within the
> 
> line..."
> 

I think I've shared it before, but can't find it at the moment. I've been 
meaning to make a page on the wiki for it but want to clean it up a bit. Here 
is my current mapping. It also includes a Vimscript fix for the same issue 
fixed by patch 7.3.235, which if you only use recent versions of Vim can be 
stripped out.

Caveat: repeating with '.' breaks slightly when using the F/f/T/t mappings, but 
not the ; and , mappings if I recall correctly. So if you use these as-is 
you'll need to (for example) dt( and use d; to repeat the first time. I've been 
meaning to fix this but it hasn't yet been worth the trouble. If somebody has a 
fix for that I'll be glad for it.

" Highlight characters found by f, F, t, and T.
" Unhighlights on a cursorhold.
"
" matchadd is needed to highlight the char
"
" Also map <leader>f to show the highlight, and jump over the next char for ,
" and ; operations if the cursor won't move normally.
if exists('*matchadd')
  nnoremap f :<C-U>call FindChar('f', v:count1)<CR>
  nnoremap F :<C-U>call FindChar('F', v:count1)<CR>
  nnoremap t :<C-U>call FindChar('t', v:count1)<CR>
  nnoremap T :<C-U>call FindChar('T', v:count1)<CR>
  onoremap f :<C-U>call FindChar('f', v:count1, 'v')<CR>
  onoremap F :<C-U>call FindChar('F', v:count1, 'v')<CR>
  onoremap t :<C-U>call FindChar('t', v:count1, 'v')<CR>
  onoremap T :<C-U>call FindChar('T', v:count1, 'v')<CR>
  xnoremap f :<C-U>call FindChar('f', v:count1, 'gv')<CR>
  xnoremap F :<C-U>call FindChar('F', v:count1, 'gv')<CR>
  xnoremap t :<C-U>call FindChar('t', v:count1, 'gv')<CR>
  xnoremap T :<C-U>call FindChar('T', v:count1, 'gv')<CR>

  nnoremap ;  :<C-U>call FindLastChar(v:count1, ';')<CR>
  onoremap ; v:<C-U>call FindLastChar(v:count1, ';')<CR>
  xnoremap ;  :<C-U>call FindLastChar(v:count1, ';', 1)<CR>
  nnoremap ,  :<C-U>call FindLastChar(v:count1, ',')<CR>
  onoremap , v:<C-U>call FindLastChar(v:count1, ',')<CR>
  xnoremap ,  :<C-U>call FindLastChar(v:count1, ',', 1)<CR>

  " <C-U> in normal mode to remove any count, in visual mode to remove range
  " Do not provide this command in op-pending mode, it doesn't do anything
  nnoremap <Leader>f :<C-U>call HighlightFoundChar()<CR>
  xnoremap <Leader>f :<C-U>call HighlightFoundChar()<CR>gv

  " highlight the last found character
  function! HighlightFoundChar()
    if &hlsearch
      if exists('w:fFtT_command_highlight')
        call matchdelete(w:fFtT_command_highlight)
      endif
      let w:fFtT_line = line('.')
      let w:fFtT_command_highlight = matchadd(
            \'Search',
            \'\V\%' . w:fFtT_line . "l".escape(g:last_found_char,'/\'),
            \11)
      setl cursorcolumn cursorline

      " Set up autocmds to turn off highlighting for f, F, t, and T commands
      " after a period of doing nothing, or moving to a new line. The
      " CursorMoved one makes the cursor move slowly so remove it when not
      " needed.
      autocmd fFtT_hi CursorMoved *
            \ if exists('w:fFtT_command_highlight') && w:fFtT_line != line('.') 
|
            \   call matchdelete(w:fFtT_command_highlight) |
            \   unlet w:fFtT_command_highlight |
            \   setl nocursorcolumn nocursorline |
            \   exec 'au! fFtT_hi CursorMoved' |
            \ endif

    endif
  endfunction

  augroup fFtT_hi
    au!
    " Set up autocmds to turn off highlighting for f, F, t, and T commands after
    " a period of doing nothing, or moving to a new line. The CursorMoved one
    " makes the cursor move slowly so remove it when not needed.
    autocmd CursorHold,CursorHoldI *
          \ if exists('w:fFtT_command_highlight') |
          \   call matchdelete(w:fFtT_command_highlight) |
          \   unlet w:fFtT_command_highlight |
          \   setl nocursorcolumn nocursorline |
          \   exec 'au! fFtT_hi CursorMoved' |
          \ endif
  augroup END

  " Set the "last found character" and highlight it.
  function! FindChar(op, count, ...)
    echo "Enter character to find"
    let g:last_found_char = nr2char(getchar())
    call HighlightFoundChar()
    " clear the echo
    echo ''
    let cmdprefix=''
    if a:0
      let cmdprefix=a:1
    endif
    exec 'normal! ' . cmdprefix . a:count . a:op . g:last_found_char
  endfunction

  " Highlight the "last found character" if it exists and pass on the input
  " operation which should be either , or ;
  "
  " Do a double-jump if a single jump doesn't move to allow ; and , to work
  " intelligently when t or T is used.
  function! FindLastChar(count, op, ...)
    if exists('g:last_found_char') && g:last_found_char != ''
      call HighlightFoundChar()
    endif
    if a:0
      normal! gv
    endif
    if a:count==1
      let curpos=getpos('.')
      exec 'normal!' a:op
      if curpos==getpos('.')
        exec 'normal! 2'.a:op
      endif
    else
      exec 'normal! '.a:count.a:op
    endif
  endfunction
endif

-- 
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

Reply via email to