Come posso spostarmi verticalmente fino a raggiungere un carattere non bianco?


27

In un file molto lungo con codice (con precisione) rientrato, può essere utile spostarsi direttamente su una riga di testo sopra o sotto il cursore che delimita il rientro.

(Un modo per farlo potrebbe essere tramite il metodo di piegatura del rientro, piegando il livello di rientro corrente, che comprime le linee che delimitano il livello di rientro in modo che siano solo a jo klontane dal cursore. Tuttavia, ho trovato casi in cui la piegatura del rientro non ha stato in grado di lavorare sul trattino che mi interessa.)

Ecco un esempio, con il cursore contrassegnato dal trattino basso _(nella seconda colonna di caratteri tra le definizioni di class Bazze class Qux), ma immagina che il numero di paragrafi o linee all'interno della modules sia sconosciuto o variabile:

module Foo
  # lots of code...
end

module Bar
  class Baz
    # ...
  end

  class Bazz
    # lots of code...
  end
 _
  class Qux
    # ...
  end

  class Quux
    # lots of code...
  end
end

... come potrei navigare rapidamente verso il odi module Barsopra del cursore o il ndi endsotto il cursore all'ultima riga? Si noti che la colonna verticale contiene spazi bianchi, ma anche nessun carattere nella seconda colonna tra le classdefinizioni.


2
correlati: "Passa alla riga successiva / precedente con lo stesso rientro" su Vim Tips Wiki vim.wikia.com/wiki/Move_to_next/…
alxndr

Premendo g, quindi il tasto di direzione, è possibile evitare le schede e spostarsi tra le righe
SibiCoder

1
La soluzione nel link di @ alxndr funziona bene tranne nel caso in cui lo spazio bianco sia scarsamente gestito (ad esempio, ci sono linee casuali che hanno solo spazi bianchi) e si desidera ignorare lo spazio bianco. La soluzione del superjer di seguito è migliore se uno è preoccupato per quel caso.
nukeguy,

Risposte:


9

Che ne dici di questa funzione?

function FloatUp()
    while line(".") > 1
                \ && (strlen(getline(".")) < col(".")
                \ || getline(".")[col(".") - 1] =~ '\s')
        norm k
    endwhile
endfunction

Potresti nnoremap gU :call FloatUp()<CR>( gUper "salire"), quindi invocare con gU.

Ecco una spiegazione:

  • Il codice sposta ripetutamente verso l'alto il cursore (con norm k) finché la whilecondizione è valida.
  • La whilecondizione vale se questa non è la prima riga ( line(".") > 1) e neanche
    • questa linea è troppo corta (probabilmente vuota); o
    • il carattere della linea corrente ( getline(".")) nella colonna corrente ( [col(".") - 1]) è spazio bianco ( =~ '\s'; cioè, corrisponde al modello di spazio bianco).

1
Questo sembra funzionare perfettamente (e rapidamente), e può essere facilmente modificato anche in una FloatDownfunzione. Nel mio .vimrc va, grazie! github.com/alxndr/dotfiles/commit/0e25a302
alxndr

1
Ho appena scoperto che questa soluzione non funziona in modalità visiva (comportamento leggermente diverso a seconda della modalità visiva, rimarrà nella stessa posizione o si muoverà di una sola riga). Qualche suggerimento su cosa sta succedendo lì?
alxndr,

13

Mi piace usare la ricerca di queste cose, perché le regex di Vim hanno una quantità folle di cose che puoi cercare, come numeri di colonna virtuali specifici, in questo caso:

nnoremap cd /\%<C-R>=virtcol(".")<CR>v\S<CR>

nnoremap cu ?\%<C-R>=virtcol(".")<CR>v\S<CR>

Usa cdper scendere e cuper salire. Sto pensando "colonna su" e "colonna giù" qui. Sono quasi sicuro al 100% che queste non sono operazioni predefinite. O scegli le tue mappature.

Questo dovrebbe funzionare indipendentemente dal fatto che tu stia utilizzando schede o spazi o entrambi.


1
Sto riscontrando problemi nell'analizzare questi comandi. Ti dispiacerebbe espandersi un po 'su di loro?
davidlowryduda,

1
/ o ? per cercare verso il basso o verso l'alto, \% xv limita la ricerca al numero di colonna virtuale 'x', la 'x' in questo caso è '<CR> = virtcol (".") <CR>' che esegue il comando virtcol e inserisce il numero di colonna virtuale su cui si trova il cursore nell'espressione, \ S indica qualsiasi carattere non bianco.
Chad,

