Wednesday, August 1, 2012

Re: What's the best way to move to an arbitrary location on your screen?

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

No comments: