Сортировка Vim Folds

У меня есть файл, который выглядит примерно так:

dog{{{
blah blah blah
}}}
cat{{{
blah blah
}}}
aardvark{{{
blah blah blah blah
}}}

В моем vimrc у меня есть set foldmethod=marker, так что содержимое файла складывается в фигурные скобки. Мой вопрос в том, как я могу отсортировать файл на основе заголовка сгиба? Я хочу, чтобы раздел aarvaark появился первым, затем cat, затем dog.

Некоторые сложенные секции имеют в себе другие складки. Я не хочу сортировать эти уровни с более низкой складкой. Файл должен быть отсортирован только по слоям 1.

Ответ 1

Когда все складки закрыты (zM или :set foldlevel=0), вы можете использовать delete dd и вставить p, чтобы вручную сдвинуть сложенные блоки вокруг. Это нормально для небольших объемов текста.

Для огромных текстов вам нужно будет написать функцию сортировки самостоятельно, так как Vim не предлагает такую ​​функциональность. Можно использовать следующий алгоритм:

  • Соедините все сложенные строки вместе с разделителем, который не существует в тексте (например, <Nul>).
  • Выполните команду :sort.
  • Отмените диапазон на специальном разделителе.

С обработкой ошибок и угловыми случаями, это на самом деле совсем немного усилий по внедрению. Я сделал здесь попытку: https://gist.github.com/4145501

Ответ 2

Один из подходов был бы следующим:

  • Найдите и замените окончания строк, чтобы складки уровня один были на одной строке (т.е. заменяя строку, заканчивающуюся уникальной строкой, которая не отображается в другом месте в файле).

  • Используйте :sort для сортировки строк в файле, как обычно.

  • Отмените поиск и замените шаг 1 для повторного ввода окончаний строки.

Все это можно записать как макрос Vim.

Шаги 1 и 3 были бы простыми, если бы не были вложенные складки или если был простой способ отличить складки верхнего уровня от вложенных (например, если строки уровня {{{и}}} flush left, а другие имеют ведущее пространство). Если это не так, возможно, все еще возможно, но гораздо сложнее.

Ответ 3

Я бы использовал силу макросов Vim.

Предположим, что у вас нет другого персонала в вашем файле, кроме записей и первой записи, начиная с первой строки. И что у вас нет начала уровня 1 и заканчивается на той же линии. И все ваши {} хорошо совпадают.

Перейдите к первой записи и запишите макрос для регистрации (qa - начать запись q - stop)

/{^MV%k:s/\n/EEEEEE/^Mj^

Скопируйте мой или лучше зарегистрируйте его самостоятельно: (^ M - означает буквальный ввод)

  • /{^ M найдите следующий {
  • V% k выберите линейные тиски до конца уровня 1, но не закрытие с помощью}}}
  • : s/\n/EEEEEE/^ M меняет символ "конец строки" на некоторую уникальную строку внутри выделения
  • j ^ перейти на одну строку вниз и просить линию в случае, если предыдущая запись имела ведущие пробелы.

Запустите макрос, начиная со второй строки (предположим, что первая обрабатывается уже при записи макроса.) В обычном режиме 100000 @a - используйте любое число, большее, чем количество ваших записей. Макрос останавливается, когда все строки обрабатываются, если первая запись находится в первой строке файла. В качестве побочного эффекта визуально выберите первую строку - отмените выбор.

Сортировка файла

:sort

Восстановить конец строк: :% S/EEEEEE/^ М/г

Примечание ^ M должно быть буквальным. Чтобы ввести его, используйте Ctrl-V Enter

Он работает с вложенными уровнями, потому что% переходит к соответствующему закрытию}. Вот почему важно, чтобы у вас был {} хорошо подобранный.

Макрос останавливается, если не может подняться с k, поэтому вы должны иметь первую запись в первой строке. Макрос будет игнорировать пустые строки или что-либо, что не является записью между записями.

Метод выше должен хорошо работать для вашего файла. Если вы хотите использовать более общий подход со сгибами, используйте следующие макросы в макросах вместо/{и%

Сначала откройте все складки

zj - перейти к началу следующей открытой складки

] z - перейти к концу текущей складки.

Остальная часть макроса остается прежней. Этот метод является более общим, но я считаю его менее надежным, поскольку он зависит от всех открываемых складок, сгибания и т.д.