Перемещение по тексту: движения как основа эффективности

Рейтинг: 70.1% · 9 голосов
Исчерпывающий курс по 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

Перемещение по тексту: движения как основа эффективности

Сообщение 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. Шпаргалка-справочник: все ключевые команды одним списком
Часть I. Основы
В прошлых главах мы разобрали философию модального редактирования и научились выживать: запускать редактор, переключать режимы и не паниковать при выходе. Теперь начинается настоящая работа. Если модальность - это сердце Vim, то движения (motions) - его кровеносная система. Без беглого перемещения по тексту все остальные возможности редактора остаются недосягаемыми.

Эта глава целиком посвящена нормальному режиму и одному вопросу: как переместить курсор туда, куда нужно, минимальным числом нажатий. Звучит скромно, но именно навигация отделяет человека, который "знает Vim", от человека, который думает на Vim. И что важнее всего: движения, которые вы выучите здесь, - это не просто способ ходить по тексту. В главе 05 они станут аргументами для операторов (d, c, y), и каждое движение превратится в команду редактирования. Выучив навигацию сейчас, вы закладываете фундамент под всю грамматику Vim.

Зачем это нужно: эффективность измеряется в нажатиях

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

Ключевая идея главы: в Vim не "двигают курсор по чуть-чуть", а выражают намерение - к слову, к строке, к символу, к структуре. Чем точнее ваш словарь движений, тем меньше вы зажимаете клавиши.

hjkl и почему не стрелки

Базовое перемещение на один символ выполняется четырьмя клавишами домашнего ряда:

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

Клавиша  |  Направление
---------+-------------
h        |  влево
j        |  вниз
k        |  вверх
l        |  вправо
Мнемоника проста: j визуально похожа на стрелку вниз (хвостик), h - крайняя слева из четырёх, l - крайняя справа. Между ними j/k - вниз/вверх.

Почему не стрелки, ведь они интуитивнее? Три причины, и все они про эффективность.
  1. Руки остаются на домашнем ряду. Стрелки находятся в правом нижнем углу клавиатуры. Каждый раз, когда вы тянетесь к ним, правая рука покидает основную позицию, а возврат стоит времени и сбивает ритм. hjkl доступны без единого движения кисти.
  2. hjkl комбинируются со счётчиками и операторами. Вы можете написать 5j (вниз на пять строк) или d3l (удалить три символа справа). Со стрелками такие конструкции либо не работают, либо работают неуклюже.
  3. Стрелки - это "обезболивающее", которое мешает учиться. Пока стрелки под рукой, мозг не запоминает hjkl. Поэтому общепринятая практика - на старте сознательно отключить стрелки (об этом в разделе про лучшие практики).
Но есть нюанс, который должен сопровождать вас всю главу: hjkl - это аварийный минимум, а не основной инструмент. Зажатая j, чтобы спуститься на восемь строк, - антипаттерн. Почти всегда существует более точное движение: по словам, по абзацам, по экрану, поиском. Дальше мы разберём весь этот арсенал.

Движения по словам: w / b / e / ge

Перемещение посимвольно слишком мелкое. Чаще нужно прыгать словами:

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

Клавиша  |  Действие
---------+--------------------------------------------
w        |  в начало следующего слова (word - forward)
b        |  в начало предыдущего слова (back)
e        |  в конец текущего/следующего слова (end)
ge       |  в конец предыдущего слова
Тонкость в определении "слова". В Vim есть два понятия:
  • word (строчные w/b/e/ge) - последовательность букв, цифр и подчёркиваний, либо последовательность знаков пунктуации. Граница между ними считается границей слова. То есть в foo.bar() курсор остановится отдельно на foo, на ., на bar, на (, на ).
  • WORD (заглавные W/B/E) - последовательность любых непробельных символов, разделённая только пробелами/табуляцией/переводами строк. В foo.bar() всё это - одна WORD.

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

