How to automatically change keyboard layout on switch to vim normal-mode?
Asked Answered
S

5

15

Sometimes I use vim to write non-US text, and when I wanna use any command in normal mode, I need to change layout to US. It's possible to do that automatically?

PS. I can do mapping like this, but in this case command looks like :ц instead :w - not pretty and typo-risk.

Update

I don't want to use keymap option, because I prefer switch languages by CapsLock. I've try to write autocmd for InsertLeave event, but failed...

Update 2

Probably anybody know, why the following not work?

function SetUsLayout()
  !setxkbmap us,ru
endfunction

autocmd InsertLeave * call SetUsLayout()
Shoplifter answered 11/6, 2012 at 15:58 Comment(3)
The answer here is relevant: https://mcmap.net/q/384616/-how-to-avoid-constant-switching-to-and-from-english-keyboard-layout-to-type-vim-commands-when-writing-in-non-latin-language-e-g-greekMidshipmite
See my answer to a similar question "Vim “annoyance” with keyboard layouts" rather than the one linked in the previous comment, since it covers effectively the same issue and it is more thorough.Byte
I already write in Update, that don't want to use keymap option, because it's not possible to map CapsLock in vim.Shoplifter
S
4

Looks like, that cross-platform solution doesn't exist... So, under KDE I use the following:

function! SetUsLayout()
  silent !qdbus org.kde.keyboard /Layouts setLayout us > /dev/null
endfunction

autocmd InsertLeave * call SetUsLayout()
Shoplifter answered 12/6, 2012 at 9:47 Comment(0)
P
5
:help langmap

is likely to provide all the info you need.

Pouf answered 11/6, 2012 at 16:17 Comment(6)
"Characters entered in Command-line mode will NOT be affected by this option." So hjkl works fine, but commands not.Shoplifter
This deals with what you asked for: normal mode commands. See :help keymap for the command mode.Pouf
Ok, I can set keymap=russian-jcukenwin, but to switch to US I need to use ctrl+^ (or map any other), but not very convenient CapsLock.Shoplifter
I'm not really in a position to test it out (french layout) but you could try something like :nnoremap : :<C-^>. What's the deal with CapsLock?Pouf
https://mcmap.net/q/88627/-how-to-map-caps-lock-key-in-vim At now I try to use OS-dependent solution: setxkbmap to switch layout automaticly on InsertLeave eventShoplifter
This approach is limited in that some keyboard layouts, for example the Canadian Multilingual layout, map keys not to characters but to the first keystroke of a digraph. For example, the key which in the US Standard layout produces [ will, when pressed with the Canadian Multilingual Layout active, initiate the creation of a circumflex-accented character, e.g. ê.Absorbefacient
S
4

Looks like, that cross-platform solution doesn't exist... So, under KDE I use the following:

function! SetUsLayout()
  silent !qdbus org.kde.keyboard /Layouts setLayout us > /dev/null
endfunction

autocmd InsertLeave * call SetUsLayout()
Shoplifter answered 12/6, 2012 at 9:47 Comment(0)
W
1

For me, using qdbus is the best option. I've made a simple but fragile plugin that works really well for me: https://github.com/ironhouzi/bikey-vim/tree/master/plugin

I call it fragile, since it doesn't have much robustness to it if anybody else wants to use it.

I mostly want English when I'm using Vim, with a few exceptions. When I want to write in my native language, I hit 'leader'-k and my airline status bar will show that I've switched language. When the language is not English, the script will ensure that every time I enter insert mode, my native language is set through qdbus. Every time I leave insert mode, the language is set back to English. It also supports individual settings between buffers. Even though this might not be the best way to do things, I thought I'd share it, in case someone else might get some use out of it.

Whittle answered 13/9, 2014 at 11:1 Comment(0)
C
0

In Ubuntu I use the following:

function! SetUsLayout()
  silent !qdbus org.gnome.SettingsDaemon.Keyboard /org/gnome/SettingsDaemon/Keyboard org.gnome.SettingsDaemon.Keyboard.SetInputSource 0 > /dev/null
endfunction

autocmd InsertLeave * call SetUsLayout()

or shorter:

silent !gsettings set org.gnome.desktop.input-sources current 0  
Corlisscorly answered 19/3, 2016 at 21:40 Comment(0)
P
0

In Linux with X11 you can do the following for nvim\vim:

SetUsLayout = function()
  vim.api.nvim_command('silent !xkb-switch -s us')
end

vim.api.nvim_command('autocmd InsertLeave * call SetUsLayout()')

(Here's an extended use case senario)

Proptosis answered 9/10, 2023 at 14:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.