# Vim Input Method Switch Plugin English | [中文](./README.md) 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: ```text 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: ```text 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: ```lua 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`: ```lua require("hs.ipc") hs.ipc.cliInstall() ``` Reload Hammerspoon config, then verify: ```bash hs -c 'hs.keycodes.setLayout("ABC")' hs -c 'hs.keycodes.setMethod("Pinyin – Simplified")' ``` Both commands should return: ```text true ``` ### im-select fallback If `hs` is unavailable, the Vim plugin falls back to `im-select`: ```bash 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: ```bash mkdir -p ~/.vim/plugin cp vim-im-switch-select.vim ~/.vim/plugin/ ``` Or source it from `.vimrc`: ```vim source /path/to/vim-im-switch-select.vim ``` ### Native Vim configuration Defaults are for macOS ABC + Apple Simplified Pinyin: ```vim " 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 ```vim 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` 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: ```bash 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 ```bash vim -Nu NONE -n -es -S "/path/to/vim-im-switch-select.vim" -c 'qa' ``` ```bash 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: ```text /usr/local/bin/fcitx-remote ``` Default input methods: ```text English: com.apple.keylayout.ABC Chinese: auto-detect, fallback com.apple.inputmethod.SCIM.ITABC ``` ### Obsidian development ```bash 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. ```text 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