[分享] 切换输入法时自动更换光标颜色

最近在Emacs 中使用 Emacs-rime 输入法时,由于设置了 Shift 按键切换输入法,经常会出现误触Shift键将当前输入法切换到中文输入法,而在专注输入内容时,很难注意到左下角的输入法状态图标。

对于这个问题,其实社区已经有了现成的方案:

  1. pyim 输入法最近增加了根据输入法状态切换颜色的功能。
  2. sis 方案也自带这个功能
  3. emacs-rime 可以使用cursor-chg 这个包实现。

cursor-chg 对我来说功能太多,我只要换个光标颜色而已。它除了支持更换光标颜色,还支持在闲置时更换光标的形状,在切换到只读模式的buffer时更换光标的形状。

所以,在参考了cursor-chg ,以及在 @tumashu 大佬的帮助下, 实现了简单的输入法切换更换光标颜色的功能。在此和大家分享,希望各位大佬能帮忙指点一下。

  (defvar input-method-cursor-color "Orange"
    "Default cursor color if using an input method.")

  (defvar default-cursor-color (frame-parameter nil 'cursor-color)
    "Default text cursor color.")

  (defun change-cursor-color-on-input-method ()
    "Set cursor color depending on whether an input method is used or not."
    (interactive)
    (set-cursor-color (if current-input-method
                          input-method-cursor-color
                        default-cursor-color)))

  (add-hook 'post-command-hook 'change-cursor-color-on-input-method)

提示:

  1. 在手动切换输入法时才会切换 各种命令后都会切换。
  2. 在通过 load-theme 更换主题时,会自动使用新主题的光标颜色作为默认颜色。
  3. 中文输入法颜色一直使用预设的"Orange",感觉 “Orange” 在各种主题下都看的清楚。
  4. 需要集成emacs-rime 断言的请参考 @Shaun 更新的change-cursor-color-on-input-method函数。
7 个赞

我也把pyim的光标颜色改为橘色试试

用上了,很顺利,很棒。反馈一个小问题:切换buffer后,光标颜色不会变。可以完善一下。

确实有这个问题,因为emacs-rime 比较智能,在进入minibuffer的时候会自动切换输入法状态到英文。 上面的最后一条代码只是在手动切换输入法的时候会变颜色。我还没想到更好的方案。

建议你先用 cursor-chg,可以这样设置:
将cursor-chg下载下来,丢到你的load-path 里面,然后:


(require 'cursor-chg)
(defun get-frame-cursor-color ()
    "Get the cursor-color of current frame."
    (interactive)
    (frame-parameter nil 'cursor-color))

(setq curchg-default-cursor-color (get-frame-cursor-color))
(setq curchg-default-cursor-type 'box)
(change-cursor-mode 1)

macOS 的自带的中英输入法切换后可以换光标颜色吗?

用系统自带的中英文输入法你需要用给我上面提到的第二种方案 sis,需要安装外部依赖,具体你看下sis的安装说明。

(advice-add 'toggle-input-method :after 'change-cursor-color-on-input-method)

input-method-deactivate-hookinput-method-activate-hook 更好吧

这个没法触发切换颜色的函数。但是 input-method-activate-hook 会生效。
因为:

The variable `current-input-method' still keeps the input method name
just deactivated."

用 popup-tip 显示个提示也是不错的。

一楼已经更新,现在行为和 cursor-chg这个包一样,绑定在post-command-hook,这样切换buffer 后,移动下光标就会更新颜色。

1 个赞

这也是一个不错的选择,但我个人不是很习惯弹出内容的方式。我现在输入法都不要弹出的候选提示了😄。

https://emacs-china.org/uploads/default/original/2X/2/272c4f4f56631dee6c63b85a7a671521fa80dc61.gif

这种小绿点提示效果怎么样?

2 个赞

:+1:我觉得你这个方案挺好的,干扰少,就是要一眼就看出输入法变化了就行。 不过我现在习惯使用红色光标,这种方案不知道配什么颜色比较显眼。

不知道,现在我正在摸索阶段

我试了一会,感觉小点不如光标好使,点太小容易忽视,太大又比较难看

确实是有这个问题。我个人是更偏向将整个光标用一种颜色来区分的,比较直观。

很好用,感谢分享!我在 change-cursor-color-on-input-method 函数的 if 里增加了两条断言,可以遵从 emacs-rime 中的 rime-disable-predicates 来改变光标颜色:

  (defun change-cursor-color-on-input-method ()
    "Set cursor color depending on whether an input method is used or not."
    (interactive)
    (set-cursor-color (if (and (rime--should-enable-p)
                               (not (rime--should-inline-ascii-p))
                               current-input-method)
                          input-method-cursor-color
                        default-cursor-color)))

5 个赞

:+1: 赞。我正在想怎么把 emacs-rime 的断言加进来呢,太及时了。
现在按错Shift 都就一点痕迹都看不出来了😄

我是使用timer , 每0.3s探测一次

刚才看了你的实现,本来想用timer的,刚开始担心post-command-hook会影响性能。后来在Windows 下测试 ,发现并没有影响,而且开了emacs-rime的断言判断也是很流畅,同时还开着1.5s 的auto-save :grinning:。其实函数所做的事情就是比对一下条件,并设置光标颜色,计算量应该很低了。