Грамматика Vim: операторы + движения = команды

Рейтинг: 64.6% · 12 голосов
Исчерпывающий курс по Vim и Neovim: модальное редактирование и грамматика (операторы, движения, текстовые объекты, точка-команда), регистры, метки, макросы, поиск и :substitute, :global, буферы/окна/quickfix, визуальный режим, конфигурация на Lua, маппинги, плагины (lazy.nvim), LSP, автодополнение (blink.cmp), Treesitter, fuzzy-поиск, Git, эргономика и антипаттерны. 34 главы, актуально на 2026 (Vim 9.1, Neovim 0.11/0.12).
Ответить
Аватара пользователя
Roman_Vim
Сообщения: 34
Зарегистрирован: 11 май 2026, 05:31

Грамматика Vim: операторы + движения = команды

Сообщение Roman_Vim »

Оглавление курса (34)
  1. Философия Vim: модальное редактирование и почему это актуально в 2026
  2. Установка и выживание: первый запуск, режимы, как выйти
  3. Перемещение по тексту: движения как основа эффективности
  4. Базовое редактирование: вставка, удаление, копирование
  5. Грамматика Vim: операторы + движения = команды (вы здесь)
  6. Текстовые объекты: оперируем структурой, а не символами
  7. Точка-команда и повторяемость: "один штрих, чтобы повторить"
  8. Регистры: продвинутая работа с буфером обмена
  9. Метки и прыжки: навигация по истории перемещений
  10. Поиск: /, ?, *, # и магия паттернов
  11. Замена :substitute и регулярные выражения Vim
  12. Команда :global - оружие массового редактирования
  13. Буферы, окна и вкладки: организация рабочего пространства
  14. Quickfix и location list: пакетная работа по всему проекту
  15. Навигация по файлам: netrw, fuzzy-поиск и проекты
  16. Макросы: автоматизация повторяющихся правок
  17. Визуальный режим и блочное редактирование
  18. Трюки режима вставки
  19. Свёртки, автодополнение и аббревиатуры (встроенные)
  20. Конфигурация с нуля: init.lua и разумные дефолты 2026
  21. Маппинги: leader, which-key и здравые привычки
  22. Скриптинг: основы Vimscript и Lua для Neovim
  23. Менеджеры плагинов: lazy.nvim и lazy-loading
  24. Neovim в 2026: чем отличается и почему выбирают
  25. LSP в Neovim: умные возможности языка
  26. Автодополнение 2026: blink.cmp против nvim-cmp
  27. Treesitter: точная подсветка и структурное редактирование
  28. Fuzzy-поиск: Telescope, fzf-lua и snacks.picker
  29. Git внутри редактора: fugitive, gitsigns и lazygit
  30. Дистрибутивы, отладка и терминал: быстрый старт и интеграции
  31. Vim повсюду: IDE, браузер и shell
  32. Эргономика и антипаттерны: как не навредить себе и не застрять
  33. Рабочие рецепты, тренажёры и план обучения
  34. Шпаргалка-справочник: все ключевые команды одним списком
В предыдущих главах вы научились перемещаться по тексту (глава 03) и выполнять базовые правки - вставлять, удалять, копировать (глава 04). Возможно, у вас уже накопилось ощущение, что команд слишком много и все их не запомнить: dw, de, d$, c0, y}, >G... Хорошая новость: запоминать их по отдельности не нужно. Все эти команды - не отдельные сущности, а результат применения одного простого правила.

Эта глава - смысловой центр всего курса. Здесь вы перестанете воспринимать Vim как набор горячих клавиш и начнёте видеть в нём язык редактирования с собственной грамматикой. Поняв эту грамматику один раз, вы будете выводить нужные команды на лету - в том числе те, которые никогда специально не учили. Это тот самый момент, после которого Vim "щёлкает" и становится по-настоящему быстрым.

Главная идея: команда как предложение

В естественном языке мы строим осмысленные фразы из глаголов и существительных: "удали слово", "измени абзац", "скопируй до конца строки". Vim устроен ровно так же. Команда редактирования - это маленькое предложение:

Код: Выделить всё

