前提

简单描述下自动切换的行为:

nvim记住最近一次插入模式时的输入法(可能是英文,也可能是中文) esc回到正常模式时,插件自动将系统输入法切换到英文状态 重新回到插入模式时, nvim自动切回上次插入模式时的输入法.

环境: ibus + ibus-rime + neovim

当前我的rime配置是有自带ascii mode的,也就是配置了输入中文时简单地按下shift就会切换到英文输入模式。

然而这个ascii mode 外部是无法感知的,也就是只有rime 自己知道,ibus是不知道的。

之前用fcitx 是没有这个问题的,fcitx-remote 配合vim插件 fcitx.vim可以非常方便地进行切换。

当前大部分对于ibus控制的插件实现都是无法直接控制到rime的。

因此,我当前的rime配置需要做一些调整。

如果使用的是mac或windows版的rime, 那么,其实前端这边是有支持vim_mode的, 见https://github.com/rime/squirrel/issues/124https://github.com/rime/weasel/issues/12 但是这个只是在前端, librime是没有这个选项的。 见https://github.com/rime/librime/issues/295

由于我的主要使用场景是Linux, 因此rime自带的vim_mode方案不可用。

另外,通过配置rime使用esc来toggle ascii_mode的方案也不太好:

key_binder/bindings:
  - { when: always, accept: Escape, toggle: ascii_mode}

这样就可以使用 Esc 键切换为英文模式,但是这样有一个弊端,必须得先按一次 Esc 切换为英文后,再按一次 Esc 切换为普通模式

我当前的rime配置是:

# @see https://github.com/rime/home/wiki/CustomizationGuide
customization:
  generator: "Rime::SwitcherSettings"
  modified_time: "Sat Dec 31 12:11:20 2016"
patch:
  schema_list:
    - {schema: wubi86}
    - {schema: wubi_pinyin}
  "key_binder/bindings":
    - { when: composing, accept: Return, send: Escape }
    - { when: has_menu, accept: semicolon, send: 2 }
    - { when: has_menu, accept: apostrophe, send: 3 }
  "ascii_composer: good_old_caps_lock": true
  "ascii_composer/switch_key":
    Caps_Lock: commit_code
    Control_L: noop
    Control_R: noop
    Shift_L: commit_code
    Shift_R: commit_code
  "switcher/hotkeys":  # 這個列表裏每項定義一個快捷鍵,使哪個都中
    - "Control+grave"  # 你看寫法並不是 Ctrl+` 而是與 IBus 一致的表示法
    #- F4 # disable default F4 map, leave it for Neovim
  switches:
    - name: ascii_mode
      reset: 1
      states: [ 中文, 西文 ]

也就是,在输入时,随便输入左/右shift 或 caps lock键,都可以在中文输入模式和ascii 输入模式之间快速切换。 这期间对于系统或ibus来说,是没有切换输入法的。

如果要在Vim里面控制这种切换,那么,只能控制到ibus层面, 要做哪些改变呢?

切换rime的ascii switch 默认状态

reset1时的问题: 比如:vim插入模式:rime中文输入 -> vim普通模式(输入法从rime切成了en)-> 再切回插入模式,此时 输入法还是英文,我们得再按一次shift切换成中文。

因此, ascii_mode reset1 时适合将rime作为默认输入法使用。

reset1 修改成0, 即可让rime从别的输入法切回时,总是中文输入状态,而不是总是英文(ascii_mode)

同时,要从rime切换到英文输入法,我们要确保有一个英文输入法添加到ibus.

可以通过ibus-setup检查你的配置.

因此, ascii_mode reset0 时适合将rime作为第二输入法使用,首选输入法应该是英文。 要记得在GNOME3系统配置里的Input Source 那里,将English(US)排到rime前面来。 毕竟,我们敲代码比较多,英文在任何时候应该是首选的。

customization:
  generator: "Rime::SwitcherSettings"
  modified_time: "Sat Dec 31 12:11:20 2016"
patch:
  schema_list:
    - {schema: wubi86}
    - {schema: wubi_pinyin}
  "key_binder/bindings":
    - { when: composing, accept: Return, send: Escape }
    - { when: has_menu, accept: semicolon, send: 2 }
    - { when: has_menu, accept: apostrophe, send: 3 }
  "ascii_composer: good_old_caps_lock": true
  "ascii_composer/switch_key":
    Caps_Lock: commit_code
    Control_L: noop
    Control_R: noop
    Shift_L: commit_code
    Shift_R: commit_code
  "switcher/hotkeys":  # 這個列表裏每項定義一個快捷鍵,使哪個都中
    - "Control+grave"  # 你看寫法並不是 Ctrl+` 而是與 IBus 一致的表示法
    #- F4 # disable default F4 map, leave it for Neovim
  switches:
    - name: ascii_mode
      reset: 0
      states: [ 中文, 西文 ]

gnome3 默认的输入法切换快捷键是: super + space, 短按可快捷切换,长按还能在屏正中overlay显示切换的输入法。

安装配置合适的nvim支持插件

vim-xkbswitch

vim-xkbswitch

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

好处: 跨平台支持 Unix: http://github.com/ierton/xkb-switch https://github.com/lyokha/g3kb-switch) 原作者新项目 lyokha/g3kb-switch 解决了 Linux(GNOME) 下的切换

Win: http://github.com/DeXP/xkb-switch-win

OSX: http://github.com/myshov/xkbswitch-macosxhttp://github.com/vovkasm/input-source-switcher

vim-ibus

vim-ibus

https://github.com/h-youhei/vim-ibus:

实际上它是直接使用的ibus engine来切换输入法, 在 GNOME 3 上切换输入法后,右上角状态栏图标并不会自动更新, fork 版本 zhmars/vim-ibus简单修复了这个问题

使用ibus list-engine可以列出当前可用的engine, 但是实际上我们只会切到一个,那就是xkb:us::eng

vim-ibus-sw

vim-ibus-sw

https://github.com/kevinhwang91/vim-ibus-sw

这个其实和h-youhei/vim-ibus 类似,只是更加智能,在GNOME3环境下,它会自动使用dbus通知的方式, 这样可以解决图片没有变的问题,在非GNOME3环境下,它同样会回退到 ibus engine 命令的方式。

由于老灯主要使用场景为Linux, 因此最终选择了 kevinhwang91/vim-ibus-sw

参考文档

vim可不可以实现在在normal模式或者visual模式下自动改输入法为英文呢 https://www.zhihu.com/question/25744174

vim 中使用 esc 切换英文输入