воскресенье, 31 января 2016 г.

vim-xkbswitch: управление keymap в нормальном режиме и в строках поиска

На днях добавил указанную фичу в vim-xkbswitch. Суть проста. При выходе из режима ввода (Insert mode) в нормальный режим (Normal mode) хотелось бы, чтобы после ввода команд r и f, а также в режиме поиска в командной строке (команды / и ?), системная раскладка переключалась на ту, что была в режиме ввода. К сожалению, реализовать такое с нуля технически весьма затруднительно. К счастью, можно воспользоваться встроенной в vim поддержкой keymap, и более того, управлять ею с помощью настройки iminsert и imsearch при выходе в нормальный режим. В общем, если есть желание управлять keymap из vim-xkbswitch, то в файл .vimrc следует добавить такие строки.
let g:XkbSwitchAssistNKeymap = 1    " for commands r and f
let g:XkbSwitchAssistSKeymap = 1    " for search lines
set keymap=russian-jcukenwin
set iminsert=0
set imsearch=0
Значение keymap в данном случае зависит от дополнительной раскладки, с которой вы работаете. Если по какой-то причине имя системной раскладки (возвращается бэкенд-библиотекой, например xkb-switch) не совпадает с именем keymap (которое обычно присваивается переменной b:keymap_name в файле keymap), то можно настроить отображение из первого во второе, например
let g:XkbSwitchKeymapNames = {'ru' : 'ru_keymap'}
Здесь ru — имя системной раскладки, а ru_keymap — предполагаемое значение b:keymap_name. Если вы работаете с несколькими раскладками одновременно (например, стандартной для нормального режима американской, русской и украинской), то возможно при выходе из режима ввода вы захотите, чтобы keymap указывал на ту из трех раскладок, которая была использована последней. Для этого вам понадобится динамическая настройка keymap, которую можно задействовать с помощью следующих настроек в .vimrc (вместо тех, что были приведены выше).
let g:XkbSwitchAssistNKeymap = 1    " for commands r and f
let g:XkbSwitchAssistSKeymap = 1    " for search lines
let g:XkbSwitchDynamicKeymap = 1
let g:XkbSwitchKeymapNames = {'ru' : 'russian-jcukenwin',
            \ 'uk' : 'ukrainian-jcuken'}
Обратите внимание, здесь не требуется настройка keymap по умолчанию (хотя и не возбраняется), а в качестве значений в словаре g:XkbSwitchKeymapNames используются имена keymap, а не значения b:keymap_name. Если в нормальном режиме вы захотите переключиться на стандартную раскладку нормального режима, то просто временно зайдите в режим ввода и в нем переключитесь на соответствующую раскладку (это можно также сделать командой :setlocal iminsert=0). В строке поиска то же самое можно сделать сочетанием клавиш Ctrl-^. Все это хорошо, но есть одна серьезная проблема. Системный индикатор раскладки будет по-прежнему показывать стандартную в нормальном режиме раскладку, ведь vim-xkbswitch здесь не действует, а keymap не влияет на системную раскладку. На помощь приходит статусная строка, которую можно легко настроить для отображения значения keymap, когда iminsert равен 1, в плагине Powerline. Индикатор keymap будет отображать активную keymap раскладку для команд r и f и строк поиска, в случае, если iminsert равен 1, в то время как индикатор системной раскладки будет отображать стандартную для нормального режима раскладку. В режиме ввода индикатор keymap не действует, поскольку vim-xkbswitch отключает keymap установкой iminsert в 0. Такое решение, кстати, позволяет пользователю видеть, какая раскладка станет активной при переходе из нормального режима в режим ввода, а это здо́рово, на мой взгляд! Я покажу, как настроить индикатор keymap в старом Powerline, в новейших репликах типа vim-airline действия должны быть похожи. Итак, в файле autoload/Powerline/Segments.vim в массиве, передаваемом в функцию Pl#Segment#Init() перед строкой, содержащей слово fileformat, вставляем строки
    \ Pl#Segment#Create('keymap_name'     ,
        \'%{&iminsert && exists("b:keymap_name") ? b:keymap_name : ""}',
        \ Pl#Segment#Modes('!N')),
, в файле autoload/Powerline/Themes/default.vim (или в другом файле темы Powerline, в зависимости от того, какую тему вы используете) в список, передаваемый в функцию Pl#Theme#Buffer(), перед строкой, содержащей слово fileformat, вставляем строку
        \ , 'keymap_name'
, и, наконец, в файле autoload/Powerline/Colorschemes/default.vim (или в другом файле цветовой схемы Powerline, если вы используете нестандартную схему), в произвольном месте списка, передаваемого в функцию Pl#Colorscheme#Init(), вставляем строки
    \ Pl#Hi#Segments(['keymap_name'], {
        \ 'n': ['brightestorange', 'gray2'],
        \ 'i': ['brightestorange', 'darkestblue'],
        \ }),
    \
После этого выполняем команду
:PowerlineClearCache
, перезагружаем vim и наслаждаемся индикацией keymap. Напоминаю, что стандартная в нормальном режиме раскладка отображаться не будет. Вот так может выглядеть статусная строка Powerline с индикатором keymap (обратите внимание на оранжевые буквы ru).