Envoltura inteligente en Vim

80

Me he estado preguntando si Vim tiene la capacidad de ajustar de forma inteligente líneas de código, de modo que mantenga la misma sangría que la línea que está sangrando. Lo he notado en algún otro editor de texto, como el editor de texto electrónico, y descubrí que me ayudó a comprender más fácilmente lo que estoy viendo.

Por ejemplo en lugar de

<p>
    <a href="http://www.example.com">
        This is a bogus link, used to demonstrate
an example
    </a>
</p>

aparecería como

<p>
    <a href="somelink">
        This is a bogus link, used to demonstrate
        an example
    </a>
</p>
Sasha
fuente
Consulte también stackoverflow.com/q/759577/240633
ergosys
Debe volver a revisar las respuestas ya que las cosas han cambiado.
1
Uso :set autoindenty:set smartindent
Shammel Lee

Respuestas:

62

Esta función se implementó el 25 de junio de 2014 como parche 7.4.338. Siguieron algunos parches que refinaron la función, siendo el último 7.4.354, por lo que esa es la versión que querrá.

:help breakindent
:help breakindentopt

Extractos de la ayuda de vim a continuación:

'breakindent'     'bri'   boolean (default off)
                          local to window
                          {not in Vi}
                          {not available when compiled without the |+linebreak|
                          feature}
        Every wrapped line will continue visually indented (same amount of
        space as the beginning of that line), thus preserving horizontal blocks
        of text.

'breakindentopt' 'briopt' string (default empty)
                          local to window
                          {not in Vi}
                          {not available when compiled without the |+linebreak|
                          feature}
        Settings for 'breakindent'. It can consist of the following optional
        items and must be seperated by a comma:
                  min:{n}     Minimum text width that will be kept after
                              applying 'breakindent', even if the resulting
                              text should normally be narrower. This prevents
                              text indented almost to the right window border
                              occupying lot of vertical space when broken.
                  shift:{n}   After applying 'breakindent', wrapped line
                              beginning will be shift by given number of
                              characters. It permits dynamic French paragraph
                              indentation (negative) or emphasizing the line
                              continuation (positive).
                  sbr         Display the 'showbreak' value before applying the 
                              additional indent.
        The default value for min is 20 and shift is 0.

También es relevante para esto la showbreakconfiguración, esto agregará como sufijo la cantidad de su turno con los caracteres que especifique.

Configuración de ejemplo

" enable indentation
set breakindent

" ident by an additional 2 characters on wrapped lines, when line >= 40 characters, put 'showbreak' at start of line
set breakindentopt=shift:2,min:40,sbr

" append '>>' to indent
set showbreak=>>   

Nota sobre el comportamiento

Si no especifica la sbropción, showbreakcualquier carácter que se agregue a la sangría. La eliminación sbrdel ejemplo anterior provoca una sangría efectiva de 4 caracteres; con esa configuración, si solo desea usar showbreaksin sangría adicional, especifique shift:0.

También puede dar un desplazamiento negativo, lo que tendría el efecto de arrastrar showbreakcaracteres y texto envuelto de nuevo a cualquier espacio de sangría disponible.

Al especificar un minvalor, la cantidad desplazada se aplastará si el ancho de su terminal es más estrecho, pero los showbreakcaracteres siempre se conservan.

Dominykas Mostauskis
fuente
2
En resumen, agregar set breakindenta su configuración de vim hará que la línea se salte y se ajuste en la sangría, en lugar de romper y comenzar en la siguiente línea como si fuera una nueva línea.
james2doyle
3
Y agregar set breakindentopt=shift:4a su configuración de vim sangrará 4 espacios adicionales.
fritzo
Esta respuesta se vería facilitada agregando más ejemplos de breakindentopt. La sintaxis no es obvia en el documento de ayuda. Gracias @fritzo por el ejemplo en tu comentario.
Mnebuerquo
33

Hay un parche para esto, pero ha estado persistiendo durante años y la última vez que revisé no se aplicó limpiamente. Consulte la entrada "Sangría correcta de líneas envueltas" en http://groups.google.com/group/vim_dev/web/vim-patches . Realmente desearía que esto se incluyera en la línea principal.

Actualización: ese enlace parece haberse roto. Aquí hay una versión más actualizada del parche .

Actualización 2: se ha fusionado en sentido ascendente (a partir de 7.4.345), por lo que ahora solo tiene que hacerlo :set breakindent.

ergosys
fuente
Me gustaría mucho, haré que el marcado html sea más legible
Jose Elera
No veo ningún parche en ese sitio. ¿Alguien más puede confirmar?
puk
Aparentemente, el sitio fue reconstruido recientemente y esos enlaces están rotos. Hay una entrada de blog reciente con un parche aún más nuevo, en ese mismo sitio.
ergosys
1
Esto realmente falta. No entiendo por qué esto no está en la línea principal, especialmente. ya que el parche está muy bien escrito.
cseelus
2
Gracias @Vitor Eiji por la actualización. Esta es una gran noticia.
ergosys
17

No creo que sea posible tener exactamente la misma sangría, pero aún puede obtener una mejor vista configurando la opción 'showbreak'.

:set showbreak=>>>

Ejemplo:

<p>
    <a href="http://www.example.com">
        This is a bogus link, used to demonstrate
>>>an example
    </a>
</p>