1
Grazie per aver spiegato Chad. Aggiungerò semplicemente che <CR> nella modalità Inserisci o nella riga di comando prende il contenuto di un registro. Il =registro è il registro delle espressioni che valuta un'espressione in atto. È molto utile, se non un po 'strano.
superjer

1
Uno svantaggio di questo approccio è che se si dispone dell'evidenziazione della ricerca, scoprirai che tutti i caratteri nella colonna verticale del cursore sono ora evidenziati dopo "colonna su" ing o "colonna giù" ing.
alxndr,

3
Se vuoi proteggere la tua ricerca esistente puoi anteporre :let searchbak=@/<CR>e aggiungere :let @/=searchbak<CR>. Ma a questo punto sta diventando un po 'lungo e inavvicinabile e forse dovrebbe essere solo una funzione.
superjer il

7

È possibile utilizzare il plugin JumpToVerticalOccurrence (impostazione predefinita mappata su ]|e [|). Ci sono pochi altri come i ]V{char}quali funzionano f, ma in verticale. Ovviamente puoi rimapparli come richiesto.


Se non si desidera utilizzare plug-in, è possibile provare a utilizzare :searchcon virtcol(.), ad esempio:

:call search('\%' . virtcol('.') . 'v\S', 'bW')

dove:

  • virtcol('.') ti dà la colonna corrente,
  • \S sta per non-spazi bianchi
  • bW è per la ricerca all'indietro

Controlla :help searchper saperne di più.

Per facilitarne l'utilizzo, è possibile mapparlo, ad esempio:

:map <C-k> :call search('\%' . virtcol('.') . 'v\S', 'bW')<CR>
:map <C-j> :call search('\%' . virtcol('.') . 'v\S', 'W')<CR>

In alternativa, se il codice contiene parentesi, l'uso %di saltare tra loro corrispondenza (ad esempio {, }, [, ], etc.) o utilizzare intero paragrafo salti ( {, }con Shiftse necessario).


Link / Fonti:


Da :h search(): wmezzo wrap around the end of the filee Wmezzo don't wrap around the end of the file. Ma perché li hai messi insieme sul secondo :map?
Jair López,

@JairLopez Correct, wnon dovrebbe essere lì, quindi l'ho rimosso, grazie. Probabilmente ero confuso dal significato dei tasti di movimento.
Kenorb,

3

Uso una versione modificata del plug -in vim-indent-object per fornire questo comportamento. Le mie modifiche sono visibili qui .

Questo mi permette di mappare [iper andare all'inizio del livello di rientro corrente e ]iper andare alla fine.


2

Non è esattamente quello che hai chiesto perché non è un movimento verticale, ma qualcosa che è simile, veloce, e potrebbe essere abbastanza buono per voi si muove all'indietro 2 paragrafi: {{. Questo ti porterà alla linea subito prima module Bar.


2
Immagina che ci sia un numero sconosciuto di linee e / o paragrafi tra il cursore e la sua modulelinea di livello superiore . (In particolare, questa situazione si è verificata quando di recente stavo navigando su un codice di terze parti lungo diverse migliaia di righe, con rientro accurato ma senza righe vuote, e cercando di trovare il contesto esterno della definizione di un modulo.)
alxndr,

Saltare per paragrafi è il mio modo preferito di spostarmi, ma non era un'opzione: l'intero file era un "paragrafo".
alxndr,


1

Per questo uso il mio plug-in move_until_char_changes.vim .

Lo associo a gKe gJ.

Passerà su molte righe con lo stesso carattere nella colonna corrente (non solo gli spazi bianchi), che può essere utile nei file di log o nei dump SQL con stringhe ripetute.

Di default si sposta prima di una riga, prima di prendere il carattere "cerca".

Funziona in modalità Visual a condizione che non si provi a usarlo due volte e non ci si trovi in ​​modalità Visual in linea o in blocco ... (correzioni benvenute!)


1

Dal momento che non lo vedo qui come una risposta ( modifica appena notato che il superjer ha menzionato qualcosa di molto simile). Puoi semplicemente il / o? ricerca.

Ad esempio, puoi cercare verso il basso un carattere non bianco nella seconda colonna in questo modo:

/\%2v\S

La ripartizione è:

/    "search downward (use ? for upward movement)
\%2v "for the following char in the 2nd virtual column
\S   "any non white space character

Quindi è possibile utilizzare i normali operatori per ripetere la ricerca.

Per maggiori informazioni sull'argomento vedi :help \%ce :help \%v.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.