pyim 代码重构了,用的同学注意一下

感谢, (frame-parameter nil 'cursor-color) 是可以获取当前frame 下的光标颜色。

2 个赞

大赞楼主这个修改,这我真不想跳出 emacs 了啊,用操作系统的输入法老切来切去了,跟插 U 盘一样,正着来反着来再正着来。感觉自己用五笔的,对输入法要求不高,rime 对外部有依赖,索性换成 pyim 的。提了个五笔86单字词表的 pr, 如果楼主觉得不符合 pyim 的发展方向可以直接关掉哈。https://github.com/tumashu/pyim-wbdict/pull/10

还没顾上看pr, 对于五笔而言,我是外行,所以你们的pr就是五笔的发展方向:slight_smile:

已经合并了。。。

1 个赞

我发现一个光标颜色设置问题:

我设置了到时间自动切换暗黑主题,因为要设置中文和英文光标颜色,但新切换 Buffer 后默认的光标颜色与我想要的颜色不同,所以我会通过 set-cursor-color 设置默认的光标颜色,再通过 pyim 设置中英文的光标颜色。

正常打开 Emacs 时是正常的,但自动切换了主题后,过一段时间光标系统默认的光标就会回到前一个主题的光标,只有开启了 pyim 后才能强制光标改变颜色,通过 set-cursor-color 函数设置后就会发现光标颜色瞬间就又切换到前一个主题的光标颜色了。

PS:目前人在外面,手机打字不方便写代码,等回到家我再把自己的设置补上

你使用环境复杂,所以最好的方式是自定义一个光标切换函数,添加到pyim-indicator-list中,这样更好的控制光标颜色切换 ‘’’ (defcustom pyim-indicator-list (list #'pyim-indicator-with-cursor-color #'pyim-indicator-with-modeline) “PYIM 当前使用的 indicators. Indicator 用于显示输入法当前输入状态(英文还是中文)。” :type '(choice (const :tag “Off” nil) (repeat :tag “Indicator functions” function)))

 '''

@tumashu 你好,我的 Lisp 水平有点儿差,抱歉 :pensive:

下面这段代码是我按照你的代码还原后的,你看下有问题没有:

(defcustom pyim-indicator-list (list #'pyim-indicator-with-cursor-color #'pyim-indicator-with-modeline)
  "PYIM 当前使用的 indicators. Indicator 用于显示输入法当前输入状态(英文还是中文)。"
  :type '(choice (const :tag "off" nil)
                 (repeat :tag "Indicator functions" function)))

下面是我光标颜色设置的核心逻辑,不清楚该如何套用到你的示例代码上,如果方便的话,可以帮我套用一下吗?

;; target-theme 是要设置的目标主题
;; day-theme 是浅色主题
;; dark-theme 是暗黑主题
(if (eq target-theme day-theme)
    (progn
      (load-theme day-theme t)
      (set-cursor-color "#666")
      (setq pyim-indicator-cursor-color (list "purple" "#666")))
  (progn
    (load-theme dark-theme t)
    (set-cursor-color "#b2b2b2")
    (setq pyim-indicator-cursor-color (list "#ff72ff" "#b2b2b2"))))

看源码的时候发现了这个变量 pyim-indicator-original-cursor-color

看注释我理解为 PYIM 启动时记录的光标颜色,仔细查看我上面设置主题的代码

感觉切换主题后,我调用「设置光标颜色的函数」设置新值,和这个变量记录的值冲突了?由于 PYIM 内部定时器的存在,所以在我手动调用 set-cursor-color 后又被更新为 pyim-indicator-original-cursor-color 记录的值了?

@tumashu 终于找到复现的方式了:

  1. 启动时根据如下代码设置

    (set-cursor-color "#b2b2b2")
    (setq pyim-indicator-cursor-color (list "#ff72ff" "#b2b2b2"))
    
  2. 此时输入拼音,并且通过 M-j 的方式进行转换,看到光标在汉字后出现粉色即可停止

  3. 通过『设置光标函数』更改光标的默认色值

    (set-cursor-color "red")
    
  4. 此时就可看到设置成功后光标立即变回到 #b2b2b2 这个色值:Bug 出现了

pyim indicator 本身就会调用 set-cursor-color, 所以如果你再手工调用,肯定会冲突

这是一个解决你的问题的一个小框架,也许有帮助

(setq pyim-indicator-list (list #'my-pyim-indicator-with-cursor-color #'pyim-indicator-with-modeline))

(defun my-pyim-indicator-with-cursor-color (input-method chinese-input-p)
  (if (not (equal input-method "pyim"))
      ;; pyim 关闭时的颜色
      (set-cursor-color "red")
    (if chinese-input-p
         ;; pyim 输入中文时的颜色
        (set-cursor-color "green")
      ;; pyim 输入英文时的颜色
      (set-cursor-color "blue"))))
1 个赞

@tumashu 最近想给一个同事安利 Emacs,本想说 Emacs 占用资源小的,结果发现 Emacs 竟然占用了 800MB+ 的内存,经过移除安装的包,最终发现原因在于 PYIM,表现形式为:通过 M-j 转换拼音的方式启动 PYIM 后,内存瞬间暴涨 100MB+,闲置一段时间后会逐步升高,用了一天后差不多能达到 800MB+

个人感觉是内存泄漏导致的,有可能是我的配置问题,第二个是源码内部存在问题。我的配置是从 GitHub 的说明上 Copy 过来的,理论上应该不存在问题,所以初步断定是源码导致的

这个是我现在使用的方式,也是唯一一点儿和 PYIM 官方说明不一致的地方。

这个要看你用的词库有多大,因为 pyim 要把词库加载到一个hashtable里面,如果词库100M,那么加载到内存有可能就很大了。

可以研究研究这个:

(defcustom pyim-dcache-backend 'pyim-dhashcache
  "词库后端引擎.负责缓冲词库并提供搜索词的算法.
可选项为 `pyim-dhashcache' 或 `pyim-dregcache'.
前者搜索单词速度很快,消耗内存多.  后者搜索单词速度较快,消耗内存少.

`pyim-dregcache' 速度和词库大小成正比.  当词库接近100M大小时,
在六年历史的笔记本上会有一秒的延迟. 这时建议换用 `pyim-dhashcache'.

注意:`pyim-dregcache' 只支持全拼和双拼输入法,不支持其它型码输入法."
  :type 'symbol)

了解了,但是内存占用会持续增长,也是 pyim-dcache-backend 导致的吗?

我感觉应该不会导致内存不断增长

我再看看吧,现在的情况是使用几个小时后,内存就暴涨到 900MB 了,使用 garbage-collect 回收也不起作用

看下gcmh-high-cons-thresholdgc-cons-threshold的值是否正常,建议设置为(* 16 1024 1024) ;; 16MB

是不是用了lsp,lsp在我这边会导致内存不断增长,换eglot就没这个问题了

我昨天又调试了下,好像是 Company 的问题,PYIM 从始至终就占用了 100MB 左右,我试试 eglot