Arquivo xml de indentação do Vim

101

Estou aprendendo Vim, mas achei que fosse uma tarefa simples, mas não consigo fazer funcionar. Tenho o navegador SO, mas as soluções não estão funcionando para mim.

Estou tentando indentar corretamente um arquivo (xml). O comando que uso é:

gg=G 

ou ggVG = (inventado por mim mesmo provavelmente faz algo diferente;))

Meu .vimrc é:

syntax on 
filetype plugin indent on 
set nu 
Haagenti
fonte
Qual é o original, o resultado e a saída esperada?
Ingo Karkat
Qual é o resultado de :set ft? indentexpr?Será que lê filetype=xml indentexpr=XmlIndentGet(v:lnum,1)?!
Ingo Karkat
filetype = xml indentexpr = XmlIndentGet (v: lnum, 1). Sim
Haagenti
1
Eu gosto de adicionar apenas um pouco a este mapa e torná-lo m'ggVG='', o que simplesmente salva a linha em que você está e retorna a ela após recuar o arquivo.
Hovis Biddle

Respostas:

193

Gosto da resposta do Berei. No entanto, acho que o seguinte é um pouco mais flexível, pois você não precisa alterar seu vimrcarquivo. Além disso, é mais fácil formatar partes selecionadas do arquivo XML (algo que eu faço muito).

Primeiro, destaque o XML que deseja formatar.

Então, no modo normal, digite ! xmllint --format -

Sua linha de comando na parte inferior será semelhante a esta:

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

Em seguida, pressione Enter.

Explicação Técnica

O texto selecionado é enviado para o xmllintcomando e, em seguida --format, editado, e os resultados xmllintsão colocados sobre o texto selecionado no vim. O -no final do comando é para receber entrada padrão - que, neste caso, é o texto selecionado que o vim envia xmllint.

Jesse Hogan
fonte
6
É claro que isso só funciona se você tiver a ferramenta externa xmllint instalada e adicionada ao seu caminho.
Polymorphix
66
para simplificar o comando, :%!xmllint --format -, %significa todo o escopo deste arquivo xml.
hakunami
1
Por que todo mundo espera que haja uma ferramenta xmllint? No Ubuntu 15.04 não existe e o apt-get também não consegue encontrar um.
erikbwork
8
@ erikb85 Use apt-cache search, não apt-get, ao pesquisar pacotes e seu conteúdo. libxml2-utilscontém a ferramenta que falta.
ParanoiaPuppy
@hakunami, gostaria de poder votar em você 1000 vezes por simplificar esse processo
niken
69

Use um programa externo para recuar seus xmlarquivos. Neste caso eu escolhi xmllint, então defina o comando para a equalprgopção:

:set equalprg=xmllint\ --format\ -

Agora você pode executar

gg=G

para deixar xmllintformatar seus xmlarquivos.

Para obtê-lo sempre que usar , use um autocommandpara defini-lo.

autocommand de um comentário abaixo

au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2>/dev/null
Birei
fonte
Não sei por que isso funciona, portanto, o iniciante, mas vou descobrir isso;) Obrigado, funciona agora;)
Haagenti
8
Você pode usar o seguinte em seu .vimrc para habilitá-lo ao editar arquivos xml - au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2>/dev/null. Fonte - ku1ik.com/2011/09/08/…
studgeek
1
Obrigado! Muito frustrado com arquivos XML grandes e vim, no Sublime eles reindentam muito rapidamente (5000-10000 linhas e dados base64), mas no Vim eles reindentam vários minutos. Esta solução corrige o problema com arquivos XML grandes. Mais uma vez estou feliz com o Vim.
Sonique de
se você estiver no ubuntu, você precisará instalar o libxml2-utilspacote para obter xmllint
hoffmanc
33

Uma solução simples que gosto e que não requer nenhuma ferramenta de terceiros é inserir uma nova linha antes de cada tag de abertura '<...>'. Depois, você pode usar o recuo automático padrão do vim. Em resumo:

  1. %s/</\r</g
  2. gg=G recuar automaticamente
