Fichier XML de retrait Vim

101

J'apprends Vim mais je pensais que c'était une tâche simple mais je ne peux pas la faire fonctionner. J'ai un navigateur SO mais les solutions ne fonctionnent pas pour moi.

J'essaie d'indenter correctement un fichier (xml). La commande que j'utilise est:

gg=G 

ou ggVG = (créé celui-ci moi-même fait probablement quelque chose de différent;))

Mon .vimrc est:

syntax on 
filetype plugin indent on 
set nu 
Haagenti
la source
Quel est l'original, le résultat et la sortie attendue?
Ingo Karkat
Quelle est la sortie de :set ft? indentexpr?Est - ce qu'il lit filetype=xml indentexpr=XmlIndentGet(v:lnum,1)?!
Ingo Karkat
filetype = xml indentexpr = XmlIndentGet (v: lnum, 1). Yup
Haagenti
1
J'aime ajouter un peu à cette carte et la créer m'ggVG='', ce qui enregistre simplement la ligne sur laquelle vous vous trouvez et y revient après avoir réindenté le fichier.
Hovis Biddle

Réponses:

193

J'aime la réponse de Berei. Cependant, je pense que ce qui suit est un peu plus flexible dans la mesure où vous n'avez pas à modifier votrevimrc fichier. De plus, il est plus facile de formater certaines parties du fichier XML (ce que je fais souvent).

Tout d'abord, mettez en surbrillance le XML que vous souhaitez formater.

Puis, en mode normal, tapez ! xmllint --format -

Votre ligne de commande en bas ressemblera à ceci:

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

Puis appuyez sur Entrée.

Explication technique

Le texte sélectionné est envoyé à la xmllintcommande, puis --format'ed, et les résultats de xmllintsont placés sur votre texte sélectionné dans vim. Le -à la fin de la commande sert à recevoir une entrée standard - qui, dans ce cas, est le texte sélectionné vers lequel vim envoie xmllint.

Jesse Hogan
la source
6
Cela ne fonctionne bien sûr que si l'outil externe xmllint est installé et ajouté à votre chemin.
Polymorphix
66
pour simplifier la commande, :%!xmllint --format -, %signifie toute l'étendue de ce fichier xml.
hakunami
1
Pourquoi tout le monde s'attend-il à ce qu'il y ait un outil xmllint? Dans Ubuntu 15.04, il n'y en a pas et apt-get n'en trouve pas non plus.
erikbwork
8
@ erikb85 À utiliser apt-cache search, non apt-get, lors de la recherche de packages et de leur contenu. libxml2-utilscontient l'outil manquant.
ParanoiaPuppy
@hakunami je souhaite que je pourrais vous voter pour 1000 fois pour simplifier ce processus
niken
69

Utilisez un programme externe pour indenter vos xmlfichiers. Dans ce cas, j'ai choisi xmllint, alors définissez la commande sur l' equalprgoption:

:set equalprg=xmllint\ --format\ -

Maintenant vous pouvez exécuter

gg=G

pour laisser xmllintformater vos xmlfichiers.

Pour l'obtenir à chaque utilisation , utilisez un autocommandpour le définir.

autocommand à partir d'un commentaire ci-dessous

au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2>/dev/null
Birei
la source
Je ne sais pas pourquoi cela fonctionne, donc le débutant, mais je vais comprendre celui-ci;) Merci, cela fonctionne maintenant;)
Haagenti
8
Vous pouvez utiliser ce qui suit dans votre .vimrc pour l'activer lors de l'édition de fichiers xml - au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2>/dev/null. Source - ku1ik.com/2011/09/08/…
studgeek
1
Je vous remercie! Très frustrés par les gros fichiers XML et vim, dans Sublime ils se réindiquent très rapidement (5000-10000 lignes et données base64), mais dans Vim ils se réindentent plusieurs minutes. Cette solution résout le problème des fichiers XML volumineux. Encore une fois, je suis content de Vim.
Sonique
si vous êtes sur ubuntu, vous devrez installer le libxml2-utilspaquet pour obtenir xmllint
hoffmanc
33

Une solution simple que j'aime et qui ne nécessite aucun outil tiers est d'insérer une nouvelle ligne avant chaque balise d'ouverture '<...>'. Ensuite, vous pouvez utiliser l'indentation automatique Vim standard. En bref:

  1. %s/</\r</g
  2. gg=G pour indenter automatiquement
