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

跟你的用法是一样的,你启用inline-mode之后,
在输入中文时,
输入空格则自动进入英文编辑模式,
之后通过空格或者回车退出英文编辑。

变量是控制如何退出英文编辑,及删除首尾空格。

默认的规则下,可以这么用:

用法1:
中文后面跟两个空格编辑英文,并将英文编辑区着色显示
英文中间可以有空格,
英文输入完毕后,再输入双空格,sis结束英文编辑,回到中文状态,
sis会删除英文区首位各一个空格,此时英文两端各保留一个空格和中文隔开。

即:你要获得中文 some english text 中文
那么就输入: 中文<spc><spc>some english text<spc><spc>中文
(<spc>是空格键,<ret>是回车键)

用法2:
中文后面跟一个空格编辑英文,并将英文编辑区着色显示,
英文中间可以有空格,
英文结束后,输入一个空格,再回车,sis结束英文编辑,回到中文状态
sis会删除英文区首尾各一个空格,此时英文和中文之间无空格隔开。

即:你要获得中文some english text中文
那么就输入:中文<spc>some english text<spc><ret>中文
(<spc>是空格键,<ret>是回车键)

用法3: 你不想要支持英文中带空格,即:中文 some english text 中文
而只想要支持单个英文单词,即:中文 english 中文
那么在下列的配置下,输入可以更简单:

(setq sis-inline-single-space-close t)
(setq sis-inline-tighten-head-rule 0)
(setq sis-inline-tighten-tail-rule 0)

直接按最终结果原样输入:中文<spc>english<spc>中文即可

用法4: 你不想要支持英文中带空格,即:中文some english text中文
而只想要支持单个英文单词,即:中文english中文
那么在下列的配置下,输入可以更简单:

(setq sis-inline-single-space-close t)

输入:中文<spc>english<spc>中文即可

1 个赞

client模式我没想过兼容性,没测试过。
可能macos下client模式也不能正常运行。
有空好好看看代码有没有哪个地方不兼容,

https://imgur.com/a/TKaD3So

问题见上面的视频,从 normal mode 切换到 insert mode 的时候,应该是切换为 rime,但从视频中可以看出,闪烁了一下,又变成了 ABC,排查了我的整个配置,最小配置内只放了 sis 和 meow 的配置,如下。

复现的步骤是打开到 org mode,在标题处 i 进入 insert mode,此刻是正常的。切回 Normal mode 后切换到其他应用再切回 emacs 后,i 进入 insert mode 后就会复现,几乎是百分百的概率。如此往复于 normal mode 和 insert mode 几次后,就会回归正常,不再复现,除非再次切换到其他应用重复以上过程。

