Come spezzare le lunghe file in vim?


12

Ho un file di testo abbastanza grande formato da blocchi come

Short line.
Really long line.
Short line.

separati da linee vuote, e vorrei usare vim (su Linux) per abbattere le lunghe file e ottenere blocchi simili

Short line.
This was
part of
a long line.
Short line.

Il mio problema con gq(e gw) è che ridisegna ogni blocco come un intero paragrafo, ovvero non conserva le due interruzioni di riga all'interno di ciascun blocco e, in base a :help fo-tablenessuna delle gqopzioni di formato, mi consentirebbe di fare ciò che voglio. Ho anche pensato che avrei potuto raggiungere il mio obiettivo se avessi potuto definire i caratteri di nuova riga come delimitatori di paragrafo, ma secondo :help paragraphquesti sono codificati.

Modifica: so che potrei usare gqo gwformattare ciascuna riga lunga una per una, ma poiché il mio file si estende su alcune migliaia di righe, sto cercando un modo per raggiungere questo obiettivo automaticamente.


A proposito: ho cercato soluzioni al mio problema nella documentazione di Vim, qui su SU, e sul web, risultando vuota. Eliminerò volentieri questa domanda se ho trascurato qualcosa di ovvio.
AP


@ MartinSchröder: felice di sapere che c'è un SE SE! Quelle risposte non risolvono il mio problema, però, dal momento che ne sapevo già gqe gw. Sono anche felice di non essermi fermato qui, altrimenti non avrei saputo del :gcomando. :)
AP

Risposte:


16
:%norm! gww

Questo applica il normalcomando gww(che formatta la riga corrente come con gw) sull'intero buffer, senza tenere conto dei mapping personalizzati (per evitare problemi se, ad esempio, gwè stato mappato a qualcos'altro).

Vedere

  • :help :%
  • :help :norm
  • :help gww

Questa alternativa è secondo il suggerimento di Ben nei commenti, ed è più semplice della soluzione originale, che viene salvata di seguito poiché potrebbe adattarsi meglio in altre circostanze simili a causa della capacità di corrispondenza delle espressioni regolari. Nel caso "abbina tutte le linee", però, è inutilmente bruto.


Applicando programmaticamente gwwsu ogni singola riga del buffer:

:g/^/norm gww

Vedi :help :ge :help norm. ^corrisponde all'inizio di una riga, che in pratica rende questa corrispondenza ogni riga.

Si può anche scegliere di selezionare solo righe più lunghe di es. 60 caratteri con

:g/\%>60v/norm gww

(vedi :help \%<) ma in pratica gwwriformatterà le linee solo più a lungo di textwidthcosì, quindi potrebbe non avere molta importanza né in termini di velocità né di risultati.

(Sto usando vper "colonna virtuale" invece che cper "colonna", poiché quest'ultimo calcola davvero un certo numero di byte nella riga. Ciò può portare a risultati imprevisti quando si utilizzano codifiche multibyte, che spesso è un motivo per diffidare. In pratica non è un vero problema per lo stesso motivo di cui sopra, per quanto riguarda questo gwwnon riformatterà le linee più corte di textwidthcomunque.)


Apparentemente :gfallisce senza uno schema, quindi :g//norm gwwnon funziona ma :g/.*/norm gwwfunziona.
AP

@AP: Huh, lavora per me. Sto usando Vim 7.4.488-6 da Debian Unstable.
Daniel Andersson,

4
:g//riutilizza l'ultimo modello di ricerca; se non ce n'è nessuno, fallisce. Utilizzare :g/^/per applicare a tutte le righe.
Ingo Karkat,

@IngoKarkat: Ah, ha senso, dal momento che il mio ultimo schema durante i test è stato quello della lunghezza della linea che ho dimostrato in seguito. Aggiornerò la risposta. Sai in quale punto dell'aiuto viene menzionato questo comportamento "modello vuoto"? Non riesco a trovarlo banalmente.
Daniel Andersson,

Esaminando il manuale, è probabilmente implicito che le informazioni fornite :help last-patternper la ricerca normale si applicano anche al :globalcomando.
Daniel Andersson,

4

Dato che hai già letto il manuale per i comandi gqe gw, immagino che probabilmente desideri qualcosa di più conveniente che spostarti manualmente sulle righe lunghe e quindi utilizzare gw0, gw$o un altro gwcomando per formattare solo la riga corrente.

Non conosco un modo semplice per spezzare le lunghe righe in Vim su un blocco di testo. Tuttavia, dal momento che hai detto che stai usando Vim su un sistema GNU / Linux, ti suggerirei di filtrare il tuo testo tramite il fmtcomando GNU .

Per l'intero file:

:%!fmt --width=75 --split-only

Per il paragrafo corrente (utilizzando le opzioni brevi):

:'{,'}!fmt -75 -s

Spiegazione delle fmtopzioni pertinenti sono:

  • -w, --width=WIDTH- larghezza massima della linea (impostazione predefinita di 75 colonne). L'opzione -WIDTHè una forma abbreviata di --width=DIGITS(se si utilizza questa versione abbreviata, deve essere la prima opzione).

  • -s, --split-only- dividere le linee lunghe, ma non riempire; questa è l'opzione che preserva le tue interruzioni di linea dura preesistenti.


Grazie per averlo menzionato fmt. Ho preferito accettare l'altra risposta, però, perché richiede solo VIM.
AP

@AP Nessun problema. È un'ottima risposta e l'avrei accettata da solo. Sia esso che la tua domanda meritano voti positivi.
Anthony Geoghegan,

1

A partire dal:

Short line.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Short line.

Posizionando il marker sulla riga "lorem ipsum" e premendo i gwwrendimenti (con textwidth=40per chiarezza):

Short line.
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
Short line.

che per me sembra quello che stai chiedendo. In caso contrario, non esitare a chiarire.

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.