У меня есть проблема, я могу думать о двух общих подходах к решению, но я не знаю специфику для любого подхода.
...
Level 1: cũng also
Level 1: và and
Level 1: như like; such as
Level 2: các plural marker
Level 2: của belonging to
...
Для каждой строки, начинающейся с «Level n», я хочу вставить число, начинающееся с «01». Для простоты давайте предварительно добавим число.
Подход 1: вручную выбрать все линии с одинаковым уровнем. Призывай магию, я скоро научусь.
Подход 2: Запишите поиск и замену, которая соответствует всем строкам с данным уровнем, который при каждом совпадении включает в текст замены значение, которое увеличивается на единицу с каждым совпадением.
Я нашел похожие вопросы в StackOverflow или на других сайтах Vim, но у каждого из них, похоже, есть одна или несколько из следующих проблем:
- Речь идет о вставке номера текущей строки, а не произвольного, но увеличивающегося числа.
- Не дополняет нулями номер.
- На самом деле не работает для выбора на моем Vim 7.4, работающем на Windows 7. (Эти приводят к ошибке
E481: No range allowed
.)
Я запускаю gVim в Windows с mswin.vim, но решение, которое работает на всех установках vanilla Vim без необходимости настройки, может быть лучшим.
Ответы:
Аналогично ответу на https://vi.stackexchange.com/a/818/227 , вы можете использовать глобальную команду.
С его помощью вы можете указать vim искать строки, соответствующие шаблону, а затем выполнять команды для него.
В вашем случае вы хотите добавить текст к строкам, начинающимся с «Level N:», чтобы наша глобальная команда могла быть
Использование команды замены (замена регулярного выражения) для команды
Команды веселее. Я обычно люблю делать регулярные выражения для подобных вещей, так как переменные легко использовать.
Пример для вашего вопроса
Как это работает
В разделе замены команды подстановки может быть выражение.
Первое, что мы сделаем, это установим переменную
i
в качестве начального номера. Я выбрал 1, но подойдет любое число.let i = 1
Затем мы запускаем нашу глобальную команду, которая настраивает нас на выполнение действий с согласованными строками.
g/^Level \d:/
Наша глобальная команда вставит значение и увеличит наш счетчик с помощью команды подстановки и команды let.
s/^/\=printf("%02d ", i)/ | let i = i+1
Регулярное выражение команды подстановки находит начало строки
^
и заменяет его выражением, и наше выражение будет результатом отформатированной печати. Как и в языке Си, vim's printf принимает параметры форматирования.%02d
средство преобразование аргумента , как если бы это было десятичное числоd
, занимающее по меньшей мере , 2 места2
и колодку с 00
. Подробности и другие параметры преобразования (включая форматирование с плавающей запятой) см:help printf
. Мы даем printf нашу переменную подсчета,i
и она дает нам01
первый раз,02
второй раз и т. Д. Это используется командой замены для замены начала строки, эффективно вставляя результат printf в начало.Обратите внимание , что я ставлю пробел после d:
"%02d "
. Вы не спрашивали об этом в вопросе (и я не видел пример вывода), но я подозревал, что вы хотите отделить число от слова «Уровень». Удалите пробел из строки, заданной для printf, чтобы вставленный номер был рядом с буквой L на уровне.Наконец, это
let i = i + 1
увеличивает наш счетчик после каждой замены.Обычно это может применяться для замены частей линий, которые соответствуют другим критериям, произвольными функциональными данными.
Использование комбинированных нормальных команд
Это хорошо для простых вставок или сложного редактирования. Как и в случае с замещением, мы будем использовать глобальное сопоставление, но вместо подстановки регулярного выражения мы будем выполнять серию операций, как если бы они были напечатаны пользователем.
Пример для вашего вопроса
Как это работает
Используемые значения очень похожи на замену (мы все еще используем printf, чтобы отформатировать наш номер, чтобы он был дополнен 0 до 2 цифр), но операция отличается.
Здесь мы используем команду execute, которая принимает строку и запускает строку как команду ex (
:help :exe
). Мы создаем строку, которая объединяет «normal! I» с нашими данными, которые будут «normal! I01» в первый раз и «normal! I02» во второй раз и т. Д.Команда
normal
выполняет операции как в обычном режиме. В этом примере наша обычная командаI
, которая вставляет в начало строки. Если бы мы использовалиdd
его, то удалили бы строку,o
открыли бы новую строку после совпавшей строки. Это как если бы вы печаталиI
(или любые другие операции) самостоятельно в обычном режиме. мы используем!
после,normal
чтобы убедиться, что никакие отображения не мешают нам. См:help :normal
.Затем вставляется значение нашего printf, как в первом примере использования замены.
Этот метод может быть сложнее, чем регулярное выражение, потому что вы можете делать такие вещи, как
execute "normal! ^2wy" . i . "th$p"
переход к началу текста^
, перемещение вперед на 2 слова2w
, рывок до i-го символа «h»y" . i . "th
, переход к концу строки$
и вставкаp
.Это почти как запуск макроса, но на самом деле он не использует регистр и может объединять строки из любых выражений. Я считаю это очень мощным.
Подход, где каждый уровень имеет свой счетчик
Возможно, вы захотите, чтобы каждый уровень имел свой счетчик. Если вы заранее знаете максимальное количество уровней, вы можете сделать следующее (добавить дополнительный код, чтобы найти самый большой уровень, может быть не сложно, но ответ будет слишком длинным. Это становится длинным, как есть).
Во-первых, давайте освободим i, если мы уже использовали его как целое число. Мы не можем преобразовать i в список, мы должны создать его таким образом.
Далее, давайте установим i в список, содержащий количество уровней. Вы показали 2 в своем вопросе, но давайте примем 10 для удовольствия. Поскольку индексирование списка основано на 0, и я не хочу беспокоиться о корректировке для 1, как ваш список, мы просто создадим достаточно элементов (11) и никогда не будем использовать индекс 0.
Далее нам нужен способ получить номер уровня. К счастью, замена также доступна как функция, поэтому мы дадим ей нашу строку и извлечем номер уровня
substitute(getline("."), "^Level \\(\\d\\):.*", "\\=submatch(1)", "")
Поскольку теперь я - список из 11
1
с (каждый индекс является счетчиком для нашего уровня), теперь мы можем настроить любой из приведенных выше примеров, чтобы использовать результат этой замены:С помощью команды замены:
С помощью обычной команды:
Пример ввода:
Пример вывода:
источник
Вы можете построить с https://stackoverflow.com/a/4224454/15934, чтобы заполнить нулями свои номера.
Но чтобы упростить действие заполнения чисел, я бы пошел для пары функций и команды:
Затем выберите свои строки и введите
:PrependNumber
(вы увидите:'<,'>PrependNumber
. [Примечание: команда принимает необязательный параметр: шаблон, перед которым будет вставлен номер]источник
line(".")
означает "использовать текущий номер строки"? Это было моей проблемой 1. с предыдущими ответами, которые я смог найти.$HOME/vimfiles/plugin/whatevernameyouwish.vim
. Или даже ваш$HOME/_vimrc
(имя файла Windows), если вы предпочитаете (в первый раз). Если вы не уверены, что $ HOME находится на вашем компьютере, спросите vim, что он думает ->:echo $HOME
:source
если скрипт vim правильно установлен в нужном каталоге ({rtp} / plugin или {rtp} / ftplugin / {filetype} / ftplugin для специфических плагинов для файловых типов).:source
это то, с чем нам пришлось играть более полутора десятилетий назад.Вы можете подойти к нему, записав макрос. Начиная с исходного файла, добавьте к первому экземпляру номер.
Наведите курсор на
01
, выберите и дерните его с помощьюyiw
. Теперь вы хотите записать свои действия с этого момента.qq/^Level 1<CR>P<C-A>A<space><esc>0yiwq
qq
Запустить макрос в регистре q/^Level 1<CR>
Поиск строки, начинающейся с «Уровень 1»P
вставить перед курсором (содержит ваш номер)<C-A>
увеличивает числоA<space><esc>
Вставьте пробел после числа0
Перейти к началуyiw
дергать текущий номерq
Конец макросаЗатем повторите этот макрос, используя
@q
.источник
<C-A>
контроль + а? Это выбирает все в Vim на Windows.