В .vimrc поддержка автоматического переключения русской раскладки в режиме ввода теперь выглядит так:
" ---- Automatic keyboard layout switching upon entering/leaving insert mode " ---- using xkb-switch utility " ---- let g:XkbSwitchEnabled = 0 let g:XkbSwitchLib = "/usr/local/lib/libxkbswitch.so" fun! <SID>xkb_mappings_load() for hcmd in ['gh', 'gH', 'g^H'] exe "nnoremap <buffer> <silent> ".hcmd. \ " :call <SID>xkb_switch(1)<CR>".hcmd endfor xnoremap <buffer> <silent> <C-g> :<C-u>call <SID>xkb_switch(1)<CR>gv<C-g> snoremap <buffer> <silent> <C-g> <C-g>:<C-u>call <SID>xkb_switch(0)<CR>gv let b:xkb_mappings_loaded = 1 endfun fun! <SID>ru_mappings_load() redir => mappings silent imap redir END for mapping in split(mappings, '\n') let value = substitute(mapping, '\s*\S\+\s\+\S\+\s\+\(.*\)', '\1', '') " do not duplicate <script> mappings (when value contains '&') if match(value, '^[\s*@]*&') != -1 continue endif let data = split(mapping, '\s\+') " do not duplicate <Plug> mappings (when key starts with '<Plug>') if match(data[1], '^\c<Plug>') != -1 continue endif let from = 'qwertyuiop[]asdfghjkl;\\x27zxcvbnm,.`/'. \ 'QWERTYUIOP{}ASDFGHJKL:\\x22ZXCVBNM<>?~@#\\x24^\\x26|' let to = 'йцукенгшщзхъфывапролджэячсмитьбюё.'. \ 'ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,Ё\\x22№;:?/' " protect backslashes before next evaluations let newkey = substitute(data[1], '\', '\\\\', 'g') " pre-evaluate the new key let newkey = substitute(newkey, \ '\(\%(<[^>]\+>\)*\)\(.\{-}\)\(\%(<[^>]\+>\)*\)$', \ '"\1".tr("\2", "'.from.'", "'.to.'")."\3"', 'i') " evaluate the new key let newkey = eval(newkey) " do not reload existing mapping unnecessarily if newkey == data[1] continue endif let mapcmd = match(value, '^[\s&@]*\*') == -1 ? 'imap' : 'inoremap' " probably the mapping was defined using <expr> let expr = match(value, \ '^[\s*&@]*[a-zA-Z][a-zA-z0-9_#\-]*(.\{-})$') != -1 ? \ '<expr>' : '' " new maps are always silent and buffer-local exe mapcmd.' <silent> <buffer> '.expr.' '.newkey.' '. \ maparg(data[1], 'i') endfor endfun fun! <SID>xkb_switch(mode) let cur_layout = libcall(g:XkbSwitchLib, 'Xkb_Switch_getXkbLayout', '') if a:mode == 0 if cur_layout != 'us' call libcall(g:XkbSwitchLib, 'Xkb_Switch_setXkbLayout', 'us') endif let b:xkb_layout = cur_layout elseif a:mode == 1 if !exists('b:xkb_mappings_loaded') call <SID>xkb_mappings_load() call <SID>ru_mappings_load() endif if exists('b:xkb_layout') if b:xkb_layout != cur_layout call libcall(g:XkbSwitchLib, 'Xkb_Switch_setXkbLayout', \ b:xkb_layout) endif endif endif endfun fun! <SID>enable_xkb_switch(force) if g:XkbSwitchEnabled && !a:force return endif if executable(g:XkbSwitchLib) autocmd InsertEnter * call <SID>xkb_switch(1) autocmd InsertLeave * call <SID>xkb_switch(0) endif let g:XkbSwitchEnabled = 1 endfun command EnableXkbSwitch call <SID>enable_xkb_switch(0) if g:XkbSwitchEnabled call <SID>enable_xkb_switch(1) endifОбратите внимание: по умолчанию автоматическое переключение раскладки неактивно (переменная g:XkbSwitchEnabled равна 0). Пользователь может включить ее либо вручную (введя команду :EnableXkbSwitch), либо объявив автокоманды, которые сработают при определенных условиях. Например, можно включить автоматическое переключение раскладки для файлов типа reStructuredText и tex:
autocmd FileType rst,tex EnableXkbSwitchВ новой версии скрипта я добавил функцию
Внимание: алгоритм трансляции из латинского ключа в русский не универсален и возможны сбои для необычных ключей! Однако для всех маппингов riv, а также маппингов плагина c.vim он работает исправно. Список загруженных маппингов режима ввода можно просмотреть командой :imap.
Update. Оформили в виде плагина, см. здесь и здесь. Последнее замечание относительно неуниверсальности трансляции маппингов в новом плагине неактуально.