KFL
fonte
Eu tentei com um grande arquivo xml e é muito demorado para processar.
Luc M
Obrigado. Isso é bastante fácil e funciona sem a necessidade de ferramentas externas.
ataque aéreo de
6
Eu prefiro %s/></>\r</g, de modo que cada elemento de texto permaneça na mesma linha.
Nicola Musatti
2
@NicolaMusatti Ou se às vezes há espaços entre as tags,%s/> *</>\r</g
Arthur Tacca
11

Isso é fácil de conseguir, uma vez que ~ / .vimrc esteja configurado corretamente.

Defina as seguintes opções em ~ / .vimrc:

filetype indent on
set smartindent

Isso permite que você mova o cursor para o topo do arquivo e indente até o final: gg = G

Você também pode selecionar o texto desejado com o modo visual e pressionar = para recuá-lo.

Jarederaj
fonte
2
Suponho que seja em .vimrcvez de .bashrc.
Birei de
1
Opa. Exatamente. Corrigido isso. Obrigado.
jarederaj
Isso funcionaria quando cada tag estivesse em uma linha. Se o XML não tiver espaços nem linhas finais, isso não fará nada.
José Ramón
Sempre funcionou para mim, desde que a marcação seja válida.
jarederaj
Se a sua marcação não estiver (consistentemente?) Em linhas distintas, você pode alterá-la descuidadamente com:% s / </ \ r </ ge então:% s / \ n \ n / \ r /
jarederaj
11

Resposta curta: Ligue matchit.vim . Você pode adicionar packadd matchitao seu .vimrcou usar o vim-sensible , que o habilita por padrão.

Resposta longa: tentei muitas estratégias para indentar XML automaticamente no Vim, incluindo a abordagem xmllint discutida no wiki do Vim . O problema com xmllint(e a mesma abordagem com outras ferramentas CLI externas, como xmlformate tidy, também) é que todos eles insistem em espremer novas linhas em branco. Se tudo o que você deseja é indentar seu XML, sem remover linhas em branco, comentários e / ou outra formatação intencional, então xmllintnão é a melhor escolha.

Acontece que o comando equals (=) do Vim já suporta XML, desde que o script matchit.vim esteja habilitado. Uma maneira super fácil de habilitá-lo é adotar o vim sensível ao tpope . Outra é adicionar packadd matchitao seu .vimrc. Então, a formatação XML "simplesmente funcionará" fora da caixa.

ctrueden
fonte
1
Para ser mais preciso, parece que matchit.vimé a solução real. Você pode habilitá-lo vimrcadicionando esta linha:packadd matchit
Christian Rondeau
1
Obrigado Christian; Atualizei a resposta para esclarecer que matchit.vim é o que resolve o problema.
ctrueden
Votado porque funcionou melhor para mim. No entanto, eu sugeriria adicionar a sugestão de Christian (packadd matchit) à resposta curta, pois é muito simples e faz o trabalho (pelo menos para mim)
marque
@mark Eu atualizei a resposta para incluir a sugestão de Christian.
ctrueden em
4

No VIM, eu recuo automaticamente todo o arquivo (usando guias rígidas) usando o seguinte comando:

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

O ^Ié um único caractere que você gera por meio de: CTRL+ v, CTRL+i

Nuvem
fonte
1

Eu tive o mesmo problema. Descobriu-se que a linha

set viewdir=~\.vim\views\

no meu .vimrccausou o problema. Apenas certifique-se de que você não o tem.

Boris Brodski
fonte
1

A resposta de Jesse Hogan é boa, mas prefiro uma resposta mais simples:

Enquanto você estiver no vim e seu arquivo XML estiver aberto, no modo normal, escreva isto:

:%!xmllint --format %

em seguida, pressione Enter. Todo o seu arquivo XML será formatado.

lembre-se de que você deve ter instalado o xmllint antes.

Cheetah Coder
fonte
0

para aqueles que aquele que está usando coc.nvimplugin, você pode instalar coc-xmlpor :CocInstall coc-xml , em seguida, mapear formato chave em seu arquivo de configuração: nmap <silent> fm <Plug>(coc-format). De agora em diante, você pode formatar não apenas o arquivo xml, mas outros arquivos muito facilmente

Lehanh
fonte