Режим Vi
Введение

Режим VI в Kate — это проект по внедрению модального редактирования в стиле Vim в текстовый редактор Kate и, как следствие, в другие приложения KDE, использующие тот же компонент редактора. Проект стартовал в рамках Google Summer of Code в 2008 году, когда была написана вся базовая функциональность. С тех пор я продолжаю поддерживать и развивать этот код, и количество функций Vim, которые ещё не реализованы, постепенно сокращается. Большинство пользователей Vim уже смогут продуктивно работать в режиме VI Kate. Список отсутствующих возможностей приведён внизу страницы.
На этой странице представлен обновлённый обзор этой работы.
Настройка → Настроить Kate… → Редактирование → Режим ввода Vi.
Его также можно переключить с помощью пункта «Режим ввода Vi» в меню «Правка». (Комбинация клавиш по умолчанию — Meta+Ctrl+V, где Meta обычно является клавишей Windows).
Цели
Цель режима VI — не полная замена Vim и поддержка всех его возможностей. Его задача — сделать «вимовский» способ редактирования текста и привычки, усвоенные в Vim, доступными для приложений, использующих текстовый редактор Kate в качестве встроенного. К таким приложениям относятся
- Текстовый редактор Kate
- KWrite — простой текстовый редактор KDE
- KDevelop — расширенная среда разработки для многих языков программирования
- Kile — редактор LaTeX
Режим VI предназначен для удобной интеграции с приложениями и в разумных пределах отклоняется от поведения Vim. Например, команда :w в режиме VI Kate откроет диалог сохранения.
Несовместимость с Vim
В режиме VI редактора Kate есть лишь несколько функций, несовместимых с Vim (не считая отсутствующих). Они перечислены ниже вместе с соответствующими причинами.
- Kate:
UиCtrl+R— повтор
Vim:Ctrl+R— обычный повтор,Uиспользуется для отмены всех последних изменений в строке
В режиме VI KateUдействует как повтор, поскольку комбинацияCtrl+Rпо умолчанию занята функцией замены Kate (поиск и замена). По умолчанию режим VI не переопределяет комбинации клавиш Kate (это можно настроить в «Настройка → Настроить Kate… → Редактирование → Режим ввода Vi»), поэтому действие повтора должно быть доступно и как «обычное» нажатие клавиши. Кроме того, поведение командыUв Vim плохо соотносится с внутренней системой отмены Kate, так что её поддержка была бы нетривиальной. - Kate:
:printоткрывает диалог «Печать»
Vim::printвыводит строки заданного диапазона, как в его предке ed. Команды вроде:printдоступны не только в режиме VI, но и для пользователей «обычной» Kate. Поэтому было решено, что команда:printбудет открывать диалог печати — следуя принципу наименьшего удивления, а не копируя поведение Vim. - Kate:
Yкопирует до конца строки.
Vim:Yкопирует всю строку, как иyy. Поведение VI для командыYфактически является ошибкой; для команд изменения и удаленияcc/ddвыполняют действие над текущей строкой, аC/Dработают от позиции курсора до конца строки. Однако иyy, иYкопируют текущую строку. В режиме VI Kate командаYкопирует до конца строки. Это описано как «более логичное» в документации Vim. - Kate:
:mapизменяет выбранные строки документа с помощью заданного выражения JavaScript.
Vim::mapдобавляет заданное сопоставление в обычный и визуальный режимы. Команда «map» уже была зарезервирована Kate; начиная с версии 4.12, для её замены можно использовать комбинацию:nmapи:vmap.
Поддерживаемые команды
Поддерживаемые команды обычного/визуального режимов
| Клавиша | Описание |
|---|---|
| a | Включить режим вставки и добавить |
| A | Включить режим вставки и добавить в конец строки |
| i | Включить режим вставки |
| I | Вставить перед первым непробельным символом в строке |
| v | Включить визуальный режим |
| V | Включить режим визуальных строк |
| <c-v> | Включить режим визуального блока |
| gv | Восстановить последнее визуальное выделение |
| o | Вставить новую строку ниже |
| O | Вставить новую строку выше |
| J | Объединить строки |
| c | Изменить |
| C | Изменить до конца строки |
| cc | Изменить строку |
| s | Заменить символ |
| S | Заменить строку |
| dd | Удалить строку |
| d | Удалить |
| D | Удалить до конца строки |
| x | Удалить символ |
| X | Удалить предыдущий символ |
| gu | Перевести в нижний регистр |
| guu | Перевести строку в нижний регистр |
| gU | Перевести в верхний регистр |
| gUU | Перевести строку в верхний регистр |
| y | Копировать |
| yy | Копировать строку |
| Y | Копировать до конца строки |
| p | Вставить |
| P | Вставить перед курсором |
| r. | Заменить символ |
| R | Перейти в режим замены |
| : | Переключиться в командную строку |
| / | Поиск |
| u | Отменить |
| <c-r> | Повторить |
| U | Повторить |
| m. | Установить метку |
| >> | Увеличить отступ строки |
| << | Уменьшить отступ строки |
| > | Увеличить отступ строк |
| < | Уменьшить отступ строк |
| <c-f> | Прокрутить на страницу вниз |
| <pagedown> | Прокрутить на страницу вниз |
| <c-b> | Прокрутить на страницу вверх |
| <pageup> | Прокрутить на страницу вверх |
| <c-u> | Прокрутить на половину страницы вверх |
| <c-d> | Прокрутить на половину страницы вниз |
| zz | Центрировать вид по курсору |
| ga | Вывести код символа |
| . | Повторить последнее изменение |
| == | Выровнять строку |
| = | Выровнять строки |
| ~ | Сменить регистр |
| <c-a> | Прибавить к числу |
| <c-x> | Вычесть из числа |
| <c-o> | Перейти к предыдущей позиции |
| <c-i> | Перейти к следующей позиции |
| <c-w>h | Перейти в окно слева |
| <c-w><c-h> | Перейти в окно слева |
| <c-w><left> | Перейти в окно слева |
| <c-w>j | Перейти в окно снизу |
| <c-w><c-j> | Перейти в окно снизу |
| <c-w><down> | Перейти в окно снизу |
| <c-w>k | Перейти в окно сверху |
| <c-w><c-k> | Перейти в окно сверху |
| <c-w><up> | Перейти в окно сверху |
| <c-w>l | Перейти в окно справа |
| <c-w><c-l> | Перейти в окно справа |
| <c-w><right> | Перейти в окно справа |
| <c-w>w | Перейти в следующее окно |
| <c-w><c-w> | Перейти в следующее окно |
| <c-w>s | Разделить по горизонтали |
| <c-w>S | Разделить по горизонтали |
| <c-w><c-s> | Разделить по горизонтали |
| <c-w>v | Разделить по вертикали |
| <c-w><c-v> | Разделить по вертикали |
| gt | Перейти к следующей вкладке |
| gT | Перейти к предыдущей вкладке |
| gqq | Форматировать строку |
| gq | Форматировать строки |
| q. / q | Начать/завершить запись макроса в именованный регистр макросов. |
Поддерживаемые перемещения
| Клавиша | Описание |
|---|---|
| h | Влево |
| <left> | Влево |
| <backspace> | Влево |
| j | Вниз |
| <down> | Вниз |
| <enter> | Вниз, к первому непробельному символу |
| k | Вверх |
| <up> | Вверх |
| - | Вверх, к первому непробельному символу |
| l | Вправо |
| <right> | Вправо |
| <space> | Вправо |
| $ | В конец строки |
| <end> | В конец строки |
| В столбец 0 | |
| <home> | В столбец 0 |
| ^ | В начало строки |
| f. | Найти символ |
| F. | Найти символ в обратном направлении |
| t. | До символа |
| T. | До символа в обратном направлении |
| ; | Повторить последнюю команду t. или f. |
| , | Повторить последнюю команду t. или f. |
| n | Найти далее |
| N | Найти предыдущее |
| gg | К первой строке |
| G | К последней строке |
| w | На слово вперёд |
| W | На СЛОВО вперёд |
| b | На слово назад |
| B | На СЛОВО назад |
| e | В конец слова |
| E | В конец СЛОВА |
| ge | В конец предыдущего слова |
| gE | В конец предыдущего СЛОВА |
| % | К парному элементу |
| `[a-zA-Z><] | К метке |
| '[a-zA-Z><] | К отмеченной строке |
| [[ | К началу предыдущего блока в фигурных скобках |
| ]] | К началу следующего блока в фигурных скобках |
| [] | К концу предыдущего блока в фигурных скобках |
| ][ | К концу следующего блока в фигурных скобках |
| * | К следующему вхождению слова под курсором |
| # | К предыдущему вхождению слова под курсором |
| H | К первой строке окна |
| M | К средней строке окна |
| L | К последней строке окна |
| gj | К следующей экранной строке |
| gk | К предыдущей экранной строке |
Поддерживаемые текстовые объекты
| Клавиша | Описание |
|---|---|
| iw | Внутренняя часть слова |
| aw | Слово |
| iW | Внутренняя часть СЛОВА |
| aW | СЛОВО |
| i" | Внутри двойных кавычек |
| a" | Двойные кавычки |
| i’ | Внутри одинарных кавычек |
| a’ | Одинарные кавычки |
| i` | Внутри обратных кавычек |
| a` | Обратные кавычки |
| ib | Внутри круглых скобок |
| i) | Внутри круглых скобок |
| i( | Внутри круглых скобок |
| ab | Круглые скобки |
| a) | Круглые скобки |
| a( | Круглые скобки |
| iB | Внутри фигурных скобок |
| i} | Внутри фигурных скобок |
| i{ | Внутри фигурных скобок |
| aB | Фигурные скобки |
| a} | Фигурные скобки |
| a{ | Фигурные скобки |
| i< | Внутри угловых скобок |
| i> | Внутри угловых скобок |
| a< | Угловые скобки |
| a> | Угловые скобки |
| i[ | Внутри квадратных скобок |
| i] | Внутри квадратных скобок |
| a[ | Квадратные скобки |
| a] | Квадратные скобки |
| i, | Между запятыми |
| a, | Между запятыми вместе с запятой |
Поддерживаемые команды режима вставки
| Клавиша | Описание |
|---|---|
| <c-d> | Уменьшить отступ |
| <c-t> | Увеличить отступ |
| <c-e> | Вставить символ из строки ниже |
| <c-y> | Вставить символ из строки выше |
| <c-w> | Удалить слово |
| <c-r>. | Вставить содержимое регистра |
| <c-o> | Перейти в обычный режим для одной команды |
| <c-a> | Увеличить число под курсором |
| <c-x> | Уменьшить число под курсором |
Текстовый объект, ограниченный запятыми
Это то, чего мне не хватало в Vim. Текстовый объект, ограниченный запятыми, упрощает изменение списков параметров в языках, подобных C, и других списков, разделённых запятыми. По сути, это область между двумя запятыми или между запятой и скобкой. В строке, показанной на иллюстрации справа, три диапазона, которые может охватывать этот текстовый объект, выделены красным.

Диапазоны текстового объекта «запятая». Если курсор стоит, например, на «arg2», нажатие c i , («изменить между запятыми») удалит «double arg2» и поместит курсор между двумя запятыми в режиме вставки. Очень удобный способ изменить параметры функции.
Эмулированная командная строка Vim
В Kate 4.11 добавлен скрытый параметр, позволяющий символам «/», «?» и «:» открывать новую панель поиска/команд вместо обычной панели поиска, замены и командной строки Kate. Панель предназначена для воспроизведения многих функций командной строки Vim, а также для устранения множества проблем взаимодействия режима Vim в Kate с панелью поиска и замены Kate (интерактивная замена не работает; инкрементный поиск не позиционирует курсор правильно; не может использоваться в назначениях/макросах и т. д.).
Следующие комбинации клавиш предоставляются эмулируемой строкой команд; как и в Vim, их возможно переназначить с помощью cmap, cnoremap и т. п.:
| Клавиша | Описание |
|---|---|
| <c-r>. | вставить содержимое регистра. |
| <c-r><c-w> | Вставить слово под курсором (в документе). |
| <c-p> | Вызвать контекстное автодополнение (см. ниже) перейти назад или вверх по списку дополнений. |
| <c-p> | Перейти вперёд или вниз по списку дополнений. |
| <c-space> | Расширение Vim для Kate. Автодополнение слова по документу. |
| <c-d> | Расширение Vim для Kate. В выражении замены в стиле sed (то есть s/найти/заменить/[g][c][i]) очистить часть «найти» и поместить туда курсор. |
| <c-f> | Расширение Vim для Kate. В выражении замены в стиле sed (то есть s/найти/заменить/[g][c][i]) очистить часть «заменить» и поместить туда курсор. |
| <c-g>. | Расширение Vim для Kate. Как и ., вставить содержимое именованного регистра, но экранировать его так, чтобы при использовании в поиске искалось буквальное содержимое регистра, а не содержимое регистра, истолкованное как регулярное выражение. |
«Контекстное автодополнение» определяется следующим образом:
- В строке поиска (
/или?) — автодополнение по журналу поиска (включая поиск, начатый с помощью*и#, поиск в выражениях замены в стиле sed и т. п.). - В пустой командной строке (
:) выполняется автодополнение из журнала команд (NB: автодополнение имён команд вызывается автоматически при начале ввода). - В командной строке, содержащей выражение замены sed (например,
:s/find/replace/gc), при нахождении курсора над «find» выполняется автодополнение из истории поиска; при нахождении над «replace» — из истории замен.
При выполнении в командной строке выражения замены в стиле sed с флагом «c» (например, s/find/replace/gc) будет запущено интерактивное выражение поиска/замены в стиле Vim.
Некоторые примеры использования эмулированной командной строки с GIF-анимацией приведены в этом блоге. В версии 4.11 эмулированную командную строку можно включить, установив скрытый параметр «Vi Input Mode Emulate Command Bar» в значение true в ваших katerc/kwriterc/kdeveloprc.
Нереализованные возможности
Как сказано выше, цель режима VI в Kate — не стопроцентная поддержка возможностей Vim, однако некоторых возможностей всё же очень не хватает
- Визуальный блочный режим — особенно возможность добавлять текст в начало или конец блочного выделения.
- Доступность команд ex не только в приложении Kate, но и в других программах.
- Код поиска нуждается в доработке, а команды * и # должны выполнять обычный поиск.
Если вам не хватает других возможностей или вы хотите помочь с перечисленными выше, свяжитесь со мной или пришлите исправления! :-)
Журнал изменений
- 16.05.2010:
Первая версия. Сведения собраны из записей в блогах и файлов README, чтобы получить единый источник актуальной информации. - 17.05.2010:
ДобавленыCtrl+AиCtrl+X(увеличение и уменьшение числа под курсором). - 30.08.2010:
Страница перенесена на kate-editor.org. - 10.09.2010:
Исправлен текст о текстовом объекте «запятая» и внесены исправления в оформление. - 03.02.2021:
Таблицы привязок клавиш преобразованы в markdown для Hugo.