команда = [count] оператор [count] движение
Здесь:
  • оператор (operator) - это глагол: что сделать. Удалить, изменить, скопировать, сдвинуть отступ.
  • движение (motion) - это объект действия: над чем сделать. До конца слова, до конца строки, до следующего абзаца.
  • count - необязательный числовой множитель: сколько раз.
Например, команда d2w читается буквально как "delete two words" - удалить два слова. Здесь d - оператор delete, 2 - count, w - движение "на слово вперёд".

Почему это так важно? Потому что знание перестаёт складываться и начинает умножаться. Если вы знаете N движений и M операторов, вам доступно не N + M, а N x M команд. Выучили новое движение } (на абзац вперёд) - и вы автоматически умеете d} (удалить до конца абзаца), c} (изменить его), y} (скопировать), >} (увеличить отступ). Не нужно учить четыре новые команды: вы уже знаете операторы, осталось скомбинировать.

Именно поэтому опытные пользователи Vim не "вспоминают сочетания клавиш". Они конструируют команду из глагола и объекта прямо в момент редактирования - так же, как вы не вспоминаете заранее заученные предложения, а собираете их из слов на ходу.

Операторы: словарь глаголов

Оператор сам по себе ничего не делает - он "ждёт" движение, чтобы понять, к какому участку текста применяться. Нажав оператор, вы переводите Vim в особое состояние operator-pending (ожидание движения), где он буквально ждёт, что вы укажете объект.

Вот основные операторы Vim:

Код: Выделить всё

Оператор  |  Действие (глагол)                   |  Мнемоника
----------+--------------------------------------+-----------------------------------------
d         |  удалить (delete)                    |  вырезать текст в регистр
c         |  изменить (change)                   |  удалить и сразу перейти в режим вставки
y         |  скопировать (yank)                  |  положить в регистр, не удаляя
>         |  увеличить отступ                    |  сдвиг строк вправо
<         |  уменьшить отступ                    |  сдвиг строк влево
=         |  автоформатирование отступов         |  по правилам equalprg/indent
gu        |  в нижний регистр                    |  gu = go lower
gU        |  в верхний регистр                   |  gU = go Upper
g~        |  переключить регистр                 |  инвертировать case
gq        |  переформатировать текст             |  перенос по textwidth
gw        |  переформатировать, сохранив курсор  |  как gq, но курсор на месте
!         |  прогнать через внешнюю команду      |  фильтрация строк через shell
Несколько важных замечаний.

c - это d плюс вставка. Оператор change удаляет указанный участок и сразу оставляет вас в режиме вставки. Это позволяет менять текст в одно движение мысли: не "удали, потом печатай", а "измени вот это".

Операторы с префиксом g (gu, gU, g~, gq, gw) - это полноценные операторы, просто их клавиша состоит из двух символов. g здесь - не модификатор "на лету", а часть имени оператора. После gU Vim точно так же переходит в operator-pending и ждёт движение: gUw сделает заглавным слово вперёд.

gq и gw переформатируют текст по ширине textwidth - незаменимы для аккуратных абзацев в комментариях, Markdown, коммит-сообщениях. Разница в том, что gw возвращает курсор на исходную позицию, а gq оставляет его в конце переформатированного участка.

! - мост к Unix-философии: выделенные строки уходят на стандартный вход внешней программы, а её вывод заменяет их. Например, !}sort отсортирует абзац. А чтобы прогнать остаток файла через awk, нажмите движение !G (оператор ! + движение G до конца файла), а затем введите команду: awk '{print $2}'<CR>. Подробнее об интеграции с shell - в главе 31.

Движения: символьные и линейные, inclusive и exclusive

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

