Word Wrap dans Vim (en préservant l'indentation)

92

Je regardais juste ce post qui décrit comment envelopper des mots entiers dans vim. La solution acceptée était la suivante:

:set formatoptions=l
:set lbr

Ce qui prend ce texte (les onglets sont affichés comme \ t):

 *Inside of window                        *Outside of window
|---------------------------------------|    
|\t\tthis is a like of text that will wr|ap here                            
|\t\tcan you see the wrap               |
|                                       |
|---------------------------------------|

Cela accomplit un comportement comme celui-ci (les onglets sont affichés comme \ t):

 *Inside of window                        *Outside of window
|---------------------------------------|    
|\t\tthis is a like of text that will   |
|wrap here                              |
|\t\tcan you see the wrap               |
|                                       |
|---------------------------------------|

Je voudrais cependant redéfinir cette fonction. Je voudrais que la ligne enveloppée ait le même nombre d'onglets devant elle que la ligne ci-dessus a plus un. C'est à dire:

 *Inside of window                        *Outside of window
|---------------------------------------|    
|\t\tthis is a like of text that will   |
|\t\t\twrap here                        |
|\t\tcan you see the wrap               |
|                                       |
|---------------------------------------|

Des idées?

soixantefootersdude
la source
34
+1 pour l'effort déployé pour rendre la question aussi claire que possible.
Jeffrey Jose
Voulez-vous que le texte soit enveloppé de manière souple au bord de la fenêtre ou que le texte soit enveloppé lorsque la ligne atteint une certaine longueur? Je pense que vous voulez un enveloppement rigide (où une nouvelle ligne est insérée dans votre texte après le mot «will»), mais c'est difficile à dire à partir de vos exemples.
Bill Odom
@Bill, je suis surtout intéressé par le softwrapping mais une solution de hardwrapping serait également acceptable.
sixtyfootersdude
1
La fonctionnalité souhaitée n'est actuellement pas intégrée à Vim. Il y a cependant un correctif qui se rapproche: groups.google.com/group/vim_dev/web/vim-patches (il s'agit du n ° 15, "Mettre correctement en retrait les lignes encapsulées ").
Bill Odom
En relation: VimCasts a eu un bel épisode sur l'utilisation d'utilitaires Unix externes pour gérer ce problème: vimcasts.org/e/18
Damien Wilson

Réponses:

18

Le patch breakindent a ce que vous recherchez. Je l'ai appliqué avec succès en utilisant les instructions trouvées dans ce fil:

Patch Vim avec le patch breakindent sur OS X avec Homebrew

Plus précisément, la formule Homebrew d'Echristopherson.

Je sais que ce fil est ancien, mais il est populaire sur Google et je l'ai rencontré plusieurs fois en essayant de trouver une solution.

EDIT: Ce patch est maintenant inclus avec vim en tant que patch 7.4.338. Voir: https://retracile.net/blog/2014/07/18/18.00

Sur Yosemite (Mac OS X), j'ai utilisé la commande de snowbound avec hombrew:

brew install macvim --with-features=huge --override-system-vim --HEAD 
Sortie42
la source
le patch ne semble pas fonctionner avec le dernier macvim sur homebrew? @ Exit42 comment l'avez-vous fait fonctionner?
enneigé le
nvm. J'ai compilé macvim avec un homebrew à la pointe de la technologiebrew install macvim --with-features=huge --override-system-vim --HEAD
enneigé le
1
Voir ma réponse ci-dessous: stackoverflow.com/questions/2828174/… Pas besoin d'un correctif dans les nouvelles versions de vim.
JoshuaD
26

Cela n'a pas fonctionné lorsque la question a été posée à l'origine, mais à partir du 25 juin 2014, cela fonctionnera. (En supposant que vous mettez à jour votre vim vers une version plus récente que cette date)

Ajoutez à votre .vimrc:

" Indents word-wrapped lines as much as the 'parent' line
set breakindent
" Ensures word-wrap does not split words
set formatoptions=l
set lbr

Et c'est tout!

-

