XML-файл с отступом vim


101

Я изучаю Vim, но я думал, что это простая задача, но я не могу заставить ее работать. У меня есть браузер SO, но решения для меня не работают.

Я пытаюсь правильно сделать отступ для файла (xml). Я использую следующую команду:

gg=G 

или ggVG = (сам придумал, наверное, что-то другое делает;))

Мой .vimrc:

syntax on 
filetype plugin indent on 
set nu 

Каков оригинал, результат и ожидаемый результат?
Инго Каркат

Что выводит :set ft? indentexpr?ли он читается filetype=xml indentexpr=XmlIndentGet(v:lnum,1)?!
Инго Каркат

filetype = xml indentexpr = XmlIndentGet (v: lnum, 1). Да
Haagenti


1
Мне нравится добавить немного к этой карте и сделать ее m'ggVG='', которая просто сохраняет линию, на которой вы находитесь, и перемещается к ней после повторного отступа файла.
Hovis Biddle

Ответы:


196

Мне нравится ответ Берея. Тем не менее, я думаю, что следующее немного более гибко, поскольку вам не нужно изменять свой vimrcфайл. Кроме того, легче форматировать отдельные части XML-файла (что я часто делаю).

Сначала выделите XML, который вы хотите отформатировать.

Затем в обычном режиме введите ! xmllint --format -

Ваша командная строка внизу будет выглядеть так:

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

Затем нажмите Enter.

Техническое объяснение

Выбранный текст отправляется xmllintкоманде, затем --format'ed, и результаты xmllintпомещаются поверх выбранного текста в vim. Значок -в конце команды предназначен для получения стандартного ввода - в данном случае это выделенный текст, который отправляет vim xmllint.


6
Это, конечно, работает только в том случае, если у вас установлен внешний инструмент xmllint и добавлен в ваш путь.
Polymorphix

67
упростить команды :%!xmllint --format -, %означает весь объем этого XML - файл.
hakunami 08

1
Почему все ожидают, что появится инструмент xmllint? В Ubuntu 15.04 его нет, и apt-get тоже не может его найти.
erikbwork

8
@ erikb85 Используйте apt-cache search, а не apt-getпри поиске пакетов и их содержимого. libxml2-utilsсодержит недостающий инструмент.
ParanoiaPuppy

@hakunami, если бы я мог проголосовать за вас 1000 раз за упрощение этого процесса
Никен

69

Используйте внешнюю программу для создания отступов для xmlфайлов. В этом случае я выбрал xmllint, поэтому установите для команды значение equalprg:

:set equalprg=xmllint\ --format\ -

Теперь вы можете выполнить

gg=G

чтобы позволить xmllintформатировать ваши xmlфайлы.

Чтобы получить это каждый раз, когда вы используете , используйте, autocommandчтобы установить его.

autocommand из комментария ниже

au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2>/dev/null

Не уверен, почему это работает, поэтому новичок, но я
разберусь с

8
Вы можете использовать в своем .vimrc следующее, чтобы включить его при редактировании файлов xml - au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2>/dev/null. Источник - ku1ik.com/2011/09/08/…
studgeek

1
Спасибо! Очень расстроен большими файлами XML и vim, в Sublime они восстанавливаются очень быстро (5000-10000 строк и данные base64), но в Vim они повторно заменяют несколько минут. Это решение устраняет проблему с большими файлами XML. Я снова доволен Vim.
Sonique

если вы используете ubuntu, вам необходимо установить libxml2-utilsпакет, чтобы получить xmllint
hoffmanc

33

Простое решение, которое мне нравится, которое не требует каких-либо сторонних инструментов, - это вставлять новую строку перед каждым открывающим тегом '<...>'. Затем вы можете использовать стандартный автоматический отступ vim. Коротко:

  1. %s/</\r</g
  2. gg=G делать отступы

Я пробовал это с большим xml файлом, и обрабатывать его очень долго.
Люк М.

Спасибо. Это достаточно просто и не требует внешних инструментов.
авиаудар,

6
Я предпочитаю %s/></>\r</g, чтобы каждый текстовый элемент оставался в одной строке.
Никола Мусатти

2
@NicolaMusatti Или, если иногда между тегами есть пробелы,%s/> *</>\r</g
Артур Такка

12