Клавиша  |  Действие
---------+--------------------------------
W        |  в начало следующей WORD
B        |  в начало предыдущей WORD
E        |  в конец текущей/следующей WORD
Правило выбора простое: строчные движения "мельче" и точнее, заглавные - "крупнее" и игнорируют пунктуацию. Если нужно перепрыгнуть user.profile.name целиком - W. Если нужно остановиться на каждом сегменте - w.

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

Было (| - курсор):
|const path = config.get("user.name");

Нажимаем w:
const |path = config.get("user.name");

Нажимаем w ещё раз:
const path |= config.get("user.name");

Из начала строки нажимаем W три раза:
const path = |config.get("user.name");
Заметьте: в этом примере и w, и W на третьем нажатии встают на одно и то же место - на =. Причина в том, что = здесь окружён пробелами, поэтому он является самостоятельной WORD (непробельный блок из одного символа). Так что W его вовсе не "проскакивает" - он честно на нём останавливается, ровно как и w. Разница между w и W тут просто ещё не проявилась.

Чтобы увидеть настоящую разницу, нужен фрагмент без пробелов между сегментами - например config.get("user.name"). Встанем на его начало:

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

Было:
const path = |config.get("user.name");

Жмём w несколько раз - курсор останавливается на каждом сегменте:
config|.get(...)    ->  config.|get(...)   ->  config.get|(...)
->  config.get(|"...)  ->  config.get("|user.name")  -> ...

А вот W из той же точки проскакивает весь блок целиком:
const path = config.get("user.name")|;
Вот теперь видно правило: w дробит config.get("user.name") на буквенно-цифровые куски (config, ., get, (, ", user, ., name, ", )), а W обращается с этим слипшимся блоком как с одной WORD и перепрыгивает его за одно нажатие - до ; (он отдельная WORD за )). На таких деталях стоит набить руку самостоятельно - упражнения в конце помогут.

Движения по строке: 0 / ^ / $ / g_

Внутри одной строки есть четыре опорные точки:

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

Клавиша  |  Действие
---------+---------------------------------------------------+------------------------------------+--------------------
0        |  в самый первый столбец строки (нулевая позиция)
^        |  в первый непробельный символ строки
$        |  в конец строки (последний символ)
g_       |  в последний непробельный символ строки
{n}\     |                                                   |  к столбцу номер n (например, 17\  |  - на 17-й столбец)
Разница между 0 и ^ важна для кода с отступами. 0 встаёт буквально на столбец 1 (на пробел отступа), а ^ - на первый значимый символ. В коде вам почти всегда нужен ^. Аналогично g_ полезен, когда в конце строки есть висящие пробелы или вы хотите встать на последний символ, а не за ним. Когда нужна точная позиция по горизонтали, помогает движение {n}|: оно ставит курсор ровно на столбец n (удобно для выровненных колонок и табличных данных).

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

Было:
    return |computeTotal(items);

Нажимаем 0 (на столбец 1, на пробел):
|    return computeTotal(items);

Нажимаем ^ (на первый значимый символ):
    |return computeTotal(items);

Нажимаем $ (в конец):
    return computeTotal(items);|
$ принимает счётчик особым образом: 2$ означает "в конец следующей строки", 3$ - через две строки вниз. Это удобно при работе с короткими строками подряд.

inclusive против exclusive: почему это важно уже сейчас

Эта глава постоянно ссылается на главу 05, где движения станут аргументами операторов (d, c, y). Чтобы предсказывать результат d{motion}, нужно знать одну вещь заранее: движения делятся на exclusive и inclusive.
  • exclusive - целевой символ под курсором не попадает в выделение/удаление. Такие: w, b, 0, ^, ), } и большинство "вперёд по словам".
  • inclusive - целевой символ включается. Такие: e, f, t, $.
На практике это меняет результат на один символ. Например, $ как движение - inclusive, поэтому d$ (то же самое, что D) удаляет вместе с последним символом строки, до самого конца, а не оставляет его. Аналогично df) удалит скобку ), а dt) остановится перед ней (t тоже inclusive, но "целится" на символ перед искомым). А вот dw (exclusive) удалит слово, но не прихватит первый символ следующего.