(require-package 'sis)
;; meow insert mode switch
(defvar meow-leaving-insert-mode-hook nil
    "Hook to run when leaving meow insert mode.")
(defvar meow-entering-insert-mode-hook nil
    "Hook to run when entering meow insert mode.")
(add-hook 'meow-insert-mode-hook
    (lambda ()
        (if meow-insert-mode
            (run-hooks 'meow-entering-insert-mode-hook)
          (run-hooks 'meow-leaving-insert-mode-hook))))
(use-package sis
  :config
  (setq sis-english-source "com.apple.keylayout.ABC")
  (sis-ism-lazyman-config
   "com.apple.keylayout.ABC"
   "im.rime.inputmethod.Squirrel.Rime" 'macism)
  ;; 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)
  ;; not delete the head spaces
  (add-hook 'meow-leaving-insert-mode-hook #'sis-set-english)
  (add-to-list 'sis-context-hooks 'meow-entering-insert-mode-hook)
  ;; org title 处切换 Rime,telega 聊天时切换 Rime。
  (add-to-list 'sis-context-detectors
    (lambda (&rest _)
      (when (or (and (eq major-mode 'org-mode) (org-at-heading-p))
                (eq major-mode 'telega-chat-mode))
        'other)))
  :ensure)

(require-package 'meow)
(require 'meow)
(defun meow-setup ()
  (setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty)
  (meow-motion-overwrite-define-key
   '("j" . meow-next)
   '("k" . meow-prev)
   '("<escape>" . ignore))
  (meow-leader-define-key
   ;; SPC j/k will run the original command in MOTION state.
   '("j" . "H-j")
   '("k" . "H-k")
   ;; Use SPC (0-9) for digit arguments.
   '("1" . meow-digit-argument)
   '("2" . meow-digit-argument)
   '("3" . meow-digit-argument)
   '("4" . meow-digit-argument)
   '("5" . meow-digit-argument)
   '("6" . meow-digit-argument)
   '("7" . meow-digit-argument)
   '("8" . meow-digit-argument)
   '("9" . meow-digit-argument)
   '("0" . meow-digit-argument)
   '("/" . meow-keypad-describe-key)
   '("?" . meow-cheatsheet))
  (meow-normal-define-key
   '("0" . meow-expand-0)
   '("9" . meow-expand-9)
   '("8" . meow-expand-8)
   '("7" . meow-expand-7)
   '("6" . meow-expand-6)
   '("5" . meow-expand-5)
   '("4" . meow-expand-4)
   '("3" . meow-expand-3)
   '("2" . meow-expand-2)
   '("1" . meow-expand-1)
   '("-" . negative-argument)
   '(";" . meow-reverse)
   '("," . meow-inner-of-thing)
   '("." . meow-bounds-of-thing)
   '("[" . meow-beginning-of-thing)
   '("]" . meow-end-of-thing)
   '("a" . meow-append)
   '("A" . meow-open-below)
   '("b" . meow-back-word)
   '("B" . meow-back-symbol)
   '("c" . meow-change)
   '("d" . meow-delete)
   '("D" . meow-backward-delete)
   '("e" . meow-next-word)
   '("E" . meow-next-symbol)
   '("f" . meow-find)
   '("g" . meow-cancel-selection)
   '("G" . meow-grab)
   '("h" . meow-left)
   '("H" . meow-left-expand)
   '("i" . meow-insert)
   '("I" . meow-open-above)
   '("j" . meow-next)
   '("J" . meow-next-expand)
   '("k" . meow-prev)
   '("K" . meow-prev-expand)
   '("l" . meow-right)
   '("L" . meow-right-expand)
   '("m" . meow-join)
   '("n" . meow-search)
   '("o" . meow-block)
   '("O" . meow-to-block)
   '("p" . meow-yank)
   '("q" . meow-quit)
   '("Q" . meow-goto-line)
   '("r" . meow-replace)
   '("R" . meow-swap-grab)
   '("s" . meow-kill)
   '("t" . meow-till)
   '("u" . meow-undo)
   '("U" . meow-undo-in-selection)
   '("v" . meow-visit)
   '("w" . meow-mark-word)
   '("W" . meow-mark-symbol)
   '("x" . meow-line)
   '("X" . meow-goto-line)
   '("y" . meow-save)
   '("Y" . meow-sync-grab)
   '("z" . meow-pop-selection)
   '("'" . repeat)
   '("<escape>" . ignore)))
(meow-setup)
(meow-global-mode 1)

确认有同样的问题,补充一下我这里的环境:

mac / vanilla emacs / evil

我测试了一下,在 scratch 里也是一样的问题。光标放在中文字符上,当首次从 normal mode 进入 insert mode 后,输入法先变成中文,后来立即又变成英文的了。。

在您的项目下我曾问过这个问题,就是

说实话我的代码能力不是很好,没有看懂这个部分的代码,是修改了什么变量实现的吗?

这样几乎是不可用的状态了,希望尽早能修复。

是这样的,
你是从其它应用切回emacs后,
立刻就 i 进入 insert mode?

如果稍微延迟一下再 i 进入 insert mode,
是不是就没这个问题了?

emacs处理窗口焦点的切换(focus in事件)是有一个延迟的,
这样操作就导致:

  • focus in之后恢复当前buffer的input source(因为离开前为normal状态,所以为english)
  • 你进入insert mode切换input source(为rime)

这二者抢占了。

比较dirty但是直接的办法是,
你把下面这个函数在自己的配置文件中重新定义一下,让sis不要切换。

但是这块也不算是sis的bug,
sis对于焦点切换也只能做到这一步。
包治百病的用法就是切回emacs稍微等一下。

不过我又想到一点,
macos可以系统配置“自动切换到文稿的输入法”,
你如果配置了这个,
在使用GUI Emacs时,应该是不需要sis自己去恢复当前buffer的输入法的。
那就可以用空函数去覆盖上面那个函数了。
但是!!!
macos也会帮你主动地切输入法,就是不知道会不会也有延迟,导致同样的问题

不过sis针对的是一般情况:非MacOS系统,或没系统设置“自动切换到文稿的输入法”,或用的是Terminal Emacs等等。

2 个赞

那个issue下面,
从下面这个回复开始,
已经很详细了啊。

没有办法再做进一步的解释了。

我测试了,MacOS下,
TUI 的 emacs client 下,sis也是没法用。
GUI的emacs client下,sis可以正常使用。
但是我看字体什么的都不对 :joy: :joy: (当然这些和sis无关)

sis应该是因为牵涉到窗口的问题。
还没考虑过client模式
需要研究一下。

感谢详细的回答,说到延迟,我想到了我当时的操作,就是不断的退出 insert mode 再进入 insert mode 几次过后,他就恢复正常了。

我这里的情况不是【从其它应用切回 emacs 后立即进入 insert mode】, 在 emacs 里已经停留了很长时间了,第一次进入 insert mode 后还是有问题(光标在中文上,输入法先是中文后来自动变英文)

你们是不是都是用的meow呢? sis本身只考虑了evil的情况。

是否有可能是将meow接入sis的代码不完善?

我这里把 sis–respect-focus-in-handler 覆盖为空函数,基本不会出现覆盖,但偶尔还是会出现英文输入法覆盖中文的情况,概率低于10% 了。

我是用的 evil, 在上面有说明我的情况. 而且,在系统配置里不勾选【自动切换输入法】也是一样的问题,所以应该不是抢占导致的

我把这个选项也去掉了,也用空函数覆盖了上面提到的函数,但还是会偶现。(用的 meow,emacs-plus@29 最新,2017 MBP)

我希望在org-roam打开minibuffer之后切换中文,然后定制了这个快捷键

  (global-set-key (kbd "C-c n n")
                  '(lambda()
                     (interactive)
                     (org-roam-node-find)
                     (sis-set-other)))


但是没有切换中文输入法,请问是哪里的问题

看了readme仍不懂,macos,鼠须管输入法 尝试一:按示例复制到init.el里

(sis-ism-lazyman-config nil “rime” 'native) 不能触发中文输入

尝试二:按macos说明写到init.el

(sis-ism-lazyman-config

   "com.apple.keylayout.US"
   "rime")

也不行,是不是rime这个名称不对?但是如果手工切到中文了又输入不了sis-get…疑惑中 ps论坛怎么才能回车换行

最近mac下的输入法鼠须管升级了, 鼠须管0.16.2 (2023-02-05)。sis也失效了,有可能是鼠须管的内部名称改变了,不是 “im.rime.inputmethod.Squirrel.Rime” 了。

有类似情况吗?

im.rime.inputmethod.Squirrel.Hans

以前是 im.rime.inputmethod.Squirrel.Rime 现在是 im.rime.inputmethod.Squirrel.Hans 或者 im.rime.inputmethod.Squirrel.Hant,对应的是简体和繁体,替换一下就行了。

1 个赞