(重新设计)中英文混打:OS输入法管理包 smart-input-source

请教各位大佬,按照github的配置,发现按ESC退出insert模式,进入normal模式,输入法不会自动切换为英文,怎么解决?

使用test.e测试:emacs -Q -l .emacs.d/test.el

 (require 'package)
  (setq package-archives '(("gnu"    . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
    		   ("nongnu" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/nongnu/")
    		   ("melpa"  . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")))

;; (setq package-archives '(("myelpa" . "~/myelpa/")))
  (package-initialize) ;; You might already have this line  

  (use-package evil
    :ensure t
    :defer 2
    :init
    (setq evil-want-C-i-jump nil)
    :config
    (evil-mode 1)
    )

(use-package sis
  :ensure t
  :config
  (sis-ism-lazyman-config "1" "2" 'fcitx5)
  ;; enable the /cursor color/ mode
  (sis-global-cursor-color-mode t)
  ;; enable the /respect/ mode
  (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)
  )

让 sis 在 evil 之后加载尼

感谢,已经解决了。

  (use-package evil
    :ensure t
    :defer 2
    :init
    (setq evil-want-C-i-jump nil)
    :config
    (evil-mode 1)
    )

(use-package sis
  :ensure t
  :after evil
  :config
  (sis-ism-lazyman-config "1" "2" 'fcitx5)
  ;; enable the /cursor color/ mode
  (sis-global-cursor-color-mode t)
  ;; enable the /respect/ mode
  (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)
  )

@DogLooksGood 狗哥的这个仓库都看不到了,你现在还在用 sis 吗,可以分享下配置吗?

分享一下我的配置,sis 与 meow 相关的配置我只用这两句:

  (add-hook 'meow-insert-exit-hook #'sis-set-english)
  (add-to-list 'sis-context-hooks 'meow-insert-enter-hook)
3 个赞

这个问题还有坛友遇到过吗?我最近频繁触发,然后 debug-on-quit 也没看出什么名堂,想问问有没有什么解决办法 :joy:

我在 minibuf 下面有时候需要输入中文

(dolist (trigger '(aider-code-change aider-region-refactor aider-ask-question
				       aider-architect-discussion
				       aider-general-command aider-help))
    (add-to-list 'sis-respect-minibuffer-triggers
                 (cons trigger (lambda () 'other))))

我配置了一下,一开始进入 minibuffer 下面是自动切换成了中文,但是一旦我输入一个词语结束以后,就又自动切换成了英文,然后我想继续输入 中文 还得手动切换一下输入法,然后输入完了以后又自动切换会英文,有办法让这种情况下不要自动切换回 英文 吗?

有空我给加到README中

有空我研究一下,好久没碰了

首先再次感谢作者如此杰出的包,在 Mac 下配合 Emacs-mac-port 使用非常舒服! :laughing:

同时,我发现,开启 sis-global-respect-mode 后,由于 sis--prefix-override-map-enable 直接被设置为了 t,所以无论当前输入法是不是中文,emulation-mode-map-alists 中的 keymap 都会生效(往往是覆盖掉了 "C-c" "C-x" "C-h" 这些按键,被绑定到 sis--prefix-override-handler)。

但是只有在中文模式下,我们才需要这些键绑定(从而在我们输入按键序列时,提前恢复英文输入状态),英文状态下是不需要的。

大多数情况这并没有什么问题,但是如果你在录制宏,那么如果键入上面的快捷键,那么,这个按键会被记录两次(比如我键入 C-c C-l,但实际宏却记录了 C-c C-c C-l),这就在执行这个键盘宏时出现问题。不知道有没有什么优美的解法?

而目前我通过:

(define-advice sis--auto-refresh-timer-function
      (:around (orig) toggle-override-map)
    (funcall orig)
    (pcase sis--current
      ('english
       (setq sis--prefix-override-map-enable nil))
      ('other
       (setq sis--prefix-override-map-enable t))))

来绕过这个问题。因为我目前开启了 sis-auto-refresh-mode,所以利用它的 timer 来检测当前输入法状态,并开关 sis--prefix-override-map-enable,从而只在中文输入法时才绑定这些按键。

只有在中文模式下,我们才需要这些键绑定(从而在我们输入按键序列时,提前恢复英文输入状态)

这个key insight非常好,可以做到sis里面去。

1 个赞

我才发现,原来之前有人在 Github 提过这个问题:

PS:其实我之前也攒了一些小改进,在本坛存个档,或许有遇到类似问题的坛友:

1、避免在 minibuffer 中激活 inline

(define-advice sis--inline-check-to-activate
    (:around (orig) no-minibuffer)
  (unless (minibufferp)
    (funcall orig)))

否则,至少在我使用 vertico 时,如果激活了 inline,那么增加的 inline overlay 会使得候选项为空。

2、支持 universal-argument 的自动切换英文输入法(就如同这些键被绑定了 sis--prefix-override-handler

(define-advice universal-argument
    (:around (orig) sis)
  (funcall orig)
  (when sis-global-respect-mode
    (setq sis--prefix-handle-stage 'prefix)
    (sis--respect-pre-command-handler)))
(define-advice universal-argument-more
    (:around (orig &rest arg) sis)
  (apply orig arg)
  (when sis-global-respect-mode
    (setq sis--prefix-handle-stage 'prefix)
    (sis--respect-pre-command-handler)))
(define-advice negative-argument
    (:around (orig &rest arg) sis)
  (apply orig arg)
  (when sis-global-respect-mode
    (setq sis--prefix-handle-stage 'prefix)
    (sis--respect-pre-command-handler)))
(define-advice `digit-argument`
    (:around (orig &rest arg) sis)
  (apply orig arg)
  (when sis-global-respect-mode
    (setq sis--prefix-handle-stage 'prefix)
    (sis--respect-pre-command-handler)))

为什么不将这些键加入 sis-prefix-override-keys 呢?因为这些键太多了,比如在 Doom Emacs 下,evil normal state 直接敲击键盘上的数字键,就都是 digit-argument 命令。

3、如果你想手动进入 inline 模式(不想「输入空格」供其检测符合断言才进入、之后再手动删去)

(defun sis-inline-mode-force ()
  (interactive)
  (when (eq sis--for-buffer 'other)
    (setq sis--prefix-handle-stage 'normal)
    (add-transient-hook! 'post-self-insert-hook
      (when (eq last-command 'sis-inline-mode-force)
        (sis--inline-activate 'english (1- (point)))))))

这里的 add-transient-hook! 是 Doom Emacs 中的函数,是为了增加一个只运行一次的 hook/advice。如果不是 Doom 想用的话,得去抄一下这个宏的定义。

4、Doom Emacs 下,不同 evil state 光标颜色不同,让 sis 考虑这一点

(defun my/sis--set-cursor-color-advice (color)
  (pcase sis--current
    ('english
     (cond ((or evil-insert-state-minor-mode evil-normal-state-minor-mode) (list (get 'cursor 'evil-normal-color)))
           (evil-emacs-state-minor-mode (list (get 'cursor 'evil-emacs-color)))
           (t (list sis-default-cursor-color))))
    ('other
     (list sis-other-cursor-color))
    (_
     color)))
(advice-add 'sis--set-cursor-color-advice :override #'my/sis--set-cursor-color-advice)

5、利用 idle 实时切换输入法状态(比如,在 evil insert/emacs state 下,在英文内容和中文内容之间移动光标,就可以自动切换输入法)

(defvar my/idle-command-for-sis-timer nil)
(defun my/idle-command-for-sis ()
  (when (and (or evil-insert-state-minor-mode evil-emacs-state-minor-mode)
             (not (and (boundp 'evil-mc-mode) evil-mc-mode))
             (not (overlayp sis--inline-overlay))
             (not (eq sis--prefix-handle-stage 'sequence))
             (not (memq real-last-command '(sis-inline-mode-force sis--inline-ret-check-to-deactivate)))
             (not (equal last-input-event '(ns-put-working-text))))
    (sis-context)))
(setq my/idle-command-for-sis-timer
      (run-with-idle-timer 0.2 t #'my/idle-command-for-sis))
;; (when my/idle-command-for-sis-timer
;;   (cancel-timer my/idle-command-for-sis-timer))

我给整理一下放到readme上最好,
能够解决更多的用户问题。

其实我在emacs上基本不写中文,
甚至也基本不写代码了。
这个包有很多需要改进的地方,
就一直拖着没动。

1 个赞

请教一下,windows下sis能够自动调用小狼毫的内置中英文切换,mac用鼠须管不行,请问mac上有没有办法实现在鼠须管内部进行中英文切换?

如果不想用 macism(macos)可以用这个 patch 来切换输入法(sis 兼容这个方法,也可以自己设置 F13 绑定到 shift 来切换).emacs.d/patches/ns-mac-input-source.patch at main · LuciusChen/.emacs.d · GitHub

使用坛友 @LuciusChen 制作的补丁,安装Emacs-plus

编辑:原来是切换输入法内部状态,这个确实没找到方法。

因为找不到在鼠须管内部进行中英文切换的方法,我在macos里,英文直接系统自带的,中文用鼠须管。

https://ringawho.github.io/emacs-input-method.html

我是自己 patch 编译鼠须管加了这个功能,不太熟悉 macos 这边,方法可能不是很好,感兴趣可以看看

1 个赞

感谢大佬,不过编译patch对我来说技术难度太大了 :sweat_smile:而且我发现小狼毫的切换也没有我想象中的美好,今天测试了一天,发现SIS在windows上的切换好像只是给小狼毫发送了个切换指令,经常造成中英文状态反转,比如在英文状态下退出insert模式,结果在normal下就变成了中文

你要用小狼毫最新的 Nightly build 版本就不会有问题了。

我也是这样。rime里面带英文输入法没有必要。