{"id":13898887,"url":"https://github.com/lyokha/vim-xkbswitch","last_synced_at":"2025-04-09T05:10:09.500Z","repository":{"id":7775162,"uuid":"9144532","full_name":"lyokha/vim-xkbswitch","owner":"lyokha","description":"vim plugin for automatic keyboard layout switching in insert mode","archived":false,"fork":false,"pushed_at":"2024-09-17T20:34:33.000Z","size":258,"stargazers_count":483,"open_issues_count":16,"forks_count":22,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-04-02T04:03:09.240Z","etag":null,"topics":["keyboard-layout","switch-layouts","vim"],"latest_commit_sha":null,"homepage":null,"language":"Vim Script","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lyokha.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-04-01T09:31:00.000Z","updated_at":"2025-03-08T16:02:06.000Z","dependencies_parsed_at":"2024-03-12T17:49:01.392Z","dependency_job_id":"082e087c-c1af-4fe8-8346-d34eabd7190f","html_url":"https://github.com/lyokha/vim-xkbswitch","commit_stats":{"total_commits":175,"total_committers":12,"mean_commits":"14.583333333333334","dds":"0.31999999999999995","last_synced_commit":"99821a4b8ee2a05996954a2894d043af001f2d7b"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyokha%2Fvim-xkbswitch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyokha%2Fvim-xkbswitch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyokha%2Fvim-xkbswitch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lyokha%2Fvim-xkbswitch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lyokha","download_url":"https://codeload.github.com/lyokha/vim-xkbswitch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247980837,"owners_count":21027808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["keyboard-layout","switch-layouts","vim"],"created_at":"2024-08-06T18:04:30.847Z","updated_at":"2025-04-09T05:10:09.474Z","avatar_url":"https://github.com/lyokha.png","language":"Vim Script","funding_links":[],"categories":["Vim Script"],"sub_categories":[],"readme":"Vim-xkbswitch\n=============\n\nby Alexey Radkov and Dmitry Hrabrov a.k.a. DeXPeriX\n\nTable of contents\n-----------------\n\n- [About](#about)\n- [Features](#features)\n- [Setup](#setup)\n- [Configuration](#configuration)\n    + [Basic configuration](#basic-configuration)\n    + [Keymap assistance in Normal mode](#keymap-assistance-in-normal-mode)\n    + [Default layouts](#default-layouts)\n    + [Disable for specific filetypes](#disable-for-specific-filetypes)\n    + [Enable in runtime](#enable-in-runtime)\n- [Insert enter hook](#insert-enter-hook)\n- [Custom keyboard layout switching rules](#custom-keyboard-layout-switching-rules)\n- [Troubleshooting](#troubleshooting)\n\nAbout\n-----\n\nIf you speak and write in two or more languages, you may know how it's\nfrustrating to constantly switch keyboard layouts manually, because vim\nin command mode can understand only English letters. So you need constantly\nchange keyboard layout into English if you need perform some command and\nif you are writing texts, for example, in Russian, German or Chinese at the\nsame time.\n\nVim plugin XkbSwitch can be used to easily switch current keyboard layout back\nand forth when entering and leaving Insert mode. Say, you are typing some\ndocument in Russian and have to leave Insert mode: when you press ``\u003cEsc\u003e``\nyour keyboard layout switches to US/English automatically. When you further\nenter Insert mode once again the Russian keyboard layout will be automatically\nswitched back!\n\nXkbSwitch requires an OS dependent keyboard layout switcher. Below is the list\nof compatible switchers.\n\n- **UNIX / Linux / X Server**:\n  [xkb-switch](http://github.com/ierton/xkb-switch).\n- **Windows**: [xkb-switch-win](http://github.com/DeXP/xkb-switch-win).\n- **Mac OS X**: [xkbswitch-macosx](http://github.com/myshov/xkbswitch-macosx) or\n  [Input Source Switcher](http://github.com/vovkasm/input-source-switcher). In\n  the latter case, put line\n\n    ```vim\n  let g:XkbSwitchLib = '/usr/local/lib/libInputSourceSwitcher.dylib'\n    ```\n\n  into your .vimrc settings.\n- **Gnome 3 and 4x**: [g3kb-switch](http://github.com/lyokha/g3kb-switch). The\n  plugin can be loaded with\n\n    ```vim\n  let g:XkbSwitchLib = '/usr/local/lib/libg3kbswitch.so'\n    ```\n\n- **i3wm**: [xkb-switch-i3](http://github.com/Zebradil/xkb-switch-i3).\n- **sway**: [sway-vim-kbswitch](http://github.com/khaser/sway-vim-kbswitch).\n\nFeatures\n--------\n\n* Supported OS: UNIX (X Server / Sway), Windows, Mac OS X.\n* Switches keyboard layout when entering / leaving Insert and Select modes\n  as well as the command line when searching patterns.\n* Dynamic keymap assistance in commands like *r* and *f* in Normal mode.\n* Keyboard layouts are stored separately for each buffer.\n* Keyboard layouts are kept intact while navigating between windows or\n  tabs without leaving Insert mode.\n* Automatic loading of language-friendly Insert mode mappings duplicates.\n  For example, when Russian mappings have loaded then if there was a mapping\n\n    ```vim\n  \u003cC-G\u003eS        \u003cPlug\u003eISurround\n    ```\n\n  a new mapping\n\n    ```vim\n  \u003cC-G\u003eЫ        \u003cPlug\u003eISurround\n    ```\n\n  will be loaded. Insert mode mappings duplicates make it easy to apply\n  existing maps in Insert mode without switching current keyboard layout.\n* Fast and easy building of custom syntax based keyboard layout switching\n  rules in Insert mode.\n\nSetup\n-----\n\nBefore installation of the plugin the OS dependent keyboard layout switcher\nmust be installed (see [About](#about)). The plugin itself is installed by\nextracting of the distribution in your vim runtime directory.\n\nConfiguration\n-------------\n\n### Basic configuration\n\nBasic configuration requires only 1 line in your .vimrc:\n\n```vim\nlet g:XkbSwitchEnabled = 1\n```\n\nAdditionally path to the backend switcher library can be defined:\n\n```vim\nlet g:XkbSwitchLib = '/usr/local/lib/libxkbswitch.so'\n```\n\nHowever normally it is not necessary as far as the plugin is able to find it\nautomatically. To enable Insert mode mappings duplicates user may want to add\n\n```vim\nlet g:XkbSwitchIMappings = ['ru']\n```\n\nHere Insert mappings duplicates for Russian winkeys layout will be generated\nwhenever Insert mode is started. It is possible to define a list of different\nlayouts, for example\n\n```vim\nlet g:XkbSwitchIMappings = ['ru', 'de']\n```\n\nbut currently only Russian winkeys ('ru') and Ukrainian ('uk') layout\ntranslation maps are supported out of the box. There are 2 ways how a user can\nprovide extra definitions of keyboard layout translation maps (or alter/remove\nexisting default 'ru' and 'uk' maps):\n\n* Define variable g:XkbSwitchIMappingsTr:\n\n    ```vim\n  let g:XkbSwitchIMappingsTr = {\n              \\ 'ru':\n              \\ {'\u003c': 'qwertyuiop[]asdfghjkl;''zxcvbnm,.`/'.\n              \\       'QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM\u003c\u003e?~@#$^\u0026|',\n              \\  '\u003e': 'йцукенгшщзхъфывапролджэячсмитьбюё.'.\n              \\       'ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,Ё\"№;:?/'},\n              \\ 'de':\n              \\ {'\u003c': 'yz-[];''/YZ{}:\"\u003c\u003e?~@#^\u0026*_\\',\n              \\  '\u003e': 'zyßü+öä-ZYÜ*ÖÄ;:_°\"§\u0026/(?#'},\n              \\ }\n    ```\n\n* Create a file with layout translation maps and put its path into variable\n  g:XkbSwitchIMappingsTrData, for example:\n\n    ```vim\n  let g:XkbSwitchIMappingsTrData = $HOME.'/opt/xkbswitch.tr'\n    ```\n\n  File with maps must follow this format:\n\n    ```\n  ru  Russian winkeys layout\n  \u003c qwertyuiop[]asdfghjkl;'zxcvbnm,.`/QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM\u003c\u003e?~@#$^\u0026|\n  \u003e йцукенгшщзхъфывапролджэячсмитьбюё.ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,Ё\"№;:?/\n\n  de\n  \u003c yz-[];'/YZ{}:\"\u003c\u003e?~@#^\u0026*(_\\\n  \u003e zyßü+öä-ZYÜ*ÖÄ;:_°\"§\u0026/()?#\n    ```\n\n  Sample file xkbswitch.tr with exactly this content is shipped with this\n  plugin distribution. Files with translation maps can be easily created from\n  vim keymap definitions: see details [here](utils/README.md).\n\nBe very careful with mapping duplicates! They won't replace existing Insert\nmode mappings but may define extra mappings that will change normal Insert\nmode user experience. For example, plugin echofunc defines Insert mode\nmappings for '(' and ')', therefore assuming that in Deutsch translation map\nthere could be ')' to '=' translation, we would get '=' unusable in any\nkeyboard layout (as far as echofunc treats ')' in a very specific way). That\nis why this translation is missing in example above and in file xkbswitch.tr\ncontent.\n\nThere are multiple examples of similar issues. For instance Russian winkeys\ntranslate '.' into 'ю' and when you are editing a C/C++ source file with\nenabled omnicompletion plugin character 'ю' (which you can use in comments)\nwill always be replaced by '.'. To address these issues starting from **version\n0.10** a new variable g:XkbSwitchSkipIMappings was introduced. It defines which\noriginal Insert mode mappings should not be translated for specific filetypes.\nAdd into your .vimrc lines\n\n```vim\nlet g:XkbSwitchSkipIMappings =\n        \\ {'c'   : ['.', '\u003e', ':', '{\u003cCR\u003e', '/*', '/*\u003cCR\u003e'],\n        \\  'cpp' : ['.', '\u003e', ':', '{\u003cCR\u003e', '/*', '/*\u003cCR\u003e']}\n```\n\nand now you will be able to print 'ю' in C and C++ source files. In this\nexample six Insert mode mappings were prohibited for translation in two\nfiletypes: C and C++. The first three correspond to omnicompletion plugin and\nthe last three address plugin c.vim. Why mappings duplicates starting from '/'\nwere added: Russian winkeys translate '/' into '.' and this makes vim wait for\na while until the next character after '.' has been inserted which makes\nomnicompletion plugin almost unusable. If you want to skip specific Insert\nmode mappings for all filetypes then you can use '\\*' as the filetype key in\ng:XkbSwitchSkipIMappings.\n\nBeware: variable g:XkbSwitchSkipIMappings is not parameterized by keyboard\nlayouts but only by filetypes.\n\nBesides natural Insert mode mappings, register insertion translations are also\nsupported. For example, being in Insert mode and having Russian winkeys layout\non, you can insert content of register 'a' just printing ``\u003cC-R\u003eф`` without\nswitching current keyboard layout. To disable translation of register names in\nInsert mode put line\n\n```vim\nlet g:XkbSwitchLoadRIMappings = 0\n```\n\ninto your .vimrc.\n\n### Keymap assistance in Normal mode\n\nXkbSwitch is unable to guess keyboard layout when using Normal mode commands\n*r* and *f* and, in the past, searching patterns with */* and *?*. Fortunately,\nit can assist *keymap* in this by setting\n\n```vim\nlet g:XkbSwitchAssistNKeymap = 1        \" for commands r and f\nif !exists('##CmdlineEnter')\n    let g:XkbSwitchAssistSKeymap = 1    \" for search lines\nendif\n```\n\ngiven that keymap is set to some value, for example\n\n```vim\nset keymap=russian-jcukenwin\nset iminsert=0\nset imsearch=0\n```\n\n(Note that setting of g:XkbSwitchAssistSKeymap is deprecated because tracking\nof entering / leaving command line for searching patterns is fully supported\nafter CmdlineEnter and CmdlineLeave events have been introduced in vim.)\n\nNow when you leave Insert mode, the keyboard layout is switched back to the\nusual Normal mode value, but values of *iminsert* and *imsearch* are set\ndepending on the last Insert mode keyboard layout: if it was equal to the\nvalue of b:keymap_name that is normally defined in keymap files then they are\nset to 1, otherwise to 0. If keymap names do not match system keyboard layout\nnames then you can remap them using variable g:XkbSwitchKeymapNames.\n\n```vim\nlet g:XkbSwitchKeymapNames = {'ru' : 'ru_keymap', 'uk' : 'uk_keymap'}\n```\n\nHere *ru* and *uk* are system keyboard layout names whereas *ru_keymap* and\n*uk_keymap* are values of b:keymap_name.\n\nWhen more than two keyboard layouts are used it probably makes sense to set\nkeymaps dynamically in runtime. XkbSwitch can do it for you! You only need to\ndefine a new variable\n\n```vim\nlet g:XkbSwitchDynamicKeymap = 1\n```\n\nand map g:XkbSwitchKeymapNames to keymap names instead of values of\nb:keymap_name. For example\n\n```vim\nlet g:XkbSwitchKeymapNames =\n            \\ {'ru' : 'russian-jcukenwin', 'uk' : 'ukrainian-jcuken'}\n\n```\n\nNow keymap will automatically switch to the last keyboard layout when you\nleave Insert mode.\n\nTo toggle keymap layout in Normal mode for using in commands *r* and *f*, you\nmay need to set a dedicated key:\n\n```vim\nlet g:XkbSwitchIminsertToggleKey = '\u003cC-^\u003e'\n```\n\nBy default pressing the key will be echoed in the command-line which is\nsometimes superfluous: modern status-line plugins such as\n[airline](http://github.com/vim-airline/vim-airline) normally provide support\nfor showing iminsert indicators.\n\nTo disable echo messages when toggling keymap layout add line\n\n```vim\nlet g:XkbSwitchIminsertToggleEcho = 0\n```\n\ninto your .vimrc.\n\nTo enable the iminsert indicator in airline add line\n\n```vim\nlet g:airline_detect_iminsert = 1\n```\n\nNotice that toggling keymap layout when typing a pattern for a search command\ncan be done with the builtin key *Ctrl-^*.\n\n### Default layouts\n\nBy default last Normal mode keyboard layout is restored when leaving Insert\nmode, but you can specify to use particular layout for that:\n\n```vim\nlet g:XkbSwitchNLayout = 'us'\n```\n\nAlso you can specify *original* Insert mode keyboard layout:\n\n```vim\nlet g:XkbSwitchILayout = 'us'\n```\n\nOr *unconditional* Insert mode keyboard layout using buffer variable with the\nsame name:\n\n```vim\nlet b:XkbSwitchILayout = 'us'\n```\n\nIf b:XkbSwitchILayout is set to the empty value then the keyboard layout is not\nchanged when entering Insert mode. Be aware that momental switching from-and-to\nInsert mode (e.g. with Insert mode command ``\u003cC-O\u003e`` and all types of\nselections) will turn current keyboard layout to the value of\nb:XkbSwitchILayout. If you want to use unconditional Insert mode keyboard layout\nby default then put line\n\n```vim\nautocmd BufEnter * let b:XkbSwitchILayout = 'us'\n```\n\ninto your .vimrc (change *us* to desired value if needed).\n\n### Disable for specific filetypes\n\nIt makes sense to disable XkbSwitch for buffers with specific filetypes, for\nexample various file system or tag navigators. For example, to disable\nXkbSwitch for NerdTree add in your .vimrc line\n\n```vim\nlet g:XkbSwitchSkipFt = ['nerdtree']\n```\n\nBy default (e.g. when g:XkbSwitchSkipFt is not defined in .vimrc) following\nfiletypes are skipped: *tagbar*, *gundo*, *nerdtree* and *fuf* (FuzzyFinder).\n\n### Enable in runtime\n\nYou can enable XkbSwitch in runtime (e.g. when g:XkbSwitchEnabled is not set\nin your .vimrc) by issuing command\n\n```vim\n:EnableXkbSwitch\n```\n\nThis command will respect current settings of g:XkbSwitchIMappings etc. Be\naware that there is no way to disable XkbSwitch after it has been enabled.\n\nInsert enter hook\n-----------------\n\nYou may want to run a custom vim function when entering Insert mode. For\nexample, let's flash the cursor for a moment if the keyboard layout effectively\nswitches. Plugin [Beacon](https://github.com/DanilaMihailov/beacon.nvim) fits\nvery well this purpose. Just put lines\n\n```vim\nlet g:XkbSwitchIEnterHook = 'XkbSwitchIEnterHook'\n\nhighlight link BeaconIEnter Cursor\n\nfun! XkbSwitchRevertBeaconHighlight(id)\n    highlight! link Beacon BeaconDefault\nendfun\n\nfun! XkbSwitchIEnterHook(old, new)\n    if a:new != a:old\n        let save_beacon_size = g:beacon_size\n        let g:beacon_size = 20\n        highlight! link Beacon BeaconIEnter\n        Beacon\n        let g:beacon_size = save_beacon_size\n        call timer_start(500, 'XkbSwitchRevertBeaconHighlight')\n    endif\nendfun\n```\n\ninto .vimrc file. Arguments *old* and *new* are keyboard layouts being switched\nfrom and to while transitioning from Normal to Insert mode.\n\nCustom keyboard layout switching rules\n--------------------------------------\n\nImagine that you are editing a simple dictionary with 2 columns delimited by\nvertical bars. In the first column you are writing down a German word and in\nthe second column - its Russian translation. For example:\n\n```\n| Wort         | Übersetzung |\n|--------------|-------------|\n| der Mond     | луна        |\n| humpeln      | хромать     |\n| stark        | сильный     |\n```\n\nYou want the keyboard layout to be automatically switched to the corresponding\nlanguage when you are moving between the columns in Insert mode. It is\nfeasible! When you start editing switch layouts in the both columns manually\njust once: after that XkbSwitch will learn how to switch them further. It will\nrestore layouts after leaving Insert mode and entering it once again.\n\nIn this section it will be shown how to achieve this. First of all there\nshould exist criteria upon which XkbSwitch will decide when it must switch\nlayouts. The simplest criteria are syntactic rules. So the content of the\ncolumns must be syntactically distinguishable. It means that we need a file\nwith syntax rules and some new filetype defined, say *mdict*. For the sake of\nsimplicity let it be not an absolutely new filetype but rather a subclass of\nan existing one, for example vimwiki. Then we should create a new file\nafter/syntax/vimwiki.vim:\n\n```vim\nif match(bufname('%'), '\\.mdict$') == -1\n    finish\nendif\n\nlet s:colors = {'original':   [189, '#d7d7ff'],\n              \\ 'translated': [194, '#d7ffd7'],\n              \\ 'extra':      [191, '#d7ff5f']}\n\nfunction! s:set_colors()\n    let colors = deepcopy(s:colors)\n    if exists('g:colors_name') \u0026\u0026 g:colors_name == 'lucius' \u0026\u0026\n                \\ g:lucius_style == 'light'\n        let colors['original']   = [26,  '#005fd7']\n        let colors['translated'] = [22,  '#005f00']\n        let colors['extra']      = [167, '#d75f5f']\n    endif\n    exe 'hi mdictOriginalHl term=standout ctermfg='.colors['original'][0].\n                \\ ' guifg='.colors['original'][1]\n    exe 'hi mdictTranslatedHl term=standout ctermfg='.colors['translated'][0].\n                \\ ' guifg='.colors['translated'][1]\n    exe 'hi mdictExtraHl term=standout ctermfg='.colors['extra'][0].\n                \\ ' guifg='.colors['extra'][1]\nendfunction\n\nsyntax match mdictCell '|[^|]*\\ze|' containedin=VimwikiTableRow contained\n            \\ contains=VimwikiCellSeparator,mdictOriginal,mdictTranslated\nsyntax match mdictOriginal '[^|]\\+\\ze|\\s*\\S*.*$' contained contains=mdictExtra\nsyntax match mdictTranslated '[^|]\\+\\ze|\\s*$' contained contains=mdictExtra\nsyntax match mdictExtra '([^()]*)' contained\n\ncall s:set_colors()\nautocmd ColorScheme * call s:set_colors()\n\nhi link mdictOriginal   mdictOriginalHl\nhi link mdictTranslated mdictTranslatedHl\nhi link mdictExtra      mdictExtraHl\n```\n\nHere the syntactic criteria have been defined: content of the first column\nwill have syntax id *mdictOriginal* and content of the second column -\n*mdictTranslated*.\n\nIn .vimrc following lines must be added:\n\n```vim\nlet g:mdict_synroles = ['mdictOriginal', 'mdictTranslated']\n\nfun! MdictCheckLang(force)\n    if !filereadable(g:XkbSwitchLib)\n        return\n    endif\n\n    let cur_synid  = synIDattr(synID(line(\".\"), col(\".\"), 1), \"name\")\n\n    if !exists('b:saved_cur_synid')\n        let b:saved_cur_synid = cur_synid\n    endif\n    if !exists('b:saved_cur_layout')\n        let b:saved_cur_layout = {}\n    endif\n\n    if cur_synid != b:saved_cur_synid || a:force\n        let cur_layout = ''\n        for role in g:mdict_synroles\n            if b:saved_cur_synid == role\n                let cur_layout =\n                    \\ libcall(g:XkbSwitchLib, 'Xkb_Switch_getXkbLayout', '')\n                let b:saved_cur_layout[role] = cur_layout\n                break\n            endif\n        endfor\n        for role in g:mdict_synroles\n            if cur_synid == role\n                if exists('b:saved_cur_layout[role]')\n                    call libcall(g:XkbSwitchLib, 'Xkb_Switch_setXkbLayout',\n                                \\ b:saved_cur_layout[role])\n                else\n                    let b:saved_cur_layout[role] = empty(cur_layout) ?\n                                \\ libcall(g:XkbSwitchLib,\n                                \\ 'Xkb_Switch_getXkbLayout', '') : cur_layout\n                endif\n                break\n            endif\n        endfor\n        let b:saved_cur_synid = cur_synid\n    endif\nendfun\n\nautocmd BufNewFile,BufRead *.mdict setlocal filetype=vimwiki |\n           \\ EnableXkbSwitch\nautocmd BufNewFile         *.mdict VimwikiTable 2 2\nautocmd BufNewFile         *.mdict exe \"normal dd\" | startinsert\nautocmd CursorMovedI       *.mdict call MdictCheckLang(0)\n\nlet g:XkbSwitchPostIEnterAuto = [\n            \\ [{'pat': '*.mdict', 'cmd': 'call MdictCheckLang(1)'}, 0] ]\n```\n\nFunction MdictCheckLang() does all the custom layout switching and can be\nregarded as a plugin to the XkbSwitch. The first autocommand states that if\nfile has extension *.mdict* then its filetype must be *vimwiki* and turns on\nXkbSwitch. The next two autocommands are optional and only make editing mdict\nfiles more comfortable. The last autocommand (for CursorMovedI events) calls\nMdictCheckLang() when cursor moves into different columns in Insert mode.\nThe next definition\n\n```vim\nlet g:XkbSwitchPostIEnterAuto = [\n            \\ [{'pat': '*.mdict', 'cmd': 'call MdictCheckLang(1)'}, 0] ]\n```\n\nregisters an InsertEnter autocommand in augroup XkbSwitch. If we had instead\ndefined an InsertEnter autocommand here then the command would have been put\nbefore the standard InsertEnter autocommand in augroup XkbSwitch. Using variable\ng:XkbSwitchPostIEnterAuto ensures that the new command will run after the\nstandard InsertEnter autocommand. The second element in an item inside\ng:XkbSwitchPostIEnterAuto can be 0 or 1. If it is 1 then XkbSwitch won't switch\nlayout itself when entering Insert mode. In our case it should be 0 because\nMdictCheckLang() requires preliminary switching keyboard layout from XkbSwitch\nwhen entering Insert mode.\n\nStarting from **version 0.9** a generic helper for building custom syntax based\nkeyboard layout switching rules was implemented inside the plugin code.  Now\nbuilding syntax rules is as simple as defining variable g:XkbSwitchSyntaxRules\nin .vimrc. For example\n\n```vim\nlet g:XkbSwitchSyntaxRules = [\n            \\ {'pat': '*.mdict', 'in': ['mdictOriginal', 'mdictTranslated']},\n            \\ {'ft': 'c,cpp', 'inout': ['cComment', 'cCommentL']} ]\n```\n\nregisters syntax rules for files with extension *.mdict* (the first element in\ng:XkbSwitchSyntaxRules: it replaces our old definitions of g:mdict_synroles,\nMdictCheckLang(), autocmd CursorMovedI and g:XkbSwitchPostIEnterAuto) and\ncomments rules for C and C++ files (the second element in\ng:XkbSwitchSyntaxRules). The comments rules define that comments areas may\nhave their own keyboard layouts in Insert mode and when cursor enters or\nleaves them the corresponding layouts must be restored. It may be useful if\na user wants to make comments in a language that uses not standard keyboard\nlayout without switching layouts back and forth. Notice that the second rule\nlists syntax groups in element *inout* whereas the first rule uses element\n*in*. The difference is that in the case of the comments rule we want to\nrestore basic keyboard layout (i.e. layout for code areas) when leaving\ncomments areas, but in the mdict rule we do not care about leaving areas\n*mdictOriginal* and *mdictTranslated* and only care about entering them.\n\nTroubleshooting\n---------------\n\n* To test if the switcher library is well configured, run commands\n\n    ```vim\n  :echo libcall(g:XkbSwitchLib, 'Xkb_Switch_getXkbLayout', '')\n    ```\n\n  and\n\n    ```vim\n  :call libcall(g:XkbSwitchLib, 'Xkb_Switch_setXkbLayout', 'ru')\n    ```\n\n  which get and set the keyboard layout.\n\n* Some characters from alternative keyboard layouts may fail to enter or behave\n  in strange ways for certain filetypes. For example in Russian winkeys layout\n  characters 'б', 'ю', 'ж' and 'э' may fail to enter in C++ source files. The\n  reason of that is layout translation maps specified in variable\n  g:XkbSwitchIMappings. You may work this around by simply not setting this\n  variable, or better by specifying characters from the main keyboard layout\n  whose translation should be skipped using variable g:XkbSwitchSkipIMappings.\n  See details in section [Basic configuration](#basic-configuration).\n\n* There is a known issue when vim-latex package is installed. In this case\n  entering Russian symbols in Insert mode when editing tex files becomes\n  impossible. The issue arises from clashing XkbSwitch Insert mappings\n  duplicates with mappings defined in vim-latex. To work this issue around you\n  can disable XkbSwitch Insert mode mappings duplicates for filetype *tex*:\n\n    ```vim\n  let g:XkbSwitchIMappingsSkipFt = ['tex']\n    ```\n\n* When leaving Insert mode after using an alternative keyboard layout (say\n  Russian), there could be a time lag (of length *1 sec* if the value of\n  ``timeoutlen`` was not altered) before typing commands in Normal mode gets\n  back to produce any effect. To cope with this issue, the value of\n  `ttimeoutlen` (notice the *double-t* in the beginning of its name!) must be\n  set to some small value, say\n\n    ```vim\n  set ttimeoutlen=50\n    ```\n\n* *Related to X Server only.* When editing files on a remote host via ssh the\n  ssh -X option must be supplied:\n\n    ```sh\n  ssh -X remote.host\n    ```\n\n  This option will make ssh forward X Server protocol messages between the\n  local host and the remote host thus making it possible to switch the local\n  host keyboard layouts.\n\n* *Related to GTK based gvim only.* In bare X terminals keycodes for ``\u003cC-S\u003e``\n  and ``\u003cC-Ы\u003e`` are the same which makes it possible to leave sequences with\n  control keys in Insert mode mappings duplicates as they are. But this is not\n  the case in GTK based gvim. The issue is still investigated.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flyokha%2Fvim-xkbswitch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flyokha%2Fvim-xkbswitch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flyokha%2Fvim-xkbswitch/lists"}