Символьные (charwise) и линейные (linewise) движения
  • Символьные движения работают с диапазоном символов. w, e, f, t, 0, $, %, }, { - символьные. dw удалит ровно от курсора до начала следующего слова, не трогая остальную строку.
  • Линейные движения захватывают целые строки. j, k, G - настоящие linewise по своей природе. dj удалит две строки целиком (текущую и следующую), а не "вниз на символ".
Это часто удивляет новичков: d + вертикальное движение j/k/G удаляет строки целиком, потому что эти движения по своей природе линейные. Логика проста: нельзя осмысленно "удалить полстолбца" - оператор расширяет диапазон до целых строк.

Отдельный нюанс - } и { (на абзац вперёд/назад). Формально это exclusive charwise движения, а не linewise. Но на практике с оператором они почти всегда ведут себя построчно: срабатывает специальное правило exclusive-linewise - когда конец движения попадает в первый столбец, а старт был на/до первого непробельного символа, exclusive-движение повышается до linewise. Поэтому d} обычно удаляет целые строки абзаца, хотя } по своей сути символьное (подробности - :help exclusive-linewise).

Inclusive и exclusive движения

Внутри символьных движений есть второе деление - включает ли движение конечный символ:
  • exclusive (исключающее): символ под конечной позицией не входит в диапазон. Таковы, например, w, 0. dw, стоя на начале слова hello world, удалит hello и оставит world - пробел вошёл, а w из world нет.
  • inclusive (включающее): конечный символ входит в диапазон. Таковы e, f{char}, t после корректировки, %, а также $. de удалит до конца слова вместе с последней буквой. Именно потому, что $ inclusive, d$ удаляет до конца строки включая последний символ (см. :help $).
Классическая иллюстрация разницы между dw и de:

Код: Выделить всё

Было (курсор на 'h'):   hello world
Нажимаем: dw         -> world          (удалено "hello " вместе с пробелом)

Было (курсор на 'h'):   hello world
Нажимаем: de         -> " world"       (удалено "hello", пробел остался)
Понимание inclusive/exclusive объясняет, почему de и dw дают разный результат и почему f (find - встаёт на символ) удобнее t (till - встаёт перед символом) для удаления "до буквы включительно". Эти тонкости перестают быть загадкой, как только вы держите в голове само свойство, а не зубрите частные случаи.
На практике гораздо удобнее и предсказуемее оперировать текстовыми объектами (diw, ci", dap), а не движениями: они не зависят от позиции курсора внутри объекта. Это тема следующей главы 06 - а пока важно понять сам механизм оператор+движение, на котором текстовые объекты потом "вырастут".
Особый случай: cw ведёт себя как ce

Есть одна классическая ловушка грамматики, о которой стоит знать заранее. Логично ожидать, что cw относится к dw так же, как c к d, - но это не совсем так. Если курсор стоит внутри слова (не на пробеле), cw ведёт себя как ce: изменяет до конца текущего слова, не захватывая идущий следом пробел. Аналогично cW работает как cE.

Сделано это намеренно: при изменении слова пробел после него почти никогда не нужно затирать, иначе слова склеились бы. Так что cw - единственный оператор, для которого w тихо превращается в e. У dw, yw, >w такого исключения нет - они захватывают пробел как обычное exclusive-движение.

Код: Выделить всё

Было (курсор на 'e' в hello):  hello world
Нажимаем: dw                -> lo world        (dw от 'e': удалено "hel", пробел НЕ трогаем, потому что курсор в середине)
Нажимаем: cw (вместо 'hel') -> ведёт себя как ce: меняет до конца слова, пробел остаётся
На практике эту тонкость проще обойти, используя текстовый объект ciw (изменить слово целиком из любой позиции) - он не зависит ни от стороны курсора, ни от этого исключения. Но знать про cw == ce полезно, чтобы не удивляться поведению.

Форсирование типа движения: v, V, <C-v> после оператора

Тип движения (charwise/linewise) можно переопределить на лету прямо в operator-pending, вставив между оператором и движением одну из клавиш v, V или <C-v> (см. :help o_v):
  • v - форсировать charwise (и заодно инвертировать inclusive/exclusive у движения);
  • V - форсировать linewise;
  • <C-v> - форсировать blockwise (прямоугольный блок).
Это даёт точный контроль там, где дефолтное поведение неудобно:
  • dvj - удалить вертикально вниз, но charwise: снимет от курсора до того же столбца на следующей строке, а не две строки целиком (как сделал бы обычный dj).
  • dV} - удалить абзац строго построчно, даже если правило exclusive-linewise по какой-то причине не сработало бы.
  • yvj, cve и т. п. - та же логика для копирования и изменения.
