在支持模态文本编辑的编辑器,比如 vim, helix, vscode的vim模式等,在使用 esc键后会进入默认的普通模式(normal mode),这个时候的操作基本是在英文输入状态下完成操作。再使用 ime 中文输入法的情况下,我们使用esc后必须切换回英文输入,无疑对模态操作多了一次步骤。这里我们可以在使用esc时同时切换输入法来解决该问题。

大致的解决办法是:

  1. 利用脚本以及 cli 命令 来切换系统输入法
  2. 编辑器插入模式,为 esc 配置命令切换为回英文,并记录当前的输入法
  3. 在编辑进入插入模式的时候,读取上次插入模式下的输入法并切换

下面介绍 Linux ,osx 下的切换输入法方法。

Linux gnome 环境 ibus

IBus 是一款输入法框架。具体使用可以参考 wiki-ibus

ibus 提供了工具 ibus engine 查看当前的输入法标识,使用 ibus engine rime 切换输入法为rime。 但在 gnome 4 版本中,该命令无法和gnome-shell中的系统状态的输入法保持一致。这个时候我们使用一款 gnome-shell-ibus-switcher 插件来解决该问题。 ibus-switcher 为 gnome-shell 42 版本后 提供了利用 d-bus 切换输入法的方式,从而切换系统输入法

ibus-switcher 提供

  • 获取当前输入法 org.gnome.Shell.Extensions.IbusSwitcher.CurrentSource
  • 切换当前输入法 org.gnome.Shell.Extensions.IbusSwitcher.SwitchSource

获取当前输入法

dbus-send --session --type=method_call --print-reply=literal --dest=org.gnome.Shell /org/gnome/Shell/Extensions/IbusSwitcher org.gnome.Shell.Extensions.IbusSwitcher.CurrentSource

因为我使用了 ibus-rime 的小鹤输入法,所以获取到的值是 1|小 (这里的数字是输入法的序号,|为分隔符,后面跟的是输入法的名称首字母), 1|A 就是 ibus-rime 的英文输入。这个具体看自己的配置情况。

设定输入法

比如切换输入法到英文

dbus-send --session --type=method_call --print-reply=literal --dest=org.gnome.Shell /org/gnome/Shell/Extensions/IbusSwitcher org.gnome.Shell.Extensions.IbusSwitcher.SwitchSource uint32:1 string:A

Mac 平台

macism 提供了 mac 平台下输入法切换工具。

通过 brew 安装

brew tap laishulu/macism
brew install macism

获取当前输入法

macism
# 这里使用的rime获得是
im.rime.inputmethod.Squirrel.Hans 

同样可以获得

  • 默认的英文为:com.apple.keylayout.ABC
  • rime 输入法为: im.rime.inputmethod.Squirrel.Hans

设定输入法

macims com.apple.keylayout.ABC

window 平台

im-select 提供了 window 平台的输入法切换工具。

脚本

查看 github.com/erasin/helix-config 中 ime-switch bash 脚本。

脚本接收参数 0/1, 0 表示切换为英文输入法,可省略该参数,1 表示恢复上次插入模式下记录的输入法。

# 设定英文,并记录当前的输入法
bash ~/.config/helix/shells/ime-switch

# 读取记录的输入法名称,设定输入法
bash ~/.config/helix/shells/ime-switch 1

helix

helix 配置文件,打开 hx 后输入 :config-open, 或者直接编辑 ~/.config/helix/config.toml

[keys.normal]
# 输入法切换
"esc" = ["normal_mode", ":pipe-to bash ~/.config/helix/shells/ime-switch"]
# 插入模式,恢复输入法
i = ["insert_mode", ":pipe-to bash ~/.config/helix/shells/ime-switch 1"]
I = [ "insert_at_line_start", ":pipe-to bash ~/.config/helix/shells/ime-switch 1" ]
# use `li` or remap `after insert`
a = [ "move_char_right", "insert_mode", ":pipe-to bash ~/.config/helix/shells/ime-switch 1" ]
A = ["insert_at_line_end", ":pipe-to bash ~/.config/helix/shells/ime-switch 1"]
o = ["open_below", ":pipe-to bash ~/.config/helix/shells/ime-switch 1"]
O = ["open_above", ":pipe-to bash ~/.config/helix/shells/ime-switch 1"]

[keys.insert]
"esc" = ["normal_mode", ":pipe-to bash ~/.config/helix/shells/ime-switch"]

vim / neovim

设定 esc 的 keymap 执行脚本即可。

vscode vim 插件

vscode vim 提供了 Input Method

"vim.autoSwitchInputMethod.enable": true,
"vim.autoSwitchInputMethod.defaultIM": "xkb:us::eng",
"vim.autoSwitchInputMethod.obtainIMCmd": "/usr/bin/ibus engine",
"vim.autoSwitchInputMethod.switchIMCmd": "/usr/bin/ibus engine {im}"

vim neovim 插件

neovim 插件 nvim-ibus-sw.