Certaines personnes (moi y compris) partagent un seul fichier .vimrc sur plusieurs ordinateurs. Dans ce cas, il est important que cette ligne soit robuste (pour éviter les messages d'erreur ennuyeux). C'est un peu mieux:

if has("patch-7.4.354")
    " Indents word-wrapped lines as much as the 'parent' line
    set breakindent
    " Ensures word-wrap does not split words
    set formatoptions=l
    set lbr
endif

De cette façon, si vous utilisez une version antérieure de vim, vous n'obtenez pas de message d'erreur.

JoshuaD
la source
Fait intéressant, cela fonctionne sur la vim 7.4 de mon cygwin mais pas dans la vim 7.4 de mon ununtu. Je suppose qu'il doit être un peu plus répandu, mais il sera bientôt adopté par tous.
JoshuaD
1
Fonctionne dans Vim 7.4 @ ArchLinux.
Andy Mikhaylenko
1
Vous pouvez utiliser ce test à la place:if has("patch-7.4.354")
Lawrence Kesteloot
Cela ne répond pas à la question concernant la remarque d'OP: le même nombre d'onglets (...) plus un . C'est d'ailleurs très important à mon avis aussi, vous voudrez peut-être souvent garder une indentation supplémentaire et décaler optiquement les segments enveloppés vers la droite (listes bien agencées, notes, etc.);
sanglant
8

Le mieux que vous obtiendrez est l' showbreakoption qui mettra une chaîne fixe devant chaque ligne enveloppée (j'utilise set showbreak=...).

trop de php
la source
@AlexanderBird Selon :help 'showbreak', non, vous ne pouvez pas - showbreakn'est qu'une chaîne.
Rory O'Kane
4

Je suis d'accord avec la réponse qui dit que le «showbreak» est la meilleure option. Showbreak ne vous permet généralement pas de mettre des caractères non imprimables (par exemple, des espaces ou des tabulations) dans la chaîne showbreak, donc comme il est généralement utilisé, il vous donnera juste un indicateur le long de la marge gauche, c'est-à-dire pas de véritable retrait. Ce n'est pas génial, car l'objectif principal d'OP, je pense, est de donner aux lignes enveloppées un retrait pour les empêcher d'encombrer la zone de marge gauche et de ressembler à des lignes qui leur sont propres.

Donc, une façon d'ajouter un (laid) retrait en utilisant showbreak est simplement d'utiliser beaucoup de caractères, .eg, ": set showbreak => --------------->". Cela donne quelque chose qui ressemble à ceci:

 *Inside of window                        *Outside of window
|---------------------------------------|    
|\t\tthis is a like of text that will   |
|>--------------->wrap here             |
|\t\tcan you see the wrap               |
|                                       |
|---------------------------------------|

Une meilleure alternative pourrait être d'utiliser des caractères d'espacement insécables (en supposant que votre instance de Vim soit activée par unicode), chacun d'entre eux pouvant être entré dans la chaîne showbreak à l'aide de la séquence de touches ctrl-v, 160. De cette façon, vous pouvez entrer une chaîne showbreak qui est vide sur le côté gauche et qui semble être un véritable retrait. Par exemple, ": set showbreak =........... >>" où chaque '.' dans la commande est en fait un caractère d'espace insécable entré en appuyant sur ctrl-V, 160. De cette façon, vous vous retrouvez avec une enveloppe qui est bien en retrait, comme ceci:

 *Inside of window                        *Outside of window
|---------------------------------------|    
|\t\tthis is a like of text that will   |
|            >>wrap here                |
|\t\tcan you see the wrap               |
|                                       |
|---------------------------------------|

Vous n'avez toujours pas la possibilité de faire varier le niveau de retrait en fonction du retrait de la ligne précédente, mais au moins vous obtenez un retrait net des lignes enveloppées sans beaucoup d'encombrement visuel le long de la marge gauche de la fenêtre. Il pourrait encore y avoir de la confusion si le retrait d'une ligne encapsulée est inférieur à celui du début d'une ligne réelle, mais cela pourrait peut-être être évité en rendant le "retrait" du showbreak assez grand (c'est-à-dire plus grand que tout retrait couramment trouvé dans votre code ) mais suffisamment petit pour offrir suffisamment d'espace pour un habillage lisible du texte. Pour de nombreuses utilisations, je pense qu'un retrait showbreak de 40 ou 50 espaces ferait assez bien cela.

Herbert Sitz
la source
7
Vous pouvez mettre des espaces dans showbreak par leur échapper: :set showbreak=\ \ \ \ . Cependant, cela ne fonctionne toujours pas pour les onglets.
Bill Odom