UP | HOME

▼ 本文更新于 [2026-04-13 周一 16:46]

emacs-配置windows下的sis


sissmart-input-source的缩写。一句话总结来说,就是根据emacs内部状态,自动操作输入法在 englishother 状态中切换。

根据我最近的体验,在windows下的sis已经基本能正常使用了, w32-get-ime-open-status 也能正常工作,根据输入法开关状态正确返回 t 或者 nil

1. 相关软件版本

我的emacs版本:通过scoop安装的kiennq的emacs-k (scoop地址对应emacs编译文件地址
我的小狼毫版本:Github Action自动编译的最新版本 4397056

2. sis配置

我的sis配置:

(use-package sis
  :demand t
  :config
  ;; 设置Windows
  (cond ((eq system-type 'windows-nt)
         (defun sis-switch ()
           "Switch input source between \\='english and \\='other."
           (interactive)
           (setq sis--for-buffer-locked nil)
           (if (w32-get-ime-open-status)
               (sis--set-english)
             (sis--set-other))))
        ;; 设置Emacs-plus with input patch
        ((eq system-type 'darwin) (sis-ism-lazyman-config "com.apple.keylayout.UnicodeHexInput" "im.rime.inputmethod.Squirrel.Hans" 'emp)))
  ;; 启用全局光标颜色
  (sis-global-cursor-color-mode t)
  ;;设置sis的状态光标颜色
  (setq sis-other-cursor-color (modus-themes-get-color-value 'fg-alt))
  (setq sis-default-cursor-color (modus-themes-get-color-value 'border))
  (set-cursor-color "#ffffff") 
  ;; enable the /respect/ mode
  ;; 启用全局respect模式
  (sis-global-respect-mode t)
  ;; enable the /context/ mode for all buffers
  (sis-global-context-mode t)
  ;; enable the /inline english/ mode for all buffers
  (sis-global-inline-mode t)
  ;;自动设置为英文的函数
  (setq sis-respect-go-english-triggers
    (list #'org-agenda))
  ;; 在切换窗口后获取并更新一次输入法状态
  (add-function :after after-focus-change-function (lambda () (sis--get)))
  :hook
  (org-capture-mode . sis-set-other)
  (atomic-chrome-edit-mode . sis-set-other)
  (beancount-mode . sis-set-other)
  (xeft-mode . sis-set-other)
  :bind
  ("C-\\" . sis-switch))

我的小狼毫 default.custom.yaml 配置:

patch:
  ascii_composer:
    good_old_caps_lock: true  # true | false
    switch_key:
      Caps_Lock: clear      # commit_code | commit_text | clear
      Shift_L: noop  # commit_code | commit_text | inline_ascii | clear | noop
      Shift_R: noop  # commit_code | commit_text | inline_ascii | clear | noop
      Control_L: noop       # commit_code | commit_text | inline_ascii | clear | noop
      Control_R: noop       # commit_code | commit_text | inline_ascii | clear | noop

2.1. 关于重新定义 sis-switch 的说明

使用 sis 时,其实存在两个状态。一个是 sis--current 变量存储的当前输入状态,在原始的 sis-switch 函数中,是通过 (eq sis--current 'english) 来检测的;另一个是我们全局输入法的状态,可以通过 (w32-get-ime-open-status) 来获取。

小狼毫中按键的 commit_code 功能,并非我们 ctrl+space 按键的开关功能,无法触发 sis 的自动检测(参见相关issue),有可能造成输入法的状态改变之后,内部存储的状态依旧没变的错位情况。

简单总结:sis 在 Windows 下依赖 w32-get-ime-open-status 实时轮询输入法开关状态。小狼毫的 inline_asciicommit_code 仅仅是在 Rime 引擎内部切换了码表输出,并未改变 Windows IME API 层面的开启/关闭状态,因此 Emacs 无法感知到这种切换。

所以这里将 shift 设定为 noop ,同时修改了 sis-switch 的定义,以尽可能避免错位。

注意,禁用 Shift 切换后,我在 Emacs 中的日常中英文切换完全依赖于 C-\ (绑定到 sis-switch ),而在 Emacs 外部,我依赖系统的 Ctrl+Space 来开关输入法。

注: Windows 设置的「允许我为每个应用窗口使用不同的输入法」功能与此无关,启用后是可以为不同应用窗口使用不同的输入法,但 windows 默认就已经在不同窗口中保存各自的某一输入法开启/关闭状态了。

:推荐启用Windows 设置的「允许我为每个应用窗口使用不同的输入法」功能。

如果关闭此功能,假设在Emacs中小狼毫为启用的中文状态,则在你切换到其他应用并Ctrl+Space关闭小狼毫时,此时切换回Emacs,则sis会保持中文,但小狼毫会跟随关闭为英文,造成状态错位。

如果开启此功能(注意如果是中途开启,需要重启现有emacs进程),则会在不同窗口间独立保持输入法开启关闭状态,在上述场景中切换回Emacs时小狼毫会自动变回中文。

© Published by Emacs 31.0.50 (Org mode 10.0-pre) | RSS Comment