3

Thank you for your interest in this rather specialized question.

This is a follow-up to this question : Mapping for expression register with langmap active

I’m looking for the best way to associate two different keymaps in (Neo)vim, one to input text (bépo in my case) and US Qwerty for all the other commands.


TL;DR

1- When using langmap, is it possible to replay the same characters as recorded by the macro instead of the same keys ?

2- Alternatively, when using keymap, is it possible on Arch Linux, ST terminal and Neovim to map chords such as CTRL + ALT + A (more specifically AltGr / right Alt) when using a qwerty layout ?

3- If nothing else, could a macro enable transparent switching between OS keymap upon entering and exiting insert / find mode ?


Full story

I have learnt VIM by using the game VIM adventures, this made me use the US layout for normal commands which seemed a reasonnable choice, albeit a bit daunting at first as I needed to switch mentally between two layouts for inputting text to qwerty for the commands.

I could actually get used to it, but configuring (neo)vim has never been fully satisfying as I am encountering limitations while improving my vim-fu.

My journey so far:

  • Solution 1 : remap every character combination, using noremap, nnoremap etc.

    • advantages : the mappings are generally simple to implement
    • disadvantages :
      • really tedious to maintain and expand when learning new commands
      • does not display the intended key in the status line triggered by the showcmd option :h showcmd
  • Solution 2 : langmap. :h langmap

    • Advantages

      • much easier to maintain, as simple correspondance list is required

      • displays the intended command key in the status line (translation is done by Vim)

      • by configuring some remap just for insert mode, I could keep the same behavior for insert mode and make shortcuts such as ctrl + W delete the word backward for instance.

      • For now, I mostly use command line mode for substitution so inputting commands in fr layout is not disturbing as I input words rather than commands.
    • Disadvantage
      • Macros are recorded with qwerty like-layout, but replays with my locale layout, ie fr-bepo. That make them unusable.
  • Solution 3 : keymap :h keymap

    • Advantages

      • With keymap, the OS keymap is set to Qwerty, so the responsability to change on locale keymap rests upon Vim when entering Insert and Search modes, and Vim is in charge of translating the keypresses from QWERTY to the target locale keymap.

      • From what I could test, this is perfect as every normal mode command is of course using the US layout natively and I really wish this could work BUT

    • Disadvantage

      • My locale keymap makes a really heavy use of the CTRL + ALT (aka AltGr) modifier which is also combined with SHIFT (Shift + AltGr). From what I’ve read, it is not possible to use this chording in Vim but may work with certain terminals in Neovim. I could not find my way through this, does anybody have succeded make this work ? I use Arch, btw ;-) and ST as Terminal.
  • Solution 4 : automatically switch OS keymap for normal mode

    • This could be the most simple solution, and the one I should have used before it seems.

:!setxkbmap us works well, but I could not yet find from the help the autocmd function that would enable this workflow :

  • upon starting Vim: switch to Qwerty layout

  • normal mode, search character (triggered by f/F/t/T): switch to fr-bepo layout

  • exit search: back to Qwerty

  • enters insert mode: fr-bepo

  • back to normal mode : Qwerty

  • exit Vim : back to fr-bepo

Thanks a lot for your reading !

1

Switching OS keymap automatically for normal mode seemed promising but I had not found a way to use f/F/t/T functions with it, now solution 1 works seemlessly even with the fantastic Coc plugin

Solution 1: using vim-xkbswitch

https://github.com/lyokha/vim-xkbswitch

requirements

  • xkb-switch
  • vim-xkb-switch

setup

for full functionality, you need to add correspondance information in :

  • xkb-switch plugin (main script file or associated file).

Natively, the plugin propose ru, de and us, the layouts used by the author.

  • (neo)vim itself.

To make f/F/t/T/ searches possible, the plugin uses the native vim keymap functionality. You can check if the layout you use already exist:

grep -r keymap_name /usr/share/*vim/

In my case, it didn't, so I created one from us-dv.vim and added it in /usr/share/nvim/keymap/fr-bepo.vim. It’s a simple tabular file, with qwerty layout characters in the first column and their equivalent for the layout you use in the second column.

Then, I added this in my init.vim / .vimrc

let g:XkbSwitchEnabled = 1
let g:XkbSwitchNLayout = 'us'
let g:XkbSwitchILayout = 'fr(bepo)'
set keymap=fr-bepo
set iminsert=0
set imsearch=0
let g:XkbSwitchAssistNKeymap = 1    " for commands r and f
let g:XkbSwitchAssistSKeymap = 1    " for search lines
let g:XkbSwitchKeymapNames = {'fr(bepo)' : 'fr-bepo'}

To be able to use fr-bepo for Command line as well, something which is not implemented in the vim-xkb-switch plugin, I also added these autocommand functions:

function! SwitchUsLayout()
    silent !xkb-switch -s us
endfunction

function! SwitchFrLayout()
    silent !xkb-switch -s fr\(bepo\)
endfunction

autocmd CmdlineLeave,VimEnter * call SwitchUsLayout()
autocmd CmdlineEnter,VimLeave * call SwitchFrLayout()

Solution 2: vanilla vim (and previous answer)

Here is a potential solution for Archlinux (maybe it works on other distros as well):

function! SetUsLayout()
    silent !setxkbmap us
endfunction

function! SetFrLayout()
    silent !setxkbmap -layout fr -variant bepo
endfunction

function! SetLayoutVimLeave()
    silent !setxkbmap -model pc104 -layout fr -variant bepo
endfunction

autocmd VimEnter * call SetUsLayout()
autocmd InsertLeave,CmdlineLeave * call SetUsLayout()
autocmd InsertEnter,CmdlineEnter * call SetFrLayout()
autocmd VimLeave * call SetLayoutVimLeave()

nnoremap f` f$
nnoremap f1 f"
nnoremap f2 f«
nnoremap f3 f»
nnoremap f4 f(
[…]

Limitations

  • The f/F/t/T nnoremap may not work for all letters however, on my config I had to comment out these :
"nnoremap f| fÇ
"nnoremap F| FÇ
"nnoremap t| tÇ
"nnoremap T| TÇ
  • Letters formed with Alt-Gr combinations will also not be accessible for these f/F/t/T functions.

  • I have to press the keymap two times for the first f/F/t/T search to make it active (as if it has to load the rule in memory).

Once that is done however, it works as fast as if it was native.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.