Особенно полезен v для инверсии inclusive/exclusive: dvf) удалит до скобки ) не включая её (обычный df) включил бы скобку). Это редкий, но точный инструмент - держите его в арсенале для случаев, когда движение "на один символ/строку" не туда.

Удвоение оператора: операция над строкой

Что произойдёт, если за оператором ввести... сам этот оператор? Vim трактует удвоенный оператор как команду над текущей строкой целиком (linewise):

Код: Выделить всё

Команда    |  Значение
-----------+------------------------------------------------------------------------------------------
dd         |  удалить текущую строку
cc         |  изменить текущую строку (очистить и войти в insert, сохранив отступ)
yy         |  скопировать текущую строку (в Vim синоним Y; в Neovim по умолчанию Y переназначен на y$)
>>         |  увеличить отступ текущей строки
<<         |  уменьшить отступ
==         |  выровнять отступ текущей строки
guu / gUU  |  строку в нижний / верхний регистр
g~~        |  переключить регистр строки
gqq        |  переформатировать строку
Это не отдельное "волшебное" правило, а естественное следствие грамматики: удвоенный оператор означает "применить операцию к строке". И count работает как обычно: 3dd удалит три строки, 5>> сдвинет вправо пять строк, 2yy скопирует две строки.
Vim vs Neovim: ловушка с Y. В классическом Vim 9.1 Y - синоним yy (скопировать строку целиком). Но в Neovim начиная с 0.6 (2021) дефолтный маппинг изменён: Y переназначен на y$ - скопировать от курсора до конца строки. Это сделано для согласованности с C (c$) и D (d$). Если вы переносите мускульную память между редакторами, держите это в голове: yy копирует строку в обоих, а вот Y ведёт себя по-разному. Чтобы вернуть в Neovim старое поведение, добавьте vim.keymap.set('n', 'Y', 'yy').

Код: Выделить всё

Было (курсор где угодно на 2-й строке):
    alpha
    beta      <- курсор здесь
    gamma
    delta

Нажимаем: 2dd ->
    alpha
    delta
Counts и их композиция

count - числовой множитель, который вы вводите перед оператором, перед движением, или и там, и там. Его можно ставить в нескольких местах, и поведение строго определено.

Count перед движением просто повторяет движение: 3w - на три слова вперёд, 5j - на пять строк вниз.

Count перед оператором повторяет всю операцию: 3dd - удалить три строки.

Два count перемножаются. Если вы поставили count и перед оператором, и перед движением, Vim умножает их:

Код: Выделить всё

2d3w  ==  d6w   ->  удалить 6 слов
3d2j  ==  d6j   ->  удалить от текущей строки + 6 строк вниз (linewise)
2d3w читается как "дважды (удалить три слова)" = удалить шесть слов. Это не частный трюк, а последовательное применение математики: оба множителя действуют на одно действие.

Код: Выделить всё

Было (курсор на 'one'):  one two three four five six seven
Нажимаем: 2d3w        -> seven
                         (удалены 6 слов: one two three four five six)
На практике одного count обычно достаточно (d5w), а перемножение полезно знать в первую очередь для понимания - и для написания собственных маппингов, о чём ниже.

Как из горстки кирпичей рождаются сотни команд

Сведём всё воедино. Возьмём матрицу: по одной оси операторы, по другой - движения и объекты. На пересечениях - готовые команды:

Код: Выделить всё

    |  w (слово)  |  $ (до конца строки)  |  } (абзац)  |  iw (внутр. слово)  |  i( (внутри скобок)
----+-------------+-----------------------+-------------+---------------------+--------------------
d   |  dw         |  d$                   |  d}         |  diw                |  di(
c   |  cw         |  c$                   |  c}         |  ciw                |  ci(
y   |  yw         |  y$                   |  y}         |  yiw                |  yi(
gU  |  gUw        |  gU$                  |  gU}        |  gUiw               |  gUi(
>   |  -          |  -                    |  >}         |  -                  |  -
Пять операторов и пять объектов дают 25 команд. Добавьте ещё один оператор - получите ещё пять команд бесплатно. Добавьте текстовый объект it (внутри тега) - снова плюс операторы команд. В этом и состоит сила композируемости: учите паттерн, а не комбинации.