KFL
la source
Je l'ai essayé avec un gros fichier xml et son traitement est très long.
Luc M
Je vous remercie. C'est assez facile et fait le travail sans nécessiter d'outils externes.
frappe aérienne du
6
Je préfère %s/></>\r</g, pour que chaque élément de texte reste sur la même ligne.
Nicola Musatti
2
@NicolaMusatti Ou s'il y a parfois des espaces entre les balises,%s/> *</>\r</g
Arthur Tacca
11

Ceci est facile à réaliser une fois que ~ / .vimrc est correctement configuré.

Définissez les options suivantes dans ~ / .vimrc:

filetype indent on
set smartindent

Cela vous permet de déplacer le curseur vers le haut du fichier et de le mettre en retrait jusqu'à la fin: gg = G

Vous pouvez également sélectionner le texte souhaité en mode visuel et appuyer sur = pour le mettre en retrait.

Jarederaj
la source
2
Je suppose que ce sera .vimrcau lieu de .bashrc.
Birei
1
Oups. Exactement. Correction de ça. Je vous remercie.
jarederaj
Cela fonctionnerait lorsque chaque balise est dans une ligne. Si le XML n'a pas d'espaces ni de lignes de fin, cela ne ferait rien du tout.
José Ramón
Cela a toujours fonctionné pour moi tant que le balisage est valide.
jarederaj
Si votre balisage n'est pas (systématiquement?) Sur des lignes distinctes, vous pouvez le modifier avec:% s / </ \ r </ g puis:% s / \ n \ n / \ r /
jarederaj
11

Réponse courte: Allumez matchit.vim . Vous pouvez ajouter packadd matchità votre .vimrc, ou utiliser vim-sensible , qui l'active par défaut.

Réponse longue: j'ai essayé de nombreuses stratégies d'auto-indentation XML dans Vim, y compris l' approche xmllint discutée sur le wiki Vim . Le problème avec xmllint(et la même approche avec d'autres outils CLI externes tels que xmlformatet tidy, aussi) est qu'ils insistent tous pour éliminer les nouvelles lignes vides. Si tout ce que vous voulez est d'indenter votre XML, sans supprimer les lignes vides, les commentaires et / ou tout autre formatage intentionnel, ce xmllintn'est pas le meilleur choix.

Il s'avère que la commande equals (=) de Vim prend déjà en charge XML, tant que le script matchit.vim est activé. Un moyen très simple de l'activer est d'adopter le vim-sensible de tpope . Un autre est d'ajouter packadd matchità votre .vimrc. Ensuite, le formatage XML "fonctionnera" dès la sortie de la boîte.

ctrueden
la source
1
Pour être plus précis, il semble que ce matchit.vimsoit la solution réelle. Vous pouvez l'activer dans votre vimrcen ajoutant cette ligne:packadd matchit
Christian Rondeau
1
Merci Christian; J'ai mis à jour la réponse pour clarifier que matchit.vim est ce qui résout le problème.
ctrueden
J'ai voté pour parce que cela fonctionnait le mieux pour moi. Cependant, je suggérerais d'ajouter la suggestion de Christian (packadd matchit) à la réponse courte car elle est très simple et fait le travail (au moins pour moi)
marquez le
@mark J'ai mis à jour la réponse pour inclure la suggestion de Christian.
ctrueden
4

Dans VIM, j'indente automatiquement le fichier entier (en utilisant des onglets fixes) à l'aide de la commande suivante:

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

Le ^Iest un personnage unique que vous générez via: CTRL+ v, CTRL+i

Nuage
la source
1

J'ai eu le même problème. Il s'est avéré que la ligne

set viewdir=~\.vim\views\

dans mon a .vimrccausé le problème. Assurez-vous simplement que vous ne l'avez pas.

Boris Brodski
la source
1

La réponse de Jesse Hogan est bonne, mais je préfère une réponse plus simple:

Pendant que vous êtes dans vim et que votre fichier XML est ouvert, en mode normal, écrivez ceci:

:%!xmllint --format %

puis appuyez sur Entrée. Tout votre fichier XML sera formaté.

rappelez-vous que vous devriez avoir installé xmllint avant.

Codeur guépard
la source
0

pour ceux qui utilise un coc.nvimplugin, vous pouvez installer coc-xmlpar :CocInstall coc-xml , puis sur la touche de format mapping dans votre fichier de configuration: nmap <silent> fm <Plug>(coc-format). À partir de maintenant, vous pouvez formater non seulement un fichier xml, mais un autre fichier très facilement

Lehanh
la source