Lo real se ve mejor que el código de ejemplo anterior, porque Vim usa un color diferente para '>>>'.

demasiado php
fuente
5
también puede usar :set showbreak=\ \ \ \ \ \ \ \ \ \ \ \ \ \ (la combinación de espacio de barra invertida crea el espacio de carácter de ruptura. Por lo tanto, podría agregar suficientes espacios para que sean más profundos que la mayoría de su código envuelto (por ejemplo, 10 espacios serían más profundos que 2 pestañas de cuatro espacios y 14 serían más profundos que 3 pestañas de cuatro espacios); una buena característica del espacio es que distrae menos visualmente (si eso es lo que quieres)
Jeromy Anglim
7
@Jeromy Anglim Una solución menor: set showbreak=\ \ \ \ \ \ \ \ \ \ \ \ \ \ es mucho menos legible quelet &showbreak=repeat(' ', 14)
ZyX
8

ACTUALIZACIÓN: En junio de 2014, se fusionó un parche para admitir una breakindentopción en Vim (versión 7.4.346 o posterior para obtener el mejor soporte).


También puede probar :set nowraplo que permitirá a vim mostrar líneas largas desplazándose hacia la derecha. Esto puede resultar útil para examinar la estructura general de un documento, pero puede resultar menos conveniente para editarlo.

Otras opciones cercanas a lo que estás buscando son linebreaky showbreak. Con showbreak, puede modificar lo que se muestra en el margen izquierdo de las líneas que están ajustadas, pero desafortunadamente no permite una sangría variable según el contexto actual.

Greg Hewgill
fuente
5

La única forma que conozco de que podría hacer esto sería usar un carácter de retorno (como lo menciona Cfreak) y combinar la textwidthopción con las diversas opciones de sangría. Si su sangría está configurada correctamente (como está por defecto con la sintaxis html, creo, pero de lo contrario vea las opciones autoindenty smartindent), puede:

:set formatoptions = tcqw
:set textwidth = 50
gggqG

Si tiene alguna personalización de la formatoptionsconfiguración, puede ser mejor simplemente hacer:

:set fo += w
:set tw = 50
gggqG

Que hace esto:

:set fo+=w  " Add the 'w' flag to the formatoptions so 
            " that reformatting is only done when lines
            " end in spaces or are too long (so your <p>
            " isn't moved onto the same line as your <a...).
:set tw=50  " Set the textwidth up to wrap at column 50
gg          " Go to the start of the file
gq{motion}  " Reformat the lines that {motion} moves over.
G           " Motion that goes to the end of the file.

Tenga en cuenta que esto no es lo mismo que un ajuste suave: ajustará las líneas en el archivo fuente así como en la pantalla (¡a menos que no lo guarde, por supuesto!). Hay otras configuraciones que se pueden agregar y formatoptionsque se formatearán automáticamente a medida que escribe: detalles en :help fo-table.

Para más información, ver:

:help 'formatoptions'
:help fo-table
:help 'textwidth'
:help gq
:help gg
:help G
:help 'autoindent'
:help 'smartindent'
DrAl
fuente
3
:set smartindent
:set autoindent

Creo que todavía tienes que usar una devolución

Cfreak
fuente
2

Si su HTML está lo suficientemente bien formado, ejecutarlo a través de xmllint podría ayudar:

:%!xmllint --html --format
Arkady
fuente
2

Una solución macro:


Editar:

Operan gq{motion}formatos automáticos a lo que sea que esté configurada la variable "textwidth". Esto es más fácil / mejor que usar el 80lBi^Mque tengo para mi macro.


Si ha habilitado la sangría automática

:set autoindent

Luego, ingresar una declaración al final de una línea sangrará la siguiente línea con la misma cantidad. Puede usar esto para ingresar de manera forzada en linewraps si lo desea. La siguiente macro aprovecha esto para sangrar automáticamente su texto:

establecer el registro z en:

gg/\v^.{80,}$^M@x (change 80 to whatever length you want your text to be)

y establezca el registro x en:

80lBi^M^[n@x (change 80 to whatever length you want your text to be)

Entonces hazlo

@x   

para activar las macros. Después de unos segundos, todo su texto estará en líneas con sangría adecuada de 80 caracteres o menos.

Explicación:

Aquí hay una disección de las macros:

Parte 1 (macro z):

gg/\v^.{80,}$^M@x

gg - start at the top of the file (this avoids some formatting issues)
/  - begin search
\v - switch search mode to use a more generic regex input style - no weird vim 'magic'
^.{80,}$ - regex for lines that contain 80 or more characters
^M - enter - do the search (don't type this, you can enter it with ctrl+v then enter)
@x - do macro x

Parte 2 (macro x):

80lBi^M^[n@x

80l - move right 80 characters
B   - move back one WORD (WORDS include characters like "[];:" etc.)
i^M - enter insert mode and then add a return (again don't type this, use ctrl+v)
^[  - escape out of insert mode (enter this with ctrl+v then escape)
@x  - repeat the macro (macro will run until there are no more lines of 80 characters or more)

Advertencias:

  • Esta macro se romperá si hay una PALABRA de 80 caracteres o más.

  • Esta macro no hará cosas inteligentes como sangrar líneas después de etiquetas.

  • Utilice la configuración de lazyredraw (: set lazyredraw) para acelerar esto

Michael Asnes
fuente