Поэтому правильная стратегия обучения - не "запомнить, что gUiw делает слово заглавным", а понять: gU (верхний регистр) + iw (внутреннее слово). Тогда gUip (абзац в верхний регистр), guap (абзац в нижний) и десятки других команд вы соберёте сами, ни разу их предварительно не "изучив".

Практические примеры: было -> нажимаем -> стало

Код: Выделить всё

# Изменить слово целиком, начав с любого места слова - лучше через объект iw
Было:   const userName = getValue();    (курсор на 'a' в userName)
Нажать: ciwuserId<Esc>
Стало:  const userId = getValue();

Код: Выделить всё

# Скопировать тело функции до конца блока и вставить ниже
Было (курсор на первой строке тела):
    return a + b;
    // ...
Нажать: y} затем p   ->  дублирует абзац ниже

Код: Выделить всё

# Сделать заглавной всю строку-заголовок
Было:   глава пятая
Нажать: gUU
Стало:  ГЛАВА ПЯТАЯ

Код: Выделить всё

# Удалить три строки и сразу начать печатать замену
Было:
    foo()      <- курсор
    bar()
    baz()
    qux()
Нажать: 3cc
Стало:  (три строки удалены, вы в режиме вставки, отступ сохранён)
    qux()

Код: Выделить всё

# Увеличить отступ абзаца кода
Нажать: >}    ->  сдвигает весь абзац вправо на один shiftwidth

Код: Выделить всё

# Поменять содержимое строки в кавычках
Было:   title = "old value"     (курсор где угодно на строке)
Нажать: ci"new value<Esc>
Стало:  title = "new value"

Код: Выделить всё

# Отсортировать абзац через внешнюю команду
Было:
    banana
    apple
    cherry
Нажать: !}sort<CR>
Стало:
    apple
    banana
    cherry
Лучшие практики 2026

Думайте "глагол + объект", а не сочетаниями клавиш. Единственное грамматическое правило Vim - оператор применяется к движению или текстовому объекту. Запомнив N движений и M операторов, вы получаете N x M команд; знание работает множителем, а не суммой. Учите паттерн (diw, ci(, gUap), а не таблицу готовых комбинаций.

Предпочитайте текстовые объекты движениям там, где важна повторяемость. Движения вроде dw, d$ зависят от позиции курсора внутри слова и плохо дружат с командой повтора . (точка). Текстовый объект diw, ci" работает одинаково из любой точки объекта, делая . предсказуемым. Это фундамент повторяемого редактирования - подробно в главах 06 (объекты) и 07 (dot-repeat).

Используйте count как множитель осознанно, а в своих маппингах берите v:count1, а не v:count. Два count перемножаются (3d2w == d6w). Когда вы пишете собственную функцию или маппинг, который должен учитывать счётчик, берите v:count1: при отсутствии счётчика он даёт 1 (разумный дефолт), тогда как v:count вернёт 0 и сломает поведение. Это типичная ошибка при написании Vimscript/Lua-маппингов (см. главу 22).

В Neovim делайте свои операторы dot-repeatable через operatorfunc + g@. Если вы создаёте собственный оператор-подобный маппинг, нативный путь без сторонних зависимостей - выставить operatorfunc на колбэк и вернуть из {expr=true}-маппинга строку g@. Тогда . будет повторять вашу операцию, а Neovim сам выставит метки '[ и '] на границы движения. Это убирает зависимость от классического плагина tpope/vim-repeat. Детали реализации - в главах 07 и 22.

Расширяйте грамматику плагинами, которые сами поддерживают . и count. Например, операции surround (добавить/удалить/заменить окружающие скобки и кавычки) от mini.surround или nvim-surround встраиваются в грамматику как новые "операторы". Современный mini.surround (организация nvim-mini) дополнительно поддерживает [count] и dot-repeat. Это естественное продолжение того же принципа композируемости. Подробнее об экосистеме - в главах 06 и 23.

Частые ошибки

