Vim команды: режимы, перемещение, правка и выход

Разработчик работает в терминальном текстовом редакторе на ноутбуке Программное обеспечение

Vim открывается в обычном режиме: клавиши там работают как команды, буквы в файл не печатаются. Чтобы набрать текст, нажмите i; чтобы сохранить файл и выйти, нажмите Esc, наберите :wq и Enter.

Для начала из основных команд хватит шести: Esc, i, :w, :q!, u и /. Остальные команды vim из этой шпаргалки добавляйте по одной, когда надоест делать что-то руками. Примеры прогнаны в vim 9.2.

Разработчик работает в терминальном текстовом редакторе на ноутбуке

Режимы работы vim

Режим Как войти Что происходит
Обычный (Normal) при запуске vim, Esc из других клавиши выполняют команды: перемещение курсора, удаление, копирование
Вставки (Insert) i, a, o и другие набранный текст попадает в файл, внизу экрана -- INSERT --, при русской локали -- РЕЖИМ ВСТАВКИ --
Визуальный (Visual) v, V, Ctrl+V движение курсора расширяет выделение текста, следующая команда работает с ним
Командной строки :, /, ? внизу экрана открывается строка для ex-команд и поиска

В справке vim обычный режим назван ещё и command mode, режимом команд. В части русских шпаргалок «командным режимом» зовут строку после двоеточия, а вставку называют режимом редактирования. Это разные режимы: dd набирается в обычном, :w в режиме командной строки. Если не помните, в каком режиме находитесь, нажмите Esc или Ctrl+[: из вставки и выделения они вернут в обычный.

Студент за ноутбуком изучает терминальный редактор

Как сохранить и выйти из vim

Команды с двоеточием набираются в обычном режиме, Enter выполняет команду.

Команда Что делает
:w сохранить файл
:w имя записать в другой файл, текущий остаётся несохранённым
:q закрыть окно; с несохранёнными изменениями не выйдет
:q! или ZQ выйти без сохранения изменений
:wq записать файл и выйти
:x или ZZ записать, только если были изменения, и выйти
:qa выйти из всех файлов, если ни один не изменён
:qa! выйти из всех файлов, изменения потеряны
:wqa записать все изменённые файлы и выйти
:e! вернуть файл к последней сохранённой версии

Если в изменённом файле набрать :q, vim 9.2 не выйдет и напишет:

E37: No write since last change (add ! to override)

:q! выходит без сохранения. :w! записывает файл, у которого стоит readonly (без ! будет E45: 'readonly' option is set); учтите, что при этом у файла могут смениться права и владелец. В новом буфере без имени :wq отвечает E32: No file name: имя дайте прямо в команде, :wq notes.txt.

:wq записывает файл всегда, :x и ZZ только при изменениях. Разницу видно по времени изменения нетронутого файла:

printf 'line one\n' > f.txt; touch -d '2020-01-01' f.txt
vim -Nu NONE -es -c 'x' f.txt; stat -c '%y' f.txt
# 2020-01-01 00:00:00.000000000 +0700
vim -Nu NONE -es -c 'wq' f.txt; stat -c '%y' f.txt
# 2026-10-10 18:48:21.640094800 +0700

Мы советуем привыкать к :x или ZZ: если правок не было, файл и время его изменения остаются прежними. Но если файл удалили с диска, пока он был открыт, :x без правок его не запишет, а :wq запишет заново.

Читайте также:  PowerShell скрипты: как написать, сохранить и запустить .ps1

Vim открывается и после git commit без -m: если редактор не задан в GIT_EDITOR, core.editor, VISUAL или EDITOR, git обычно запускает vi. Нажмите i, напишите сообщение коммита в первой строке, затем Esc и :wq. Если при новом коммите выйти через :q!, git его отменит:

Aborting commit due to empty commit message.

Рука на клавиатуре нажимает клавишу в верхнем левом углу

Перемещение курсора

Команда Куда перемещает курсор
h j k l на символ влево, строку вниз, строку вверх, символ вправо
w / b начало следующего слова / начало слова назад
e конец слова
0 / ^ / $ начало строки / первый непробельный символ / конец строки
gg / G первая строка / последняя строка файла
5G или :5 переход на строку номер 5
Ctrl+F / Ctrl+B экран вниз / экран вверх
Ctrl+D / Ctrl+U полэкрана вниз / вверх

Стрелки тоже перемещают курсор, но hjkl всегда под пальцами. Число перед командой повторяет её: 4j переместит курсор на 4 строки вниз, 3w на 3 слова вперёд. В строке for x in items: команда 0 ставит курсор на первый пробел, ^ на букву f. В коде на Python ^ удобнее: курсор встаёт после отступа.

Вставка текста

  • i вставка перед курсором, a после курсора;
  • I вставка в начало строки (после отступа), A в конец строки;
  • o новая строка ниже, O новая строка выше.

После набора возвращайтесь в обычный режим через Esc, иначе следующие команды vim попадут в текст буквами.

Удаление, копирование и вставка

Команда Что делает
x удалить символ под курсором
dd / 3dd удалить строку / три строки
dw удалить до начала следующего слова
D удалить остаток строки, начиная с курсора
cw заменить слово: удалить до конца слова и перейти в режим вставки
ciw заменить слово под курсором целиком
r заменить один символ (rD поставит D на место символа под курсором)
yy скопировать строку
p / P вставить содержимое после курсора / перед ним
J присоединить следующую строку к текущей
>> / << сдвинуть строку вправо / влево на shiftwidth
. повторить последнее изменение

Удалённый текст vim кладёт в тот же регистр, что и скопированный, поэтому dd, а затем p в другом месте работают как «вырезать и вставить». Точка повторяет правку на новом месте: A;, Esc, j, . добавит точку с запятой в конец текущей строки и следующей. Команды двоеточия точка не повторяет.

Правка кода в терминале, курсор-блок на строке

Регистры: почему p вставил не то

Возьмём файл:

user = get_user()
print(user)
save(user, user_id)
log("user ok")

На первой строке yy, затем 3G и dd, затем 1G и p. Вставится удалённая строка save(user, user_id): удаление перезаписало безымянный регистр. Скопированное лежит в регистре 0, его вставляет "0p. Содержимое регистров показывает :reg, а :reg "01 выводит только три нужных:

Type Name Content
  l  ""   save(user, user_id)^J
  l  "0   user = get_user()^J
  l  "1   save(user, user_id)^J

Свой регистр задают буквой: "ayy копирует строку в регистр a, затем j и "Ayy дописывают к нему следующую строку, "ap вставляет обе. Системный буфер обмена доступен через "+y и "+p, если vim собран с поддержкой clipboard: проверьте vim --version | grep clipboard, нужен +clipboard. На Linux в терминале нужен ещё +xterm_clipboard, без него vim использует обычный регистр.

Читайте также:  Jupyter Notebook: установка, запуск и работа с ячейками

Монитор с открытым кодом, строки в редакторе подсвечены выделением

Отмена и повтор

u отменяет последнее изменение, 5u пять изменений, Ctrl+R возвращает отменённое. Если второе u возвращает правку, которую отменило первое, vim работает в режиме совместимости с vi. Так бывает при запуске vim -u NONE: он не читает ни .vimrc, ни defaults.vim. Обычный запуск выключает совместимость сам: её снимает и найденный .vimrc, и defaults.vim, который vim загружает, когда своего .vimrc нет.

Поиск и замена

Команда Что делает
/текст поиск вперёд
?текст поиск назад
n / N следующее совпадение / предыдущее
* / # искать слово под курсором вперёд / назад
/текст\c поиск без учёта регистра букв
:noh отключить подсветку совпадений до следующего поиска

Подсветка по умолчанию выключена, включает её :set hlsearch. В нашем файле /user с начала первой строки остановится внутри get_user. Команда * на слове user ищет его целиком и сразу переходит ко второй строке. Дойдя до конца файла, поиск продолжается с начала.

Код на мониторе, найденные слова подсвечены

Замена: :s/old/new/ меняет первое совпадение в текущей строке, флаг g все совпадения в строке, % распространяет команду на весь файл, c спрашивает подтверждение (y заменить, n пропустить, a заменить все оставшиеся, Esc прервать). :2,3s/old/new/g работает только на строках 2-3.

Замена без границ слова ломает код:

:%s/user/account/g
account = get_account()
print(account)
save(account, account_id)
log("account ok")

Переименовалась и функция, и user_id. С \< и \> vim заменит только отдельное слово:

:%s/\<user\>/account/g
account = get_user()
print(account)
save(account, user_id)
log("account ok")

Слово user внутри строки "user ok" тоже заменилось. На чужом коде лучше :%s/\<user\>/account/gc: vim спросит про каждое место.

Визуальный режим и выделение текста

v выделяет по символам, V строками, Ctrl+V прямоугольным блоком. Выделили, затем команда: d удалить, y скопировать, > сдвинуть строки вправо.

Закомментировать четыре строки Python: 1G, Ctrl+V, 3j, I#, Esc. Курсор останется на первой строке, а решётка с пробелом появится в начале каждой строки блока. Если в Windows Ctrl+V вставляет текст из буфера обмена, блочное выделение включает Ctrl+Q, но в терминалах, где Ctrl+Q занят управлением потоком, оно не сработает.

Макросы

qa начинает запись макроса в регистр a, q останавливает, @a выполняет, @@ повторяет последний. Пример: qa, A # checked, Esc, j, q дописывает комментарий в конец строки и переходит на следующую; 2@a повторит это ещё на двух строках.

Два монитора на рабочем столе, на одном терминал с размытым кодом

Вкладки, окна и несколько файлов

Команда Что делает
:e имя открыть другой файл в текущем окне
:tabnew имя открыть файл в новой вкладке
gt / gT следующая вкладка / предыдущая
:tabclose закрыть текущую вкладку
:sp имя / :vsp имя разделить окно по горизонтали / по вертикали
Ctrl+W w перейти в соседнее окно
:only оставить одно текущее окно
:ls список буферов, то есть открытых файлов
:bn / :bp перейти в следующий буфер / предыдущий
Читайте также:  Что такое Docker

Метки и сворачивание

ma ставит метку a в позиции курсора. 'a возвращает на строку с меткой, к первому непробельному символу, `a в точную позицию.

Сворачивание при настройке по умолчанию ручное: zfj сворачивает текущую строку и следующую, zo разворачивает, zc сворачивает снова, za переключает.

Полезные команды для работы с кодом

  • :set number включает номера строк, :set nu! переключает обратно. Постоянные настройки пишут в ~/.vimrc, в Git Bash тоже. Vim, установленный в Windows отдельно, читает $HOME/_vimrc.
  • :!python3 % запускает текущий файл: % vim подставляет как имя файла. Если в системе есть только команда python, пишите :!python %. Сохраните файл через :w до запуска. Так удобно гонять простые программы на Python прямо из редактора.
  • Ctrl+Z в обычном режиме во многих Unix-системах приостанавливает vim и возвращает в терминал, команда fg выводит редактор обратно на передний план. Приостановленный процесс в списке процессов Linux виден со статусом T.
  • :set keymap=russian-jcukenwin: раскладка системы остаётся английской, в режиме вставки vim сам печатает кириллицу, а команды обычного режима остаются латинскими. Ctrl+^ в режиме вставки переключает язык ввода.
  • vimtutor ru открывает встроенный учебник на русском, в нём две главы (вторая: vimtutor -c 2 ru). :help команда открывает справку, например :help ZZ.

Для Python с отладчиком удобнее VS Code, а vim без плагинов хорош для конфигов на сервере и сообщений коммитов.

Ноутбук с терминалом в серверной, рядом стойки с оборудованием

vi, vim и Neovim

В vi нет визуального режима и многоуровневой отмены, в vim они есть. Команда vi может запускать vim: в Git Bash vi это скрипт exec vim "$@". В Neovim команды редактора почти те же, что в vim. Отличаются настройки: конфиг лежит в init.vim, подсветка всех найденных совпадений включена сразу.

Частые вопросы по командам vim

Как выйти из vim без сохранения?

Нажмите Esc, наберите :q! и Enter. То же делает ZQ.

Что делать с сообщением ATTENTION при открытии файла?

Vim нашёл swap-файл: файл, возможно, уже правят в другой программе, или прошлый сеанс vim аварийно завершился. O откроет файл только для чтения, R восстановит несохранённые изменения из swap-файла, Q выйдет, D удалит swap-файл, когда он точно не нужен. E (редактировать всё равно) опасен: если файл открыт ещё в одном vim, получатся две версии.

Почему команды не работают и вместо них печатаются буквы?

Вы в режиме вставки: нажмите Esc. Если команды не срабатывают в обычном режиме, проверьте раскладку: vim понимает dd, но не вв.

Оцените статью
bestprogrammer.ru
Добавить комментарий