Native & OS 输入法管理包『sis』使用交流

你这个错误不是和之前的错误一样吗,按照之前的方式重新解决一下看看

重新清空doom的所有包,重新安裝之後,問題解決了,可以正常使用。謝謝樓上各位大佬。

大家在使用 sis 时遇没遇到这样的问题:sis 运行一段时间后,切换到中文,输入中文,按 Enter 上词后,sis 就自动切换回英文。

可能和 inline chinese mode有关?

就是英文中在线插入中文,通过空格和回车触发,而不需要显式切换输入法的功能。

我没用 inline chinese mode,我没有设置这个选项 sis-inline-with-other。 这个问题是使用过程中出现的,也不知道什么时间会出现,我现在遇到就重启下 emacs 就好了。但感觉还是有点烦,不知道怎么定位排查。

这是我的配置:

(use-package sis
  :demand
  :config
  (add-to-list 'sis-prefix-override-keys "M-s")
  (add-to-list 'sis-prefix-override-keys "M-g")
  (when IS-MAC
    (sis-ism-lazyman-config
     "com.apple.keylayout.ABC"
     "com.apple.inputmethod.SCIM.Shuangpin"))
  (sis-global-inline-mode +1)
  (sis-global-respect-mode +1))

请教一下,在中文中插入英文,但在输入完英文后需要紧跟一个全角标点,如果通过 SPC 退出英文 inline 的话会导致英文和标点之间有一个空格。这个大佬们是怎么处理的?

sis-inline-tighten-tail-rule 默认是 'one,设置这个参数为一个你自己提供的函数即可:

(defvar sis-inline-tighten-tail-rule 'one
  "Rule to delete tail spaces.

Possible values:
0: don't delete space
1: delete 1 space if exists
\\='zero: always ensure no space
\\='one: always ensure one space
custom function: the cursor will be moved to the end of the inline region, and
                   the function will be called with an argument which is the
                   beginning of the tailing whitespaces in the inline region.")

非常感谢!我让 Gemini 帮我实现了一个:

;; 中文标点列表,方便管理
(defvar +sis-chinese-punctuation-list
  '(?, ?。 ?? ?! ?; ?: ?“ ?‘ ?’ ?” ?( ?) ?《 ?》 ?、)
  "A list of Chinese punctuations for sis inline mode correction.")

(defun +sis-delete-space-before-punc-on-insert ()
  "When a Chinese punctuation is inserted, if it's preceded by
'ASCII_CHAR + SPACE', delete the space.
This function should be added to `post-self-insert-hook'."
  ;; 获取刚刚插入的字符
  (let ((punc (char-before)))
    ;; 设定触发条件,必须同时满足:
    ;; 1. 刚刚插入的字符是在我们定义的中文标点列表里。
    ;; 2. 缓冲区里的位置要大于2,防止在文件开头出错。
    ;; 3. 标点的前一个字符是空格(字符编码 32)。
    ;; 4. 空格的前一个字符是 ASCII 字符(编码小于 128),这能大概率确定是英文。
    (when (and (memq punc +sis-chinese-punctuation-list)
               (> (point) 2)
               (eq (char-before (- (point) 1)) ?\s)
               (< (char-before (- (point) 2)) 128))
      ;; 如果条件全部满足,就执行删除操作
      (save-excursion
        ;; `save-excursion` 保存当前光标位置,在执行完内部代码后恢复
        (backward-char 2) ; 从标点后移动到空格前
        (delete-char 1))))) ; 删除光标后的一个字符(也就是那个空格)

;; 将我们的函数添加到 `post-self-insert-hook`
;; 这个 hook 会在用户每次输入一个字符后运行
(add-hook 'post-self-insert-hook #'+sis-delete-space-before-punc-on-insert)

根据我最近的体验,在windows下 w32-get-ime-open-status 能正常返回t或者nil了。
我的emacs版本:通过scoop安装的kiennq的emacs-k (scoop地址对应emacs编译文件地址
我的小狼毫版本:Github Action自动编译的最新版本 4397056
我的sis相关配置:

(use-package sis
  :demand t
  :config
  (when (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)))))

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

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

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

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

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

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

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

[2026-04-13 周一]:推荐启用Windows 设置的「允许我为每个应用窗口使用不同的输入法」功能。

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

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

2 个赞

使用了你这个设置确认可以解决问题了。 感觉可以贡献到 sis.el 上游。 @goumao

1 个赞

我也写了个改动,还在用看看有没有问题,主要是对respect-mode prefix handling and buffer restore tracking 两方面的修改。

(add-function :after after-focus-change-function (lambda () (sis--get)))

这样可以在切回emacs的时候保持输入法状态和sis状态的同步