Пока просто запомните деление; в главе 05 мы вернёмся к нему уже в контексте редактирования. Если хоть раз d{motion} отработал "на символ не так, как ожидалось", причина почти всегда здесь.

Поиск по строке: f / F / t / T / ; / ,

Это одни из самых недооценённых движений, и именно они отличают опытного пользователя. Они позволяют прыгнуть к конкретному символу в текущей строке:

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

Клавиша  |  Действие
---------+---------------------------------------------------------
f{char}  |  вперёд на символ {char} (find)
F{char}  |  назад на символ {char}
t{char}  |  вперёд до символа {char} (остановиться перед ним, till)
T{char}  |  назад до символа {char} (остановиться после него)
;        |  повторить последний f/F/t/T в том же направлении
,        |  повторить в противоположном направлении
Разница f и t тонкая, но принципиальная, особенно когда движение становится аргументом оператора. f) ставит курсор на скобку, t) - на символ перед ней. Для навигации это редко важно, а вот для dt) ("удалить до скобки, не включая её") - критично.

f/t работают только в пределах текущей строки и принимают счётчик: 3fa - к третьей букве a справа.

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

Было:
|let result = items.filter(x => x.active).map(toDto);

Нажимаем f. (к первой точке):
let result = items|.filter(x => x.active).map(toDto);

Нажимаем ; (к следующей точке - повтор f.):
let result = items.filter(x => x.active)|.map(toDto);

Нажимаем , (вернуться к предыдущей - повтор в обратную сторону):
let result = items|.filter(x => x.active).map(toDto);
Освойте f плюс ;/, - это превратит навигацию по строке в стрельбу по точным мишеням, без зажатых l.

Движения по экрану: H / M / L, zz / zt / zb, прокрутка

Когда нужно переместиться в пределах видимой области, помогают три "якоря" экрана:

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

Клавиша  |  Действие
---------+----------------------------------
H        |  к верхней строке экрана (High)
M        |  к средней строке экрана (Middle)
L        |  к нижней строке экрана (Low)
H и L принимают счётчик: 3H - к третьей строке сверху, 3L - к третьей снизу.

Отдельный частый источник путаницы у новичков - визуально перенесённые (wrapped) строки. Когда одна логическая строка не помещается по ширине и переносится на несколько экранных строк, j/k/0/$ работают по логическим строкам и могут "перепрыгнуть" весь видимый перенос разом. Чтобы двигаться по тому, что видно на экране, есть "display-line" движения с префиксом g:

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

Клавиша  |  Действие
---------+-------------------------------
gj       |  вниз на одну экранную строку
gk       |  вверх на одну экранную строку
g0       |  в начало экранной строки
g$       |  в конец экранной строки
Если вы редактируете длинные абзацы прозы или Markdown с включённым wrap, привычка к gj/gk вместо j/k избавляет от ощущения, что курсор "прыгает не туда".

Часто требуется не двигать курсор по экрану, а наоборот - подвинуть экран под курсор, оставив курсор на месте по тексту:

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

Клавиша  |  Действие
---------+-------------------------------------------------------------
zz       |  прокрутить так, чтобы текущая строка стала по центру экрана
zt       |  текущая строка - наверх экрана (top)
zb       |  текущая строка - вниз экрана (bottom)
zz - едва ли не самая используемая команда центрирования: прыгнули куда-то поиском, нажали zz, и нужное место оказалось в центре с контекстом сверху и снизу.

Для прокрутки на бо́льшие расстояния:

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

Клавиша  |  Действие
---------+---------------------------------
Ctrl-d   |  вниз на полэкрана (down)
Ctrl-u   |  вверх на полэкрана (up)
Ctrl-f   |  вперёд на целый экран (forward)
Ctrl-b   |  назад на целый экран (back)
Ctrl-d/Ctrl-u предпочтительнее Ctrl-f/Ctrl-b: полэкрана сохраняет контекст (часть текста остаётся видимой), и глаз не теряет место. Прокрутка на полный экран чаще дезориентирует.

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

