1

I am trying to automatically switch my keyboard layout from de to us when leaving insert mode in vim. langmap is not an option, as I sue both us and es keyboard layout system wide.

Could anyone explain why using

function! SetUsLayout()
    silent !setxkbmap us,de
endfunction
autocmd InsertLeave * call SetUsLayout()

does not switch from de to us, nor us to de, when leaving insert mode? I already read: How to automatically change keyboard layout on switch to vim normal-mode? But could not find an answer.

First changing completely to us and then to mixed layout does not solve the issue:

function! SetUsLayout()
    silent !setxkbmap us
    silent !setxkbmap us,de
endfunction
autocmd InsertLeave * call SetUsLayout()

does not work either. In both cases the layout active in insert mode is continued to be used. The function

function! SetUsLayout()
    silent !setxkbmap us
endfunction
autocmd InsertLeave * call SetUsLayout()

however, works perfectly fine. Switching to us layout from an initial de layout. This however is not an option, as then switching back to es is no longer possible.

gwinship
  • 13
  • 4
  • To clarify, are you trying to set your system-wide keyboard layout? Why not just use `:h 'keymap'`? – Jake Grossman Oct 07 '20 at 14:24
  • I find it more comfortable to type characters, such as ü, directly without some hack like "u. But for normal mode I prefer us bindings. If there would be a command to simply toggle between different layouts, I'd be happy to use it. – gwinship Oct 07 '20 at 16:52

1 Answers1

1

For full answer and alternatives you can check this thread on the vi/vim stackexchange here.

I am not sure if I have understood correctly your question, as you mention both [de] and [es] layouts for inserting characters.

This is a solution in case you want :

  • [de] layout for inserting characters
  • [us] layout for normal mode operations
function! SetUsLayout()
    silent !setxkbmap us
endfunction

function! SetDeLayout()
    silent !setxkbmap de
endfunction

function! SetUsDeLayout()
    silent !setxkbmap us,de
endfunction

autocmd VimEnter * call SetUsLayout()
autocmd InsertLeave,CmdlineLeave * call SetUsLayout()
autocmd InsertEnter,CmdlineEnter * call SetDeLayout()
autocmd VimLeave * call SetUsDeLayout()

Arrange the VimLeave function at your preference, I also added that Cmdline Enter/Leave event so that typing in the nvim command line occurs in my native language.

Note also that:

  • For macros, plugins etc… this solution enables you to use the native [us] layout, which prevent a few headaches and remaps. That's the main advantage of this solution over langmap.

  • on my neovim, replace mode does not trigger the event "InsertModeEnter", so you have to use the us layout there if that's also the case on your config.

  • in normal mode, find by character (i.e. f/F/t/T) require to use [us] layout, which may be an annoyance. In that case, you can add mappings such as:

nnoremap fy fz
nnoremap Fy Fz
nnoremap ty tz
nnoremap Ty TZ

It may not work for all letters however, and strangely on my config it requires to press the keymap two times to make it taken into account (as if it had to load the rule in memory). Once done, it works as fast as if it was native.

Lionel Hamayon
  • 1,240
  • 15
  • 25
  • Thank you very much I have tooled around with xkb-switch in the mean time. But I guess I like your native solution better, as it does not come with any external dependencies. – gwinship Dec 06 '20 at 12:09