Краткий ответ: включите matchit.vim . Вы можете добавить packadd matchitв свой .vimrcили использовать vim-sensible , который включает его по умолчанию.

Длинный ответ: я пробовал много стратегий автоматического отступа XML в Vim, включая подход xmllint, обсуждаемый в вики Vim . Проблема с xmllint(и тот же подход с другими внешними инструментами CLI, такими как xmlformatи tidyтоже) заключается в том, что все они настаивают на выдавливании пустых символов новой строки. Если все, что вам нужно, это сделать отступ в XML, не удаляя пустые строки, комментарии и / или другое намеренное форматирование, то xmllintэто не лучший выбор.

Оказывается, команда Vim equals (=) уже поддерживает XML, пока включен сценарий matchit.vim . Один из очень простых способов сделать это - использовать vim-sensible tpope . Другой - добавить packadd matchitв ваш .vimrc. Тогда форматирование XML будет "просто работать" из коробки.


1
Если быть более точным, похоже, matchit.vimэто реальное решение. Вы можете включить его в своем vimrc, добавив эту строку:packadd matchit
Christian Rondeau

1
Спасибо, Кристиан; Я обновил ответ, чтобы уточнить, что matchit.vim - это то, что решает проблему.
ctrueden

Проголосовали за, потому что это сработало для меня лучше всего. Однако я бы посоветовал добавить предложение Кристиана (packadd matchit) к короткому ответу, поскольку он очень прост и выполняет свою работу (по крайней мере, для меня)
Марк

1
@tohuwawohu Используйте =команду. Если вы находитесь в верхней части файла, вы можете печатать =G. В качестве альтернативы вы можете перейти к началу файла с помощью 1G, войти в режим выбора визуальной строки с помощью V, затем ввести, Gчтобы перейти к нижней части файла, выбрав все. А затем нажмите, =чтобы сделать отступ для всего файла. Точно так же, если вы хотите сделать отступ только для части файла, выберите только эту часть и нажмите =.
ctrueden

1
@tohuwawohu Я только что понял, что вы сказали "без разрывов строки". Команда =не будет вставлять (или удалять) разрывы строк, которых еще нет. Это влияет только на отступ в начале. Так что matchit.vimэто не решение для красивого печатного XML, сжатого в одну строку. Используйте xmllintили подобное для этого.
ctrueden

11

Этого легко добиться, если правильно настроить ~ / .vimrc.

Установите следующие параметры в ~ / .vimrc:

filetype indent on
set smartindent

Это позволяет переместить курсор в начало файла и сделать отступ до конца: gg = G

Вы также можете выбрать нужный текст в визуальном режиме и нажать =, чтобы сделать отступ.


2
Полагаю, это будет .vimrcвместо .bashrc.
Бирей

1
Упс. Именно. Исправлено. Спасибо.
jarederaj

Это будет работать, когда каждый тег находится в строке. Если в XML нет пробелов и конечных строк, это вообще ничего не даст.
Хосе Рамон

У меня всегда работало, пока действовала разметка.
jarederaj

Если ваша разметка не (постоянно?) На отдельных строках, вы можете небрежно изменить это с помощью:% s / </ \ r </ g, а затем:% s / \ n \ n / \ r /
jarederaj

4

В VIM я автоматически делаю отступ для всего файла (используя жесткие вкладки), используя следующую команду:

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

Это ^Iединственный символ, который вы создаете с помощью: CTRL+ v, CTRL+i


1

У меня такая же проблема. Оказалось, что линия

set viewdir=~\.vim\views\

в моем случае .vimrcвозникла проблема. Только убедитесь, что у вас его нет.


1

Ответ Джесси Хогана хорош, но я бы предпочел более простой ответ:

Пока вы находитесь в vim и ваш XML-файл открыт, в обычном режиме напишите следующее:

:%!xmllint --format %

затем нажмите Enter. Все ваши XML-файлы будут отформатированы.

помните, вы должны были установить xmllint раньше.


0

для тех , кто один , который использует coc.nvimплагин, вы можете установить с coc-xmlпомощью :CocInstall coc-xml , то отображение ключа формата в файле конфигурации: nmap <silent> fm <Plug>(coc-format). С этого момента вы можете легко форматировать не только файл xml, но и другой файл.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.