6.8 KiB
Vim Input Method Switch Plugin
English | 中文
This repository contains two related but currently separate implementations:
- Native Vim plugin:
vim-im-switch-select.vim, currently the stable macOS path. - Obsidian plugin:
main.ts, unchanged by the recent Hammerspoon work.
Native Vim plugin
The native Vim plugin is designed for macOS Vim and uses this stable strategy:
- Normal mode always switches to English
ABC. - Insert mode restores the last Chinese/English state used in the same Vim process.
- Hammerspoon is preferred via
hs.keycodes.setLayout()/hs.keycodes.setMethod(). im-selectis kept only as fallback.
Note: The Hammerspoon behavior described here applies only to the native Vim plugin
vim-im-switch-select.vim. It does not change the Obsidian plugin.
Mode behavior
| Vim state | Behavior |
|---|---|
| After Vim starts | Delayed switch to English ABC |
| Enter Insert | Restore the last Insert-mode Chinese/English state in this Vim process; first entry defaults to Chinese |
Leave Insert / Esc |
Save the current Insert-mode language state, then switch to English ABC |
Example:
First Insert -> Chinese
Manually switch to English in Insert -> Esc -> next Insert -> English
Manually switch back to Chinese in Insert -> Esc -> next Insert -> Chinese
Quit Vim and open again -> memory resets; first Insert defaults to Chinese
Why Hammerspoon
Using only im-select can leave Apple Pinyin in an inconsistent macOS state:
sourceID = com.apple.inputmethod.SCIM.ITABC
layout = ABC
method = Pinyin – Simplified
The menu bar may show Chinese input, but actual typing remains English.
Hammerspoon can directly set layout and method:
hs.keycodes.setLayout("ABC")
hs.keycodes.setMethod("Pinyin – Simplified")
This avoids relying only on the input source ID.
Hammerspoon setup
Install and run Hammerspoon. Enable IPC in ~/.hammerspoon/init.lua:
require("hs.ipc")
hs.ipc.cliInstall()
Reload Hammerspoon config, then verify:
hs -c 'hs.keycodes.setLayout("ABC")'
hs -c 'hs.keycodes.setMethod("Pinyin – Simplified")'
Both commands should return:
true
im-select fallback
If hs is unavailable, the Vim plugin falls back to im-select:
im-select
im-select com.apple.keylayout.ABC
im-select com.apple.inputmethod.SCIM.ITABC
Common input source IDs:
| Input method | ID |
|---|---|
| ABC | com.apple.keylayout.ABC |
| Apple Simplified Pinyin | com.apple.inputmethod.SCIM.ITABC |
Install native Vim plugin
Copy the plugin to Vim's plugin directory:
mkdir -p ~/.vim/plugin
cp vim-im-switch-select.vim ~/.vim/plugin/
Or source it from .vimrc:
source /path/to/vim-im-switch-select.vim
Native Vim configuration
Defaults are for macOS ABC + Apple Simplified Pinyin:
" Hammerspoon path: English keyboard layout name
let g:imselect_hs_english_layout = 'ABC'
" Hammerspoon path: Chinese input method name
let g:imselect_hs_chinese_method = 'Pinyin – Simplified'
" im-select fallback: English input source ID
let g:imselect_english_im = 'com.apple.keylayout.ABC'
" im-select fallback: Chinese input source ID
let g:imselect_chinese_im = 'com.apple.inputmethod.SCIM.ITABC'
" Delay before restoring Insert state, default 80ms
let g:imselect_restore_delay = 80
" Confirm target state after restore, default 200ms
let g:imselect_confirm_delay = 200
Native Vim implementation notes
InsertLeavePre -> Save the last Insert-mode Chinese/English state
InsertLeave -> Switch to English ABC
InsertEnter -> Delayed restore of the last Insert-mode state
VimEnter -> Delayed switch to English ABC on startup
Important details:
InsertLeavePremust save state beforeInsertLeaveswitches to English.- Timer callbacks check the target state so fast
i<Esc>does not switch Normal mode back to Chinese. - Hammerspoon is the primary path;
im-selectis fallback only. - State memory is script-local and only valid within the current Vim process.
Native Vim manual test
-
Open Vim:
vim test-im-switch.txt -
First
i: should switch to Chinese. -
Type Chinese, press
Esc: should switch to EnglishABC. -
Press
iagain: should restore Chinese. -
In Insert, manually switch to English, type English, press
Esc. -
Press
iagain: should restore English. -
In Insert, manually switch back to Chinese, press
Esc, theni: should restore Chinese. -
Quit and reopen Vim: first Insert defaults to Chinese; this is a known limitation.
Native Vim verification
vim -Nu NONE -n -es -S "/path/to/vim-im-switch-select.vim" -c 'qa'
hs -c 'hs.keycodes.setLayout("ABC")'
hs -c 'hs.keycodes.setMethod("Pinyin – Simplified")'
Obsidian plugin
The Obsidian plugin remains in this repository and is implemented by main.ts.
Current Obsidian plugin behavior is unchanged:
- Uses
fcitx-remoteto query and switch input methods. - Listens to Obsidian / CodeMirror Vim mode changes.
- Normal / Visual mode switches to English.
- Insert / Replace mode restores the last Insert-mode state.
- Settings still use the plugin settings page and the configured
fcitx-remotepaths / input method IDs.
Obsidian requirements
The plugin expects a working fcitx-remote command for the current platform.
Default macOS path:
/usr/local/bin/fcitx-remote
Default input methods:
English: com.apple.keylayout.ABC
Chinese: auto-detect, fallback com.apple.inputmethod.SCIM.ITABC
Obsidian development
npm install
npm run build
Known limitations
Native Vim Insert memory is not persisted across Vim processes
The native Vim plugin only remembers the last Insert-mode state within the current Vim process.
Switch to English in Insert -> Esc -> next Insert -> English
Quit Vim -> reopen Vim -> first Insert defaults to Chinese
This is intentional for now; no file-based persistence is implemented.
Native Vim depends on Hammerspoon for the stable macOS path
The stable path requires:
- Hammerspoon running
hsCLI availablehs.ipcenabled- Input method name matching
Pinyin – Simplified
If Hammerspoon is unavailable, the plugin falls back to im-select, but fallback cannot fully fix Apple Pinyin layout/method inconsistency.
No simulated CapsLock / Ctrl-Space
The native Vim plugin does not simulate Caps Lock, Ctrl-Space, Shift, or other system shortcuts. Those keys may be received by Vim and cause side effects.
Main files
| File | Description |
|---|---|
vim-im-switch-select.vim |
Current stable native Vim plugin |
main.ts |
Obsidian plugin entry |
README.md |
Chinese documentation |
README_en.md |
English documentation |
CHANGELOG.md / CHANGELOG_en.md |
Change history |
RELEASE.md |
Release notes |
License
MIT License