2010-10-13 18 views
34

¿Alguien sabe cómo encontrar rápidamente la siguiente aparición de un carácter (como el comando f) pero multilíneas? Es decir. para saltar rápidamente a la siguiente aparición de algún personaje en un archivo?Uso del comando f de vim en varias líneas

+1

I [resumió algunas alternativas aquí] (http://vi.stackexchange.com/questions/4486/expand-f-and-t-motion-to-next-lines#4525), incluido uno que ayudé a escribir qué * flashes cuenta * en la pantalla! – joeytwiddle

Respuesta

35

¿No es eso lo que "/" hace?

Si está buscando la siguiente "x", haga do/x en modo comando.

entonces puede presionar "n" para avanzar a los siguientes x, y luego el siguiente x, etc.

Hay un montón de vim cheat sheets por ahí con todo tipo de consejos.

+0

Gracias! De hecho, sabía de/y me preguntaba si conoces de una manera más rápida (lo siento, no lo dije en la pregunta original). En lugar de escribir/y luego necesitar escribir , ¿hay una forma clave de hacerlo? ¡Gracias! – Koko

+4

hmm ... "fx" tiene dos teclas. presionar "/ x " tiene tres teclas. después del primer partido, puedes avanzar a los siguientes con otra pulsación de tecla en ambos casos. quién además de un vi (m) usuario podría estar molesto por tal ineficiencia :) ¿Siempre estás buscando el mismo personaje o tipo de personaje? De ser así, puede haber una solución para usted, especialmente si está relacionada con la programación, como "pasar a la siguiente llave" –

+0

@Koko - la respuesta es, sí, hay un personaje para encontrar la siguiente ocurrencia, la letra 'n' . Y eso está incluido en la respuesta. – KevinDTimm

12

Hay un ejemplo de redefinición de f para ignorar el caso en el archivo de ayuda 'eval.txt'.

:h eval.txt 

(búsqueda de "ignorar caso" un par de veces)

Podemos modificar eso para hacer lo que quiera. Agregue la siguiente función a su archivo ~/.vimrc o mejor aún, cree un archivo de complemento: ~/.vim/plugin/find-char.vim (cree los directorios si aún no los tiene).

function FindChar() 
    let c = nr2char(getchar()) 
    let match = search('\V' . c) 
endfunction 

Luego, en su ~/.vimrc añadir la siguiente línea:

nmap f :call FindChar()<CR> 

Ahora, f debería funcionar como usted desea.

Por cierto, esto fue probado con Vim 7.2 en Ubuntu 10.04.

+1

esto no funcionará si está buscando '$', '\', '^' o '/' entre otros (también puede ser estrella, marca de interrogación, etc.) '' command = "normal!/\ V" . c. "^ M" '. Todavía esto no funcionará para la barra invertida. – Benoit

+2

@Benoit: Ahh, personajes especiales, debería haberlo sabido mejor. He actualizado la respuesta. –

+1

Puede omitir la instrucción if si solo antepone todos los patrones de búsqueda con '\ V' - función FindChar() let c = nr2char (getchar()) let match = search ('\ V'. C) endfunction –

1

Se podría hacer un mapeo para ir al siguiente carácter bajo el cursor:

:map f yl/\V<c-r>"<c-m> 

la \ V se asegurará de que los símbolos se hacen coincidir literalmente.

Además, es posible que desee consultar los comandos * y #, que ya están definidos para usted, aunque es posible que no sean los que usted desea.

4

Aaaa, vimscript. Toma aproximadamente 2 años escribir bien 20 líneas: D. Aquí está la última y más elegante versión: funciona para TODOS los modos: visual, operador pendiente, normal.

let prvft='f' 
let prvftc=32 
fun! MLvF(c,...) 
    let [g:prvftc,g:prvft]=[a:c,a:0? 'f':'F'] 
    let pos=searchpos('\C\V'.nr2char(g:prvftc),'bW') 
    call setpos("'x", pos==[0,0]? [0,line('.'),col('.'),0] : [0,pos[0],pos[1],0]) 
    return "`x" 
endfun 
fun! MLvf(c,...) 
    let [g:prvftc,g:prvft]=[a:c,a:0? 'F':'f'] 
    let pos=searchpos('\C\V'.nr2char(g:prvftc).(mode(1)=='no'? '\zs' : ''),'W') 
    call setpos("'x", pos==[0,0]? [0,line('.'),col('.'),0] : [0,pos[0],pos[1],0]) 
    return "`x" 
endfun 
fun! MLvT(c,...) 
    let [g:prvftc,g:prvft]=[a:c,a:0? 't':'T'] 
    let pos=searchpos('\C\V'.nr2char(g:prvftc).'\zs','bW') 
    call setpos("'x", pos==[0,0]? [0,line('.'),col('.'),0] : [0,pos[0],pos[1],0]) 
    return "`x" 
