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

- Режимы работы vim
- Как сохранить и выйти из vim
- Перемещение курсора
- Вставка текста
- Удаление, копирование и вставка
- Регистры: почему p вставил не то
- Отмена и повтор
- Поиск и замена
- Визуальный режим и выделение текста
- Макросы
- Вкладки, окна и несколько файлов
- Метки и сворачивание
- Полезные команды для работы с кодом
- vi, vim и Neovim
- Частые вопросы по командам vim
- Как выйти из vim без сохранения?
- Что делать с сообщением ATTENTION при открытии файла?
- Почему команды не работают и вместо них печатаются буквы?
Режимы работы 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 запишет заново.
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 использует обычный регистр.

Отмена и повтор
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 | перейти в следующий буфер / предыдущий |
Метки и сворачивание
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, но не вв.








