пример из гл. 16 «изучите vimscript на собственном опыте»

#vim

Вопрос:

Я пытаюсь выполнить упражнение из https://learnvimscriptthehardway.stevelosh.com/chapters/16.html

Пример текста, над которым необходимо поработать, таков:

 Topic One

=========

This is some text about topic one. 

It has multiple paragraphs.


Topic Two

=========

This is some text about topic two. It has only one paragraph.
 

Сопоставление для удаления заголовка Первой или Второй темы (в зависимости от того, в каком теле находится курсор) и перехода в режим вставки:

 :onoremap ih :<c-u>execute "normal! ?^==\ $r:nohlsearchrkvg_"<cr> 
 

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

Когда я опускаю $ и использую это сопоставление:

 :onoremap ih :<c-u>execute "normal! ?^==r:nohlsearchrkvg_"<cr>
 

это работает нормально, по-видимому, идентично другому отображению. Так в чем же польза от $ этого ?

Вот как г-н Лош объясняет это:

Первая часть,

 ?^== $
 

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

Но чего же $ он добивается? Я пытался ввести его вручную в командной строке, но я просто получаю звук ошибки. Однако он работает так, как задумано, как часть полной функции. но, как я уже сказал, когда я удаляю его и запускаю полную команду без него, он работает нормально.

Есть кое-что, чего мне не хватает в необходимости этого» $»… Может быть, это связано с «двумя или более знаками равенства и ничем другим«?

Ответ №1:

Команда автора:

 ?^== $
 

выполняет поиск в обратном направлении строки, состоящей исключительно из 2 или более знаков равенства:

  • ^ закрепляет шаблон в начале линии,
  • = соответствует буквальному знаку равенства,
  • ^= таким образом, соответствует буквальному знаку равенства в начале строки,
  • = соответствует второму знаку равенства,
  • соответствует одному или нескольким из предыдущих атомов, как можно большему числу,
  • = таким образом, соответствует одному или нескольким знакам равенства, как можно большему числу,
  • $ закрепляет шаблон в конце строки,

таким образом, приведенный выше шаблон будет соответствовать любой из следующих строк:

 ==
===
=============
etc.
 

но не такие строки, как:

 ==foo
==      <- six spaces
etc.
 

что как раз и является целью этого упражнения.

С другой стороны, ваша команда:

 ?^==
 

выполняет поиск в обратном направлении последовательности из двух одинаковых знаков в начале строки:

  • ^ закрепляет шаблон в начале линии,
  • == соответствует двум буквальным знакам равенства,

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

 ==
===
=============
etc.
 

но также и такие строки, как:

 ==foo
==      <- six spaces
etc.
 

потому что это недостаточно строго.

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

Короче говоря, шаблон Стива проверяет все поля, в то время как ваш-нет: он явный и точный, в то время как ваш неявный и неточный.

Ответ №2:

$ Является частью регулярного выражения, соответствующего строке, состоящей только из знаков равенства. Без этого ваше отображение распознало бы, например,

 This is not a heading
=This is not an underline
 

в качестве заголовка.

Означает «По крайней мере два предыдущих символа (=)». $ Означает конец строки, поэтому после знаков равенства ничего быть не может.