endfun 
fun! MLvt(c,...) 
    let [g:prvftc,g:prvft]=[a:c,a:0? 'T':'t'] 
    let pos=searchpos('\C\V\_.'.(mode(1)=='no'? '\zs' : '').nr2char(g:prvftc),'W') 
    call setpos("'x", pos==[0,0]? [0,line('.'),col('.'),0] : [0,pos[0],pos[1],0]) 
    return "`x" 
endfun 
no <expr> F MLvF(getchar()) 
no <expr> f MLvf(getchar()) 
no <expr> T MLvT(getchar()) 
no <expr> t MLvt(getchar()) 
no <expr> ; MLv{prvft}(prvftc) 
no <expr> , MLv{prvft<#'Z'? tolower(prvft) : toupper(prvft)}(prvftc,1) 

o el Super ilegible:

let [pvft,pvftc]=[1,32] 
fun! Multift(x,c,i) 
    let [g:pvftc,g:pvft]=[a:c,a:i] 
    let pos=searchpos((a:x==2? mode(1)=='no'? '\C\V\_.\zs' : '\C\V\_.' : '\C\V').(a:x==1 && mode(1)=='no' || a:x==-2? nr2char(g:pvftc).'\zs' : nr2char(g:pvftc)),a:x<0? 'bW':'W') 
    call setpos("'x", pos[0]? [0,pos[0],pos[1],0] : [0,line('.'),col('.'),0]) 
    return "`x" 
endfun 
no <expr> F Multift(-1,getchar(),-1) 
no <expr> f Multift(1,getchar(),1) 
no <expr> T Multift(-2,getchar(),-2) 
no <expr> t Multift(2,getchar(),2) 
no <expr> ; Multift(pvft,pvftc,pvft) 
no <expr> , Multift(-pvft,pvftc,pvft) 
6

haber querido saber exactamente lo mismo que yo miraba a través de las respuestas aquí. Ninguno de ellos es exactamente lo que yo quería, así que improvisé algunos de ellos.

La respuesta de q335 fue la más cercana porque maneja correctamente omaps que es necesario para hacer algo como dt} (eliminar todo hasta, pero sin incluir el siguiente corchete) pero la respuesta de Curt maneja búsquedas especiales de caracteres y utiliza una función única que yo es mucho más preferible así que no estoy agregando demasiado a mi.vimrc

Aquí está mi resultado:

"Makes f and t work across multiple lines 
nmap <silent> f :call FindChar(0, 0, 0)<cr> 
omap <silent> f :call FindChar(0, 1, 0)<cr> 
nmap <silent> F :call FindChar(1, 0, 0)<cr> 
omap <silent> F :call FindChar(1, 1, 0)<cr> 
nmap <silent> t :call FindChar(0, 0, 1)<cr> 
omap <silent> t :call FindChar(0, 0, 0)<cr> 
nmap <silent> T :call FindChar(1, 0, 1)<cr> 
omap <silent> T :call FindChar(1, 0, 0)<cr> 

"Functions 
fun! FindChar(back, inclusive, exclusive) 
    let flag = 'W' 
    if a:back 
    let flag = 'Wb' 
    endif 
    if search('\V' . nr2char(getchar()), flag) 
    if a:inclusive 
     norm! l 
    endif 
    if a:exclusive 
     norm! h 
    endif 
    endif 
endfun 
+0

Parecía funcionar bien, pero no retenía el carácter buscado para usar ';' y ',' – joeytwiddle

+0

Movimiento para cerrar la llave:]} - si desea eliminar: d]} - también funciona para los parens]): el movimiento para abrir llaves es [{ –

+0

] No funciona para mí cuando se agrega un número, por ejemplo, 'c2fa' cambia hasta el _first_' a'. –

5

de Christian Brabandt ft_improved plugin extiende la incorporada en f/t comandos para buscar en las líneas siguientes, también.

+3

Gracias, lo probé. Pero terminé usando http://github.com/dahu/vim-fanfingtastic (que puede funcionar con comandos '.' si también instalas http://github.com/tpope/vim-repeat). 9 meses sin quejas! – joeytwiddle

1

La forma más razonable de hacerlo en este momento está oculta en this comment.

Solo tiene que instalar dos complementos: vim-repeat y vim-fanfingtastic.

Personalmente, uso Vundle para administrar mis complementos de vim.

Así que esta es la forma en que puede hacer f, F, etc. trabajo como desee:

  1. Instalar Vundle.
  2. Añadir estas líneas a su .vimrc:

    Plugin 'tpope/vim-repeat' 
    Plugin 'dahu/vim-fanfingtastic' 
    
  3. Run $ vim +PluginInstall +qall en su concha.
  4. Voila!
1

Un enfoque a este problema es utilizar el plugin easymotion.

Esto le permite usar movimientos como f en toda la ventana de texto visible. Usted activa el complemento, luego ingrese f y el caracter que está buscando. Resalta cada posición en la que el personaje aparece en la pantalla en un color resaltado (por ejemplo, rojo) y muestra la posición usando una letra (a, b, c, d, ...). Simplemente presione la letra correspondiente a la posición a la que desea saltar.

El README del plugin en Github incluye una animación que muestra visualmente cómo funciona.

Cuestiones relacionadas