Comment briser les longues lignes dans vim?

12

J'ai un assez gros fichier texte formé de blocs comme

Short line.
Really long line.
Short line.

séparés par des lignes vides, et je voudrais utiliser vim (sous Linux) pour briser les longues lignes et obtenir des blocs comme

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

Mon problème avec gq(et gw) est qu'il redistribue chaque bloc comme un paragraphe entier, c'est-à-dire qu'il ne préserve pas les deux sauts de ligne dans chaque bloc, et selon :help fo-tableaucune des gqoptions de format de me permettrait de faire ce que je veux. J'ai également pensé que je pourrais atteindre mon objectif si je pouvais définir des caractères de nouvelle ligne comme délimiteurs de paragraphe, mais selon :help paragraphceux-ci, ils sont codés en dur.

Edit: je sais que je pourrais utiliser gqou gwformater chaque ligne longue une par une, mais comme mon fichier s'étend sur quelques milliers de lignes, je cherche un moyen d'y parvenir automatiquement.

AP
la source
Soit dit en passant: j'ai cherché des solutions à mon problème dans la documentation de vim, ici sur SU, et sur le Web, à venir vide. Je supprimerai volontiers cette question si j'ai oublié quelque chose d'évident.
AP
Il y a Puis-je justifier du texte dans Vim? à vi.sx .
Rétablir Monica - M. Schröder
@ MartinSchröder: Heureux de savoir qu'il existe un vi SE! Ces réponses ne résolvent pas mon problème, car je connaissais déjà gqet gw. Je suis également content de ne pas m'être arrêté là, sinon je n'aurais pas entendu parler de la :gcommande. :)
AP

Réponses:

16
:%norm! gww

Cela applique la normalcommande gww(qui formate la ligne actuelle comme avec gw) sur tout le tampon, sans tenir compte des mappages personnalisés (pour éviter les problèmes si par exemple gwa été mappé à autre chose).

Voir

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

Cette alternative est selon la suggestion de Ben dans les commentaires, et est plus simple que la solution d'origine, qui est enregistrée ci-dessous car elle pourrait mieux convenir dans d'autres circonstances similaires en raison de la capacité de correspondance d'expression régulière. Dans le cas "match toutes les lignes", il est cependant inutilement brut.


Application par programmation gwwsur chaque ligne individuelle du tampon:

:g/^/norm gww

Voir :help :get :help norm. ^correspond au début d'une ligne, ce qui en pratique fait correspondre chaque ligne.

On peut également choisir de ne sélectionner que les lignes plus longues que par exemple 60 caractères avec

:g/\%>60v/norm gww

(voir :help \%<) mais dans la pratique gww, les lignes ne seront reformatées que plus longtemps que de textwidthtoute façon, donc cela peut ne pas avoir beaucoup d'importance ni en vitesse ni en résultat.

(J'utilise vpour "colonne virtuelle" au lieu de cpour "colonne", car cette dernière calcule vraiment un certain nombre d'octets dans la ligne. Cela peut conduire à des résultats inattendus lors de l'utilisation de codages multi-octets, ce qui est souvent une raison de se méfier. En pratique, ce n'est pas un vrai problème pour la même raison que ci-dessus, car gwwcela ne reformatera pas les lignes plus courtes que de textwidthtoute façon.)

Daniel Andersson
la source
Échoue apparemment :gsans modèle, donc :g//norm gwwne fonctionne pas mais :g/.*/norm gwwfonctionne.
AP
@AP: Huh, travaille pour moi. J'utilise Vim 7.4.488-6 de Debian Unstable.
Daniel Andersson
4
:g//réutilise le dernier motif de recherche; s'il n'y en a pas, il échoue. Utilisez :g/^/pour appliquer à toutes les lignes.
Ingo Karkat
@IngoKarkat: Ah, c'est logique, puisque mon dernier modèle pendant les tests était celui qui connaissait la longueur de ligne que j'ai démontré plus tard. Je mettrai à jour la réponse. Savez-vous où dans l'aide ce comportement de "modèle vide" est mentionné? Je ne peux pas le trouver trivialement.
Daniel Andersson
En parcourant le manuel, il est probablement sous-entendu que les informations fournies :help last-patternpour une recherche normale s'appliquent également à la :globalcommande.
Daniel Andersson
4

Comme vous avez déjà lu le manuel des commandes gqet gw, je pense que vous voulez probablement quelque chose de plus pratique que de passer manuellement aux longues lignes, puis d'utiliser gw0, gw$ou une autre gwcommande pour formater uniquement la ligne actuelle.

Je ne connais pas un moyen facile de casser de longues lignes dans Vim sur un bloc de texte. Cependant, puisque vous avez mentionné que vous utilisez Vim sur un système GNU / Linux, je suggère de filtrer votre texte via la fmtcommande GNU .

Pour l'ensemble du dossier:

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

Pour le paragraphe actuel (en utilisant des options courtes):

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

Explication des fmtoptions pertinentes :

  • -w, --width=WIDTH- largeur de ligne maximale (75 colonnes par défaut). L'option -WIDTHest une forme abrégée de --width=DIGITS(si vous utilisez cette version abrégée, elle doit être la première option).

  • -s, --split-only- séparer les longues lignes, mais ne pas recharger; il s'agit de l'option qui préserve vos sauts de ligne durs préexistants.

Anthony Geoghegan
la source
Merci d'avoir mentionné fmt. J'ai préféré accepter l'autre réponse, car elle ne nécessite que vim.
AP
@AP Pas de soucis. C'est une excellente réponse et je l'aurais acceptée moi-même. Tant elle que votre question méritent des votes positifs.
Anthony Geoghegan
1

De:

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.

Placer le marqueur sur la ligne "lorem ipsum" et presser les gwwrendements (avec textwidth=40pour plus de clarté):

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.

qui me semble être ce que vous demandez. Sinon, n'hésitez pas à clarifier.

Daniel Andersson
la source