Зубрить команды как отдельные сочетания. Самая дорогая ошибка. dw, de, d$, cc, yy - это не пять команд, которые надо заучить, а применения двух операторов к разным движениям. Пока вы воспринимаете их по отдельности, Vim кажется бесконечным списком клавиш. Как только увидите грамматику - список схлопнется в правило.

Путать символьные и линейные движения. Ожидать, что dj удалит "вниз на символ", - j линейное движение, поэтому dj удаляет две целые строки. Аналогично dG работает построчно. d} тоже обычно снимает целые строки, но по другой причине: } - exclusive charwise, повышаемое до linewise правилом exclusive-linewise (см. выше).

Не учитывать inclusive/exclusive. Удивляться, почему dw оставил последнюю букву слова на месте, а de - нет. w exclusive (не включает конечную позицию), e inclusive (включает символ под курсором). Это не баг, а определение движений.

Брать v:count вместо v:count1 в маппингах. При отсутствии счётчика v:count даёт 0, и операция выполняется ноль раз - то есть "ничего". Для повторяемого по умолчанию действия нужен v:count1.

Использовать движение там, где нужен повторяемый edit. dw повторённое точкой ведёт себя непредсказуемо из-за зависимости от позиции курсора. Если планируете повторять правку через ., берите текстовый объект (diw, di").

Забывать, что g-операторы - полноценные операторы. gU сам по себе ничего не делает и ждёт движение. Новички иногда жмут gU и недоумевают, почему "ничего не произошло" - Vim в operator-pending ждёт объект.

Ожидать, что cw симметричен dw. cw при курсоре внутри слова ведёт себя как ce (меняет до конца слова, не трогая пробел), тогда как dw пробел захватывает. Это не баг, а намеренное исключение. Чтобы не думать об этом - берите ciw.

Полагаться, что Y всюду равно yy. В Vim да, а в Neovim по умолчанию Y == y$. При переносе привычек между редакторами это источник тихих ошибок копирования.

Упражнения
  1. Матрица команд. Возьмите строку let result = compute(alpha, beta, gamma). Не подглядывая, выведите и выполните: удалить слово compute; изменить alpha на x; скопировать всё внутри скобок; сделать result заглавным. Для каждой задачи сначала проговорите "глагол + объект", потом нажмите.
  1. Inclusive vs exclusive. На строке foobar baz поставьте курсор на f и сравните результаты dw и de. Запишите, чем отличается итог и почему. Затем сравните df + пробел и dt + b.
  1. Линейные операции и count. В файле из 10 строк потренируйтесь: 3dd, 2yy затем p, 4>>, gUU. Убедитесь, что count и удвоение оператора работают так, как вы предсказываете до нажатия.
  1. Композиция count. На длинной строке из 8+ слов выполните 2d3w и убедитесь, что удалилось ровно 6 слов. Затем добейтесь того же результата другим способом (d6w) и сравните.
  1. Операторы с движением по абзацу. В коде с несколькими блоками примените >} (увеличить отступ абзаца), gq} (переформатировать абзац), =} (выровнять отступы). Понаблюдайте, как один и тот же объект } сочетается с разными операторами.
  1. Внешний фильтр. Создайте список из 5 неупорядоченных строк и отсортируйте абзац командой !}sort. Затем (на новых данных) пронумеруйте строки через !}nl или !}cat -n.
  1. Форсирование типа движения. На паре строк сравните dj и dvj: первое удалит две строки целиком, второе - charwise до того же столбца. Затем на строке foo (bar) поставьте курсор на f и сравните df) и dvf) - обратите внимание, что v инвертирует inclusive в exclusive (скобка останется). См. :help o_v.
  1. Ловушка cw. На строке hello world поставьте курсор на e в hello. Выполните dw (запомните результат), отмените (u), затем выполните cwX<Esc>. Убедитесь, что cw повёл себя как ce - изменил до конца слова, не тронув пробел. Повторите задачу через ciw и сравните удобство.