Курсор где-то в середине большого файла.

Нажимаем zt - текущая строка уезжает наверх,
ниже открывается следующий блок кода для чтения.

Нажимаем Ctrl-d - спустились на полэкрана,
половина старого контекста ещё видна сверху.
Движения по файлу: gg / G / {n}G, % и предложения/абзацы

Перемещение по всему файлу:

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

Клавиша  |  Действие
---------+---------------------------------------------------
gg       |  в начало файла (первая строка)
G        |  в конец файла (последняя строка)
{n}G     |  к строке номер n (например, 42G - на 42-ю строку)
{n}gg    |  то же, что {n}G
G и gg ставят курсор на первый непробельный символ целевой строки. Конструкция {n}G незаменима, когда компилятор или линтер сообщил "ошибка в строке 217": 217G - и вы там.

Отдельная звезда - команда %:

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

Клавиша  |  Действие
---------+-------------------------------------
%        |  прыжок к парной скобке - (), [], {}
Когда курсор стоит на самой скобке, % перебросит на парную: с открывающей - на закрывающую, и наоборот. Это спасение при чтении вложенного кода: встали на { начала блока, нажали % - и сразу видите, где блок заканчивается.

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

Было (курсор явно на открывающей скобке):
function process|(items) {
  // ... много строк ...
}

Нажимаем % - прыжок на парную закрывающую:
function process(items|) {

Перешли на { и нажимаем %:
function process(items) {
  // ...
}|   <- курсор на закрывающей фигурной скобке
Тонкость: если курсор стоит не на скобке, % не "никуда не прыгает", а сначала ищет ближайшую скобку справа в текущей строке и затем переходит к её паре. Например, из function process(|items) { (курсор на items, внутри пары) % найдёт справа ) и прыгнет к её паре - открывающей ( перед items. То есть курсор окажется на (, а не на ). Учитывайте это: чтобы результат был предсказуем, ставьте курсор прямо на нужную скобку.

Для навигации по структуре прозы и кода есть движения по предложениям и абзацам:

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

Клавиша  |  Действие
---------+--------------------------------------------------
)        |  к началу следующего предложения
(        |  к началу предыдущего предложения
}        |  к началу следующего абзаца (или к пустой строке)
{        |  к началу предыдущего абзаца
Предложение в Vim заканчивается на ., ! или ?, за которыми следует пробел (или конец строки). Здесь есть тонкость: по умолчанию Vim считает концом предложения как одиночный, так и двойной пробел после точки, но это поведение регулируется опцией 'cpoptions' (флаг J требует именно двух пробелов). В коде, где после точек редко стоят пробелы по правилам прозы, sentence-движения (/) ведут себя не всегда интуитивно - для кода надёжнее опираться на {/} и поиск.

Абзац - блок текста, отделённый пустыми строками. В коде { и } особенно удобны: они прыгают между логическими блоками (функциями, методами), разделёнными пустыми строками, и при этом гораздо "крупнее", чем построчное движение. Зажатой j тут не место - используйте }.

Ещё одна важная для главы 05 деталь: }/{, а также gg/G - это linewise-движения (они оперируют целыми строками, а не диапазоном символов). Поэтому d} удалит абзац построчно (целыми строками), а dG - от текущей строки до конца файла целыми строками, а не "от позиции курсора". Это отличает их от character-wise движений вроде w или f и прямо влияет на то, что именно вырежет оператор.
Не путайте movement-команды {/}/(/) с текстовыми объектами i{/a( и т. п. - это разные вещи. Текстовые объекты ("внутри скобок", "вокруг абзаца") разбираются подробно в главе 06.
Прыжки по поиску

Поиск - это тоже движение, и одно из самых мощных. Беглый обзор (полноценно - в главе 10):

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

Клавиша    |  Действие
-----------+------------------------------------------------
/{шаблон}  |  искать {шаблон} вперёд
?{шаблон}  |  искать назад
n          |  к следующему совпадению (в направлении поиска)
N          |  к предыдущему совпадению
*          |  искать слово под курсором вперёд
#          |  искать слово под курсором назад
Идея в том, что вместо "дойти до строки 80 и там до слова config" вы пишете /config<Enter> и оказываетесь на первом совпадении, а n ведёт к следующим. Это часто самый быстрый способ преодолеть большое расстояние: вы прыгаете прямо к содержимому, а не к координатам.

Поскольку поиск - это движение, он тоже комбинируется с операторами: d/end<Enter> удалит всё от курсора до слова end. Но об операторах - в главе 05.

После "дальних" прыжков (gg, G, /, %, переход по метке) Vim запоминает позицию в jumplist. Вернуться по истории прыжков можно через Ctrl-o (назад) и Ctrl-i (вперёд). Важный практический нюанс: Ctrl-i - это та же физическая клавиша, что и <Tab> (на уровне терминала они шлют один и тот же код), поэтому во многих терминалах их нельзя замапить независимо друг от друга. Это отдельная большая тема - навигации по истории перемещений посвящена глава 09.

Тесно связаны с jumplist и метки позиций. Vim сам ведёт несколько автоматических меток, к которым удобно возвращаться: ` (две обратные кавычки) - к позиции до последнего прыжка, '' (две одинарные кавычки) - к строке до последнего прыжка, а `. - к месту последней правки. Эти возвраты часто экономят время: например, прыгнули поиском "посмотреть объявление функции", а ` мгновенно вернул туда, где вы редактировали. Подробно метки разбираются в главе 09.

Лучшие практики 2026

Думайте движениями, а не нажатиями. Прежде чем нажать клавишу перемещения, спросите себя: "куда мне нужно - к слову, к символу, к строке, к структуре?" - и выберите соответствующее движение. Привычка зажимать j/k/h/l или стрелки - антипаттерн номер один. Почти всегда есть более выразительная альтернатива: счётчик (8j), абзац (}), полэкрана (Ctrl-d), точечный прыжок (f/t), поиск (/).

Включите относительную нумерацию строк. Опции number и relativenumber вместе дают "гибридный" режим: текущая строка показывает абсолютный номер, остальные - расстояние до неё. Это превращает счётные прыжки в рефлекс: видите слева 6, нажимаете 6j - и вы там. В Neovim это настраивается в init.lua так (конфигурация подробно разбирается в главе 20):

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

vim.opt.number = true
vim.opt.relativenumber = true
В классическом Vim - в ~/.vimrc:

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

set number
set relativenumber
Отключите стрелки на время обучения, чтобы выработать привычку. Дисциплина силой воли работает плохо - лучше убрать "костыль". Распространённый приём - переназначить стрелки на "ничего":

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

nnoremap <Up>    <Nop>
nnoremap <Down>  <Nop>
nnoremap <Left>  <Nop>
nnoremap <Right> <Nop>
В экосистеме Neovim 2025-2026 популярен плагин hardtime.nvim: он отслеживает спам одной клавиши перемещения, предупреждает о неэффективных действиях и подталкивает к counts и точным motion. Это самый надёжный способ сформировать правильные привычки, а не полагаться на самоконтроль. (Маппинги и плагины - главы 21 и 23.)

Центрируйте экран после дальних прыжков. Возьмите за рефлекс связку "прыжок + zz": после G, /, * или перехода по номеру строки нажмите zz, чтобы цель оказалась в центре с контекстом. Многие идут дальше и делают n и N автоцентрирующими через маппинги nnoremap n nzz и nnoremap N Nzz.

Соберите "лестницу" движений по дальности. Полезная ментальная модель - выбирать движение под расстояние: символ -> h/l, слово -> w/b/e, символ в строке -> f/t, строка целиком -> 0/^/$, абзац/блок -> {/}, полэкрана -> Ctrl-d/Ctrl-u, файл -> gg/G/{n}G, произвольное содержимое -> /. Чем больше расстояние, тем "крупнее" движение.

Частые ошибки
  • Зажимать j/k вместо счётчика или абзаца. Если вы держите j, чтобы спуститься на десяток строк, остановитесь и подумайте: 10j, } или Ctrl-d сделают это точнее и без потери позиции глаза.
  • Не различать 0 и ^. В коде с отступами 0 встаёт на пробел, а вам почти всегда нужен первый значимый символ - ^. Привыкайте к ^.
  • Путать f и t. f{char} встаёт на символ, t{char} - перед ним. Для простой навигации разница невелика, но как только движение станет аргументом оператора (dt) против df)), ошибка изменит результат на один символ.
  • Не пользоваться ; и ,. Многие нажимают f. снова и снова с нуля, забыв, что повтор поиска по строке - это ; (и , в обратную сторону). Это удваивает число нажатий на пустом месте.
  • Игнорировать % при чтении вложенного кода. Считать парные скобки глазами - медленно и ошибкоопасно. % делает это мгновенно.
  • Думать, что hjkl - основной способ перемещения. Это аварийный минимум. Если ваша навигация на 90% состоит из hjkl, вы ещё не "думаете движениями".
  • Считать {/} текстовыми объектами. Как movement они прыгают по абзацам; текстовые объекты (i{, ap) - отдельная грамматическая конструкция (глава 06).
Упражнения
  1. Домашний ряд. Откройте любой файл и поставьте себе правило на 20 минут: перемещаться только клавишами нормального режима, без стрелок и мыши. Каждый раз, когда рука потянется к стрелке, останавливайтесь и ищите подходящее движение.
  2. word против WORD. Возьмите строку вида obj.method(arg1, arg2).chain["key"]. Пройдите её слева направо сначала клавишей w (считая остановки), затем W. Сравните, на сколько меньше нажатий потребовала W, и сформулируйте, когда какое движение уместнее.
  3. Стрельба по символам. В строке с несколькими запятыми и точками потренируйте f, плюс ; для перехода к каждой следующей запятой и , для возврата. Затем повторите с t и сравните, где встаёт курсор.
  4. Парные скобки. Найдите в коде функцию с вложенными блоками. Встаньте на открывающую ( или { и нажмите %, чтобы прыгнуть к парной. Пройдитесь так по нескольким уровням вложенности.
  5. Лестница дальности. Откройте файл на 200+ строк. Доберитесь до строки 150 четырьмя разными способами: 150G; повторными Ctrl-d; через / по уникальному слову на этой строке; через гибридную нумерацию и счётный прыжок {n}j. Отметьте, какой способ оказался быстрее для этого конкретного случая.
  6. Рефлекс центрирования. Включите relativenumber. Несколько раз прыгните по файлу через G, gg и /, каждый раз добавляя zz. Прочувствуйте, насколько комфортнее читать, когда цель в центре экрана.
Главное из главы
  • hjkl - базовое посимвольное движение и причина держать руки на домашнем ряду; стрелки уводят руку с позиции и не комбинируются со счётчиками/операторами. Но hjkl - аварийный минимум, а не основной инструмент.
  • По словам: w/b/e/ge (с учётом пунктуации) и W/B/E (WORD - только по пробелам). Строчные "мельче", заглавные "крупнее".
  • По строке: 0 (столбец 1), ^ (первый значимый), $ (конец), g_ (последний значимый), {n}| (к столбцу N). Для перенесённых строк - display-line движения gj/gk/g0/g$.
  • Движения делятся на inclusive (e, f, t, $ - включают целевой символ) и exclusive (w, b, 0, ^ - не включают), а }/{/gg/G - linewise. Это критично для результата d{motion} в главе 05.
  • Точечные прыжки по строке: f/F/t/T плюс ;/, для повтора - мощнейший и недооценённый инструмент.
  • По экрану: H/M/L - якоря экрана; zz/zt/zb - позиционирование экрана под курсор; Ctrl-d/Ctrl-u (полэкрана, предпочтительно) и Ctrl-f/Ctrl-b (экран).
  • По файлу: gg/G/{n}G; % - к парной скобке; (/) и {/} - по предложениям и абзацам.
  • Поиск (/, ?, n, N, *, #) - это тоже движение, часто самый быстрый способ преодолеть расстояние (подробно - глава 10).
  • Возврат по истории: Ctrl-o/Ctrl-i (jumplist; Ctrl-i == <Tab>), автоматические метки `/'' (предыдущая позиция) и `. (последняя правка) - подробно в главе 09.
  • Практики 2026: думать движениями под расстояние, включить гибридный number+relativenumber, отключить стрелки и/или поставить hardtime.nvim, центрировать экран через zz после дальних прыжков.
  • Всё, что вы выучили здесь, в главе 05 станет аргументами для операторов - навигация и есть фундамент грамматики Vim.
👍5 ❤️3 🔥 😄 🤔1
✔ Лучший ответ сформирован автоматически — roman88
затык был с длинными строками в markdown - j прыгала через весь перенос разом и я не понимал куда курсор делся. оказалось это logical line, а по видимым строкам надо gj/gk. ну и про W vs w долго не видел разницы пока не попал на config.get('user.name') без пробелов, вот там W за раз весь блок проскочил а w дробил на куски
Перейти к ответу →
Аватара пользователя
mslesa
Сообщения: 1
Зарегистрирован: 28 май 2026, 20:07

Re: Перемещение по тексту: движения как основа эффективности

Сообщение mslesa »

спасибо, наконец дошло почему f и t разные. для навигации казалось одно и то же, а тут на dt) и df) сразу понятно зачем оно надо
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
kun_vovan
Сообщения: 1
Зарегистрирован: 11 май 2026, 17:56

Re: Перемещение по тексту: движения как основа эффективности

Сообщение kun_vovan »

а у меня % сначала вообще не туда прыгало, бесился полчаса. оказалось курсор стоял не на скобке, а внутри на тексте - он справа искал ближайшую и прыгал к её паре, в итоге попадал на открывающую а не на закрывающую. поставил прямо на скобку - всё ровно
👍2 ❤️1 🔥 😄 🤔
Аватара пользователя
envoy_lover
Сообщения: 1
Зарегистрирован: 05 июн 2026, 07:33

Re: Перемещение по тексту: движения как основа эффективности

Сообщение envoy_lover »

привычка зажимать j/k или стрелки - антипаттерн номер один. вот это прям про меня было, до сих пор спускаюсь зажатой j на пол файла. поставил relativenumber и hardtime.nvim, второй день ругается на меня но реально начал считать строки и жать } по абзацам
👍1 ❤️ 🔥 😄 🤔1
Аватара пользователя
miami
Сообщения: 1
Зарегистрирован: 03 июн 2026, 10:58

Re: Перемещение по тексту: движения как основа эффективности

Сообщение miami »

мой лайфхак для тех кто прыгает поиском - сделайте nnoremap n nzz и N Nzz, чтобы после n экран сам центрировался. плюс связка / потом zz вошла в рефлекс, читать стало в разы удобнее когда цель в середине а не в самом низу экрана
👍1 ❤️ 🔥2 😄 🤔1
Аватара пользователя
roman88
Сообщения: 1
Зарегистрирован: 08 июн 2026, 14:53

Re: Перемещение по тексту: движения как основа эффективности

Сообщение roman88 »

✔ Лучший ответ — сформирован автоматически
затык был с длинными строками в markdown - j прыгала через весь перенос разом и я не понимал куда курсор делся. оказалось это logical line, а по видимым строкам надо gj/gk. ну и про W vs w долго не видел разницы пока не попал на config.get('user.name') без пробелов, вот там W за раз весь блок проскочил а w дробил на куски
👍 ❤️ 🔥 😄 🤔1
Ответить
← Предыдущая глава
Установка и выживание: первый запуск, режимы, как выйти
Следующая глава →
Базовое редактирование: вставка, удаление, копирование

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

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

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

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

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