2010-10-13 14 views
34

Qualcuno sa trovare rapidamente la prossima occorrenza di un carattere (come il comando f) ma multi-linea? Cioè passare rapidamente alla prossima occorrenza di un personaggio in un file?Utilizzo del comando f di vim su più righe

+1

I [riassunto qui alcune alternative] (http://vi.stackexchange.com/questions/4486/expand-f-and-t-motion-to-next-lines#4525), incluso uno che ho aiutato a scrivere quale * lampeggia conta * sullo schermo! – joeytwiddle

risposta

35

Non è questo che "/" fa?

Se stai cercando la "x" successiva, fai/x mentre sei in modalità comando.

Poi si può colpire "n" per avanzare al prossimo x, e poi la prossima x, ecc

Ci sono un sacco di vim cheat sheets là fuori con tutti i tipi di punte.

+0

Grazie! In realtà sapevo di/e mi stavo chiedendo se sapessi di un modo più veloce (scusa se non l'ho detto nella domanda originale). Invece di digitare/e quindi di digitare c'è un unico modo per farlo? Grazie! – Koko

+4

hmm ... "fx" è composto da due sequenze di tasti. colpire "/ x " è di tre tasti. dopo la prima partita, puoi passare agli hit successivi con un altro tasto in entrambi i casi. chi oltre a un utente vi (m) potrebbe essere turbato da tale inefficienza :) Stai sempre cercando lo stesso personaggio o tipo di personaggio? In tal caso potrebbe esserci una soluzione, specialmente se si tratta di una programmazione correlata, come "passa alla prossima parentesi graffa" –

+0

@Koko - la risposta è sì, c'è un carattere per trovare l'occorrenza successiva, la lettera 'n' . E questo è incluso nella risposta. – KevinDTimm

12

C'è un esempio di ridefinizione di f per ignorare il caso nel file della guida "eval.txt".

:h eval.txt 

(ricerca per "ignorare caso" un paio di volte)

Possiamo modificare che per fare quello che vuoi. Aggiungi la seguente funzione al tuo file ~/.vimrc o, meglio ancora, crea un file plugin: ~/.vim/plugin/find-char.vim (crea le directory se non le hai già).

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

Poi, nel vostro ~/.vimrc aggiungere la seguente riga:

nmap f :call FindChar()<CR> 

Ora, f dovrebbe funzionare come si desidera.

BTW, questo è stato testato con Vim 7.2 su Ubuntu 10.04.

+1

questo non funzionerà se stai cercando '$', '\', '^' o '/' tra gli altri (anche forse stella, segno di interrogazione, ecc. Puoi lasciare let command = "normal!/\ V" c. "^ M" '. Ancora questo non funzionerà per il backslash. – Benoit

+2

@Benoit: Ahh, personaggi speciali, avrei dovuto saperlo meglio. Ho aggiornato la risposta. –

+1

È possibile saltare l'istruzione if se si antepone ogni modello di ricerca con '\ V' - funzione FindChar() lasciare c = nr2char (getchar()) let match = search ('\ V'. C) endfunction –

1

Si potrebbe fare una mappatura per andare al carattere successivo sotto il cursore:

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

l'\ V farà in modo che i simboli sono abbinati alla lettera.

Inoltre, potresti voler dare un'occhiata ai comandi * e #, che sono già definiti per te, sebbene potrebbero non essere ciò che desideri.

4

Aaaa, vimscript. Ci vogliono circa 2 anni per scrivere bene 20 righe: D. Ecco l'ultima versione più elegante: funziona per TUTTE le modalità: visiva, operatore in attesa, normale.

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 il super confuso:

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

aver voluto conoscere esattamente la stessa cosa che ho guardato attraverso le risposte qui. Nessuno di questi è esattamente quello che volevo, quindi ho messo insieme alcuni di essi.

La risposta di q335 era la più vicina perché gestisce gli omessi correttamente, è necessario fare qualcosa come dt} (elimina tutto fino a, ma non includendo la parentesi graffa successiva) ma la risposta di Curt gestisce la ricerca di caratteri speciali e utilizza una singola funzione che io sono molto più preferibile quindi non aggiungo troppo al mio.vimrc

Ecco il mio risultato:

"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

Sembrava funzionare bene, ma non manteneva il carattere cercato per l'uso di ';' e ',' – joeytwiddle

+0

Movimento alla chiusura parentesi graffa:]} - se si desidera eliminare: d]} - funziona anche per i parenti]) - il movimento per l'apertura delle parentesi graffe è [{ –

+0

Non funziona per me quando viene prefisso con un numero, ad es. 'c2fa' cambia in _prima_' a'. –

5

di Christian Brabandt ft_improved plugin estende il built-in f/t comandi per la ricerca in righe seguenti, troppo.

+3

Grazie, l'ho provato. Ma ho finito per usare http://github.com/dahu/vim-fanfingtastic (che può funzionare con i comandi '.' se installi anche http://github.com/tpope/vim-repeat). 9 mesi senza lamentele! – joeytwiddle

1

Il modo più ragionevole di farlo al momento è nascosto in this comment.

È sufficiente installare due plug-in: vim-repeat e vim-fanfingtastic.

Personalmente, io uso Vundle per gestire i miei plugin vim.

Quindi questo è il modo in cui si può fare f, F, ecc lavoro, se lo desideri:

  1. Installare Vundle.
  2. Aggiungere queste righe al .vimrc:

    Plugin 'tpope/vim-repeat' 
    Plugin 'dahu/vim-fanfingtastic' 
    
  3. Run $ vim +PluginInstall +qall nella shell.
  4. Voilà!
1

Un approccio a questo problema è utilizzare il plug-in easymotion.

Ciò consente di utilizzare movimenti come f attraverso l'intera finestra di testo visibile. Attiva il plug-in, quindi inserisci f e il personaggio che stai cercando. Evidenzia ogni posizione in cui il carattere appare sullo schermo in un colore di evidenziazione (ad esempio rosso) e mostra la posizione utilizzando una lettera (a, b, c, d, ...). Basta premere la lettera corrispondente alla posizione in cui si desidera saltare.

Il README del plugin su Github include un'animazione che mostra visivamente come funziona.