Курс по Vim. Часть 3. Работа с регулярными выражениями и макросами в Vim
Мы запустили бесплатный курс по легендарному редактору кода Vim. В нём 16 уроков. Сегодня — регулярные выражения, управление окнами, макросы.
Иллюстрация: Polina Vari для Skillbox Media
За 16 уроков мы рассмотрим всё, что нужно для старта работы с Vim:
- историю текстовых редакторов;
- работу в режиме вставки, в командном режиме, режиме командной строки, визуальном режиме;
- использование регулярных выражений и создание макросов;
- плагины, пакетные менеджеры плагинов;
- конфигурацию Vim, работу с файлом .vimrc (в том числе на примере файла .vimrc автора курса);
- работу с Neovim;
- настройку автодополнения.
Сегодня будет три видеоурока. Подробно разберём, для чего нужны регулярные выражения, как управлять окнами Vim и задавать макросы.
Как устроен курс
Мы публикуем видеоуроки и текстовые расшифровки — вы можете смотреть или читать теорию.
Автор курса
Паша Калашников
Тимлид в Purple Magic, продюсер видео в Red Magic, соведущий IT Way Podcast, автор курсов по этому вашему программированию. Любит Ruby.
Урок 8
Использование регулярных выражений
У нас нет задачи научить вас всем возможностям регулярных выражений: мы покажем несколько примеров их использования именно в Vim. Потому что кейсы использования регулярок, которые применяются для текстовых редакторов, не всегда очевидны с первого взгляда.
Мы с вами уже поговорили о возможностях замены в Vim. Повторим — это делается через s:
Из предыдущих уроков мы знаем, что к этой команде можно добавить g — и тогда заменяться будет каждое вхождение в строке. Поговорим о других аргументах.
Добавление аргумента с (confirm) позволит самостоятельно выбрать, какие замены делать, какие нет. Вводим, например, команду : s/user/admin/gc — и меняем все user в строке на admin с подтверждением каждой замены:
Редактор будет последовательно выделять их и просить подтверждения. Подтверждение производится клавишей y (yes), отклонение — клавишей n (no). Можно также заменить все оставшиеся вхождения, нажав клавишу a.
Аргумент i позволит игнорировать регистр букв. Попробуем ввести его для текущей строки : s/user/admin/gi:
Как мы видим, заменились все слова user вне зависимости от регистра.
В предыдущих уроках мы уже говорили о том, что перед использованием специализированных символов в регулярных выражениях нужно вставлять обратный слеш. Но иногда сделать это довольно сложно — например, для замены длинного пути файла придётся писать что-то типа такого:
Много обратных слешей и сложно читается. В таких ситуациях проще использовать лайфхак: вместо слешей в команде s ставить двоеточия:
Тогда можно напрямую использовать слеши. Естественно, при таком написании перед двоеточиями нужно вставлять обратный слеш.
Использование пайпа поможет найти строки, которые содержат два и больше регулярных выражения. Например, мы хотим найти все строки со словами user или admin. Вводим /user\|admin:
Обратите внимание, что в выражении есть обратный слеш. Если его не поставить, регулярка начнёт искать user|admin.
Чтобы найти все слова, которые заканчиваются определённым регулярным выражением, можно использовать угловую скобку. Например, мы хотим увидеть все слова, которые заканчиваются на er. Вводим /er\>:
Обратите внимание, что и здесь есть обратный слеш. С началом слова примерно то же самое, только используем открывающую угловую скобку.
Естественно, это лишь часть лайфхаков, которые доступны в регулярных выражениях Vim. Поищите сами — и найдите те, которые пригодятся именно вам.
Напоследок покажем несколько часто используемых команд, связанных с регулярными выражениями.
Удаление всех пустых строк в файле производится командой : g/^$/d. Каждая строка, даже если она пустая, имеет начало и конец. Соответственно, строки, состоящие только из начала и конца, считаются пустыми.
Если так получилось, что в вашем файле есть строки, в которых, например, только пробелы, символы табуляции и так далее, используем команду : g/^\s*$/d. Комбинация \s в этой команде означает пробельные символы. Всё выражение в итоге читается так: удалить строки, в которых между началом и концом только пробельные символы в любом количестве (в том числе и нулевом). Ведь звёздочка, или астериск, обозначает любое количество символов, в том числе и нулевое.
Кстати, для этого кейса есть ещё один вариант. Можно использовать команду : v/\S/d, где \S означает любой символ, кроме пробельных, а : v — это аналог команды g, с тем отличием, что регулярное выражение инвертируется. Это хорошая фича для простых регулярок.
Урок 9
Работа с окнами Vim
Ранее мы уже рассмотрели команды и способы манипуляции окнами: научились открывать файлы в текущем и в новом окне, в горизонтальном и вертикальном расположении. Попробуем ещё несколько возможностей управления окнами в Vim.
Чтобы перейти в соседнее окно, по умолчанию используется комбинация клавиш Ctrl + w и направление, в какое окно перейти. Например, Ctrl + w l переместит вас в окно правее:
Обратите внимание, что направление нужно нажимать, отжав Ctrl + w. Это не совсем удобно, поэтому лучше вспомнить предыдущий урок, где мы обсуждали, как настроить этот переход на Ctrl + направление. Так будет проще.
Команда : split открывает новое окно с горизонтальным разделением:
По умолчанию оно будет расположено ниже текущего окна.
Команда : vsplit открывает новое окно с вертикальным разделением:
По умолчанию оно откроется справа. Обратите внимание, что, если в текущем окне уже открыт файл, в новом он откроется тоже.
По умолчанию новые окна делят предыдущее пополам по вертикали или горизонтали. Существует набор команд, которые позволяют менять размер окна.
Ctrl + w 10 + увеличит высоту окна на 10 строк. Ctrl + w 10 - — соответственно, уменьшит.
Ctrl +w _ увеличит высоту окна до возможного максимума, оставив всем остальным окнам по одной строке:
Эта команда может быть полезна, если вы хотите временно посмотреть больше содержимого в текущем файле. После этого вы можете вернуть размер всех окон к стандартному с помощью команды Ctrl + w =:
Увеличить ширину окна на один символ можно, нажав сочетание Ctrl + w >, уменьшить — соответственно, Ctrl + w <. Если вы хотите задать другое число символов, на которое хотите расширить или сузить своё окно, добавьте его к указанным выше комбинациям. Например, Ctrl + w 10 > увеличит размер вашего окна на 10 символов. Советуем всегда выставлять ширину окна по максимальной длине строки вашего кода. Допустим, в Ruby-проектах она составляет обычно 80 или 120 символов.
Чтобы увеличить максимально ширину окна, используют команду Ctrl + w |.
Безусловно, большинство фич, которые мы перечислили, можно делать в Vim и с помощью мыши, если она включена. Но моё мнение, что даже в управлении окнами она будет скорее мешать работе. С другой стороны, освоив описанные выше команды, вы научитесь думать, как использовать каждый пиксель на мониторе с максимальной пользой, а не просто увеличивать и уменьшать размеры как получится.
Наконец, главный лайфхак: весь набор клавиш можно забиндить в одну команду и сразу раскрывать нужное количество окон при открытии редактора. Или, например, сделать разные настройки для разных проектов. Со временем это станет настолько обыденным, что вы перестанете считать это чем-то сложным. В следующем уроке мы с вами попробуем одну из самых крутых фич Vim — макросы!
Урок 10
Макросы
Макросы — штука, которую начинающие специалисты почему-то игнорируют не только в Vim, но и во всех языках программирования, а также в Excel и других программных продуктах. А зря, ведь макросы позволяют творить магию: вместо того чтобы долго и муторно ковырять что-то вручную, можно кое-что подкрутить — и всё будет делаться само!
Для Vim это в первую очередь возможность настроить повторяющиеся действия. Давайте попробуем перепоручить их макросу. Например, на седьмом уроке про визуальный режим мы рассматривали CSV-файл с данными пользователей, в котором, прежде чем удалить столбцы, их нужно было выделять вручную:
Теперь представим подобный CSV-файл на 10 тысяч строк, в каждой из которых чья-то фамилия, инициалы телефоны и ID в формате UUID:
Допустим, нам по какой-то причине потребовалось перенести данные из этого CSV в консоль Ruby как массив массивов. Более того: после инициалов нужно поставить точки, во всех телефонах 8 заменить на +7 и каждую строку обрамить в кавычки, потому что в Ruby так принято по умолчанию.
Конечно, можно написать в Ruby скрипт со сложной командой замены через режим командной строки, который соберёт данные из CSV и сделает всё, что описано выше. Но нам лень — поэтому давайте используем макросы.
Переходим на первую строку, нажимаем Shift + o, ставим открывающую квадратную скобку, потому что именно так обозначаются массивы в Ruby. Это будет скобка нашего основного массива:
Переходим на следующую строку в командном режиме. Чтобы начать запись макроса, нажимаем q a, где q — это команда начала записи макроса, a — имя макроса; впрочем, вы можете назвать его любым другим символом:
Подумаем, какие действия предстоит повторять макросу. Строки CSV-файла разделены запятыми — будем ориентироваться на них. Сперва нужно поставить первую кавычку для имени пользователя:
Далее ищем пробел с помощью команды f пробел:
Конечно, мы можем прыгнуть на одно слово вперёд с помощью w, но тогда макрос отработает неправильно на двойных фамилиях, потому что технически это два слова. Значит, доходим до пробела. Переходим на один знак вперёд, чтобы поставить точку после первого инициала, ставим точку после второго инициала. Далее переходим к первой запятой с помощью f,:
Ставим закрывающую кавычку для имени пользователя, переходим к цифре 8 в телефонах:
Нажимаем s» + 7, где « — первая кавычка в обозначении телефона как строки:
После каждого ввода самое главное — не забывать нажимать Esc, чтобы возвращаться обратно в командный режим. Макрос запоминает и переходы между режимами. Переходим к концу телефона. Тут можно использовать w, потому что мы считаем, что в телефонах разделителей у нас нет:
Ставим вторую кавычку для телефона, переходим к запятой. Ставим первую кавычку, нажимаем Esc и Shift + a, чтобы вставить последнюю кавычку, закрывающую квадратную скобку и запятую:
Переходим на следующую строку в то же место, где мы начали записывать макрос:
Важно, чтобы макрос сам переходил на следующую строку каждый раз. Много действий, да. Более того, если вы опечатаетесь в середине записи, ничего страшного, в некоторых ситуациях можно сделать исправление. Макрос тоже будет ошибаться и делать исправление. Вы сами с опытом поймёте, когда можно исправлять действия макроса, а когда лучше начать сначала. Теперь запускаем макрос с помощью команды @a. @ вызывает макросы, a — это имя макроса:
Макрос применился один раз. Чтобы выполнить его до конца файла, выполняем 10000@a:
Магия! Самое главное — что все изменения после выполнения 10 000 повторений макроса можно отменить с помощью единичного нажатия u:
Есть и более простые применения макроса. Допустим, вот эта строка кода слишком длинная, потому что в вызове этой функции слишком много аргументов. Мы хотим распределить их в столбик:
Некоторые литеры в языках программирования или плагины для форматирования могут это делать сами. Но если такой опции нет, просто записываем такой макрос:
Потом повторяем его восемь раз:
Макросы — сильный инструмент, позволяющий быстро менять не только исходный код, но также и строковые файлы с большим количеством данных.
В следующем уроке мы поговорим об инфраструктуре вокруг Vim.