Files
vim-im-switch/README_en.md
2026-07-15 11:10:25 +08:00

6.8 KiB
Raw Blame History

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-select is 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:

  • InsertLeavePre must save state before InsertLeave switches 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-select is fallback only.
  • State memory is script-local and only valid within the current Vim process.

Native Vim manual test

  1. Open Vim:

    vim test-im-switch.txt
    
  2. First i: should switch to Chinese.

  3. Type Chinese, press Esc: should switch to English ABC.

  4. Press i again: should restore Chinese.

  5. In Insert, manually switch to English, type English, press Esc.

  6. Press i again: should restore English.

  7. In Insert, manually switch back to Chinese, press Esc, then i: should restore Chinese.

  8. 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-remote to 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-remote paths / 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
  • hs CLI available
  • hs.ipc enabled
  • 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