Сортировка 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 - перейти к концу текущей складки.
Остальная часть макроса остается прежней.
Этот метод является более общим, но я считаю его менее надежным, поскольку он зависит от всех открываемых складок, сгибания и т.д.