Главное из главы
  • Команда редактирования в Vim - это предложение: [count] оператор [count] движение. Оператор - глагол (что сделать), движение - объект (над чем).
  • Основные операторы: d (удалить), c (изменить + insert), y (скопировать), >/< (отступ), = (выровнять), gu/gU/g~ (регистр), gq/gw (переформатировать), ! (внешний фильтр). g-операторы - полноценные операторы из двух символов.
  • Движения бывают линейные (целые строки: j, k, G) и символьные; символьные делятся на exclusive (w, 0) и inclusive (e, f, $). Это определяет, попадает ли последний символ/строка в диапазон. Отдельно: }/{ - exclusive charwise, но с оператором обычно работают построчно по правилу exclusive-linewise.
  • Удвоение оператора (dd, yy, >>, gUU) применяет его к текущей строке целиком. Внимание на различие: yy копирует строку и в Vim, и в Neovim, но Y - это yy только в Vim, а в Neovim по умолчанию Y == y$.
  • Тип движения форсируется в operator-pending: v (charwise + инверсия inclusive/exclusive), V (linewise), <C-v> (blockwise). Например, dvj удалит charwise вниз, а не две строки. А cw - особый случай: внутри слова он работает как ce.
  • Counts перемножаются: 2d3w == d6w. В своих маппингах берите v:count1, а не v:count.
  • Сила Vim - в композируемости: N операторов x M объектов = N x M команд. Учите паттерн "глагол + объект", и сотни команд соберутся сами.
  • Дальше эта грамматика раскроется через текстовые объекты (глава 06) и повторяемость через . (глава 07) - именно там операторы раскрывают полную мощь.
👍4 ❤️4 🔥3 😄 🤔1
Аватара пользователя
thebest436
Сообщения: 1
Зарегистрирован: 14 май 2026, 21:23

Re: Грамматика Vim: операторы + движения = команды

Сообщение thebest436 »

вот эта глава реально щелкнула. я полгода тупо зубрил dw de d$ как отдельные кнопки и каждый раз лез в шпаргалку. а оказывается это просто d + движение и всё. теперь >} и c} собираю сам не вспоминая
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
chumly38
Сообщения: 1
Зарегистрирован: 06 июн 2026, 05:53

Re: Грамматика Vim: операторы + движения = команды

Сообщение chumly38 »

а у меня dvf) не сработало как написано, оказалось я раскладку не переключил и v вообще не дошло до вима. с английской раскладкой все ок, скобка осталась снаружи. так что если у кого 'не инвертирует' - проверьте раскладку первым делом
👍 ❤️1 🔥1 😄 🤔
Аватара пользователя
main_kolya
Сообщения: 1
Зарегистрирован: 07 июн 2026, 23:03

Re: Грамматика Vim: операторы + движения = команды

Сообщение main_kolya »

Roman_Vim писал(а):если курсор стоит внутри слова (не на пробеле), cw ведёт себя как ce
вот за это спасибо, я годами думал что у меня вим глючит когда cw не съедает пробел. так это by design. перешел на ciw и забыл проблему
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
maniac3
Сообщения: 1
Зарегистрирован: 13 май 2026, 08:18

Re: Грамматика Vim: операторы + движения = команды

Сообщение maniac3 »

лайфхак для тех кто пишет коммиты и markdown: gqap переформатит абзац по textwidth, очень удобно когда вставил длиннющую строку. а если не хочешь чтоб курсор ускакал в конец - бери gw вместо gq, он на месте оставляет
👍1 ❤️ 🔥 😄 🤔
Аватара пользователя
geek_andrei
Сообщения: 1
Зарегистрирован: 03 июн 2026, 03:42

Re: Грамматика Vim: операторы + движения = команды

Сообщение geek_andrei »

короткий вопрос про граничный случай. d} вроде по правилу exclusive-linewise строки целиком сносит, но если курсор НЕ на первом непробельном символе строки? тогда оно вроде уже charwise сработает и кусок строки останется. кто нить ловил такое или я путаю
👍2 ❤️ 🔥1 😄 🤔1
Ответить
← Предыдущая глава
Базовое редактирование: вставка, удаление, копирование
Следующая глава →
Текстовые объекты: оперируем структурой, а не символами

Все главы курса «Vim и Neovim: модальное редактирование от основ до современного Neovim»

Поделиться темой: ✈ Telegram VK

Вернуться в «Vim и Neovim: модальное редактирование от основ до Neovim 2026»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость