Archivo XML de sangría Vim

101

Estoy aprendiendo Vim, pero pensé que era una tarea simple, pero no puedo hacer que funcione. Tengo un navegador SO pero las soluciones no me funcionan.

Estoy intentando sangrar correctamente un archivo (xml). El comando que uso es:

gg=G 

o ggVG = (este hecho por mí mismo probablemente hace algo diferente;))

Mi .vimrc es:

syntax on 
filetype plugin indent on 
set nu 
Haagenti
fuente
¿Cuál es el resultado original, el resultado y el esperado?
Ingo Karkat
¿Cuál es el resultado de :set ft? indentexpr?¿Se lee filetype=xml indentexpr=XmlIndentGet(v:lnum,1)?
Ingo Karkat
tipo de archivo = xml indentexpr = XmlIndentGet (v: lnum, 1). Sí
Haagenti
1
Me gusta agregar solo un poco a este mapa y hacerlo m'ggVG='', lo que simplemente guarda la línea en la que se encuentra y regresa a ella después de volver a indentar el archivo.
Hovis Biddle

Respuestas:

193

Me gusta la respuesta de Berei. Sin embargo, creo que lo siguiente es un poco más flexible en el sentido de que no tiene que modificar su vimrcarchivo. Además, es más fácil formatear partes seleccionadas del archivo XML (algo que hago a menudo).

Primero, resalte el XML que desea formatear.

Luego, en modo normal, escriba ! xmllint --format -

Su línea de comando en la parte inferior se verá así:

:'<,'>!xmllint --format -

Luego presiona Enter.

Explicación técnica

El texto seleccionado se envía al xmllintcomando, luego se --formatedita y los resultados de xmllintse colocan sobre el texto seleccionado en vim. El -al final del comando es para recibir una entrada estándar, que, en este caso, es el texto seleccionado al que envía vim xmllint.

Jesse Hogan
fuente
6
Por supuesto, esto solo funciona si tiene la herramienta externa xmllint instalada y agregada a su ruta.
Polymorphix
66
para simplificar el comando, :%!xmllint --format -, %significa todo el alcance de este archivo XML.
hakunami
1
¿Por qué todos esperan que haya una herramienta xmllint? En Ubuntu 15.04 no hay y apt-get tampoco puede encontrar uno.
erikbwork
8
@ erikb85 Se usa apt-cache search, no apt-get, cuando se buscan paquetes y su contenido. libxml2-utilscontiene la herramienta que falta.
ParanoiaPuppy
@hakunami desearía poder votarte 1000 veces por simplificar ese proceso
niken
69

Utilice un programa externo para sangrar sus xmlarchivos. En este caso lo elegí xmllint, así que configure el comando en la equalprgopción:

:set equalprg=xmllint\ --format\ -

Ahora puedes ejecutar

gg=G

para permitir xmllintformatear sus xmlarchivos.

Para conseguirlo cada vez que lo uses , use un autocommandpara configurarlo.

autocommand de un comentario a continuación

au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2>/dev/null
Birei
fuente
No estoy seguro de por qué esto funciona, por lo tanto, el principiante, pero lo resolveré;) Gracias, funciona ahora;)
Haagenti
8
Se puede utilizar el siguiente en su .vimrc para permitirle al editar archivos XML - au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2>/dev/null. Fuente - ku1ik.com/2011/09/08/…
studgeek
1
¡Gracias! Muy frustrado con archivos XML grandes y vim, en Sublime se reinventan muy rápidamente (5000-10000 líneas y datos base64), pero en Vim se reinventan varios minutos. Esta solución soluciona el problema con archivos XML grandes. De nuevo estoy feliz con Vim.
Sonique
si está en ubuntu, deberá instalar el libxml2-utilspaquete para obtener xmllint
hoffmanc
33

Una solución simple que me gusta y que no requiere ninguna herramienta de terceros es insertar una nueva línea antes de cada etiqueta de apertura '<...>'. Entonces puede usar la sangría automática de vim estándar. En breve:

  1. %s/</\r</g
  2. gg=G sangría automática
