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

258 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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<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:
```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