KFL
fuente
Lo probé con un archivo xml grande y su proceso es muy largo.
Luc M
Gracias. Esto es bastante fácil y funciona sin necesidad de herramientas externas.
ataque aéreo
6
Prefiero %s/></>\r</g, para que cada elemento de texto permanezca en la misma línea.
Nicola Musatti
2
@NicolaMusatti O si a veces hay espacios entre las etiquetas,%s/> *</>\r</g
Arthur Tacca
11

Esto es fácil de lograr una vez que ~ / .vimrc está configurado correctamente.

Configure las siguientes opciones en ~ / .vimrc:

filetype indent on
set smartindent

Esto le permite mover el cursor a la parte superior del archivo y sangrar hasta el final: gg = G

También puede seleccionar el texto deseado con el modo visual y presionar = para sangrarlo.

jarederaj
fuente
2
Supongo que será en .vimrclugar de .bashrc.
Birei
1
¡Ups! Exactamente. Arreglado eso. Gracias.
jarederaj
Eso funcionaría cuando cada etiqueta está en una línea. Si el XML no tiene espacios ni líneas finales, esto no haría nada en absoluto.
José Ramón
Siempre me ha funcionado siempre que el marcado sea válido.
jarederaj
Si su marcado no está (¿consistentemente?) En líneas distintas, puede cambiarlo descuidadamente con:% s / </ \ r </ gy luego:% s / \ n \ n / \ r /
jarederaj
11

Respuesta corta: Enciende matchit.vim . Puede agregar packadd matchita su .vimrc, o usar vim-sensible , que lo habilita por defecto.

Respuesta larga: he probado muchas estrategias para aplicar sangría automática a XML en Vim, incluido el enfoque xmllint que se analiza en la wiki de Vim . El problema con xmllint(y el mismo enfoque con otras herramientas CLI externas como xmlformaty tidy, también) es que todas insisten en eliminar nuevas líneas en blanco. Si todo lo que desea es sangrar su XML, sin eliminar líneas en blanco, comentarios y / u otro formato intencional, entonces xmllintno es la mejor opción.

Resulta que el comando equals (=) de Vim ya es compatible con XML, siempre que el script matchit.vim esté habilitado. Una forma súper fácil de habilitarlo es adoptar vim-sensible de tpope . Otro es agregar packadd matchita su .vimrc. Entonces, el formato XML "simplemente funcionará" desde el primer momento.

ctrueden
fuente
1
Para ser más precisos, parece que matchit.vimes la solución real. Puede habilitarlo en su vimrcagregando esta línea:packadd matchit
Christian Rondeau
1
Gracias Christian; Actualicé la respuesta para aclarar que matchit.vim es lo que resuelve el problema.
ctrueden
Voto a favor porque esto funcionó mejor para mí. Sin embargo, sugeriría agregar la sugerencia de Christian (packadd matchit) a la respuesta corta, ya que es muy simple y hace el trabajo (al menos para mí)
marque el
@mark Actualicé la respuesta para incluir la sugerencia de Christian.
ctrueden
4

En VIM, auto-sangra todo el archivo (usando pestañas duras) usando el siguiente comando:

:%!XMLLINT_INDENT="^I" xmllint --format -

El ^Ies un carácter único que genera a través de: CTRL+ v, CTRL+i

Nube
fuente
1

Yo tuve el mismo problema. Resultó que la línea

set viewdir=~\.vim\views\

en mi .vimrccausó el problema. Solo asegúrate de que no lo tienes.

Boris Brodski
fuente
1

La respuesta de Jesse Hogan es buena, pero prefiero una respuesta más simple:

Mientras está en vim y su archivo XML está abierto, en modo normal escriba esto:

:%!xmllint --format %

luego presione Enter. Se formateará todo su archivo XML.

recuerde que debería haber instalado xmllint antes.

Codificador de guepardo
fuente
0

para los que uno que está utilizando coc.nvimplug-in, puede instalar coc-xmlmediante :CocInstall coc-xml , a continuación, asignación de teclas de formato en su archivo de configuración: nmap <silent> fm <Plug>(coc-format). A partir de ahora, puede formatear no solo el archivo xml sino también otro archivo muy fácilmente

lehanh
fuente