在写包的时候怎么根据一个 defcustom 的值来改变变量的值?

之前我魔改了一下 pinyinlib 将拼音查词改成了五笔查词(见下)

然后现在我想给原repo贡献一个选择Char table的功能。

于是想要一个通过设定变量的值从而条件地改变另外一个变量的值的方法。

比如说我 defcustom 一个变量pinyinlib--char-table-type,当用户设定这个值为'wubi时,然后pinyinlib--simplified-char-table就是五笔的table,而当用户设定这个值为'pinyin的时候,pinyinlib--simplified-char-table的值就是一个拼音的table。

为什么要用两个变量?在启动后用户改了 defcustom 要怎么办?为什么不同时保留两个 table,根据 defcustom 来选用的 table?为什么不直接暴露pinyinlib--simplified-char-table让用户设定用的 table (defcustom 可以 :options 用来设定这类变量?)

参考

可能是我问题里面没有表述清楚,我确实是这样做的,因此正想问问应该如何做到根据defcustom的值来选用使用哪个table。

而且我是在修改别的老哥的代码,原repo已经被别的库使用了。因此我必须考虑到兼容的问题,现在我的修改是可以跑的通的,但是却减少了 pinyinlib--{simplified,traditional}-char-table 两个变量,取在代之的是 pinyinlib--{wubi,pinyin}-{simplified,traditional}-char-table 这四个变量。如果有别的程序依赖于这个变量的话,那么就会导致不兼容。所以我就想能不能够通过defcustom的方式来使得值不相同。

我没有找到解决的办法,我当时尝试了下面这样 image

但是这样的话,在配置里面该如何写呢?

(use-package pinyinlib
  :custom
  (pinyinlib--simplified-char-table pinyinlib--pinyin-simplified-char-table))

这样写会在执行的时候报错,应该和 use-package 代码的加载顺序有关,在执行这条语句的时候,pinyinlib--pinyin-simplified-char-table尚未加载。

没看懂这里的作用,我去查查 Manual ……

leaf-find-function-support: t

find-function-regexp-alist:

'((leaf . leaf-find-regexp)
 (flycheck-checker . flycheck-find-checker-regexp)
 (define-type . cl--typedef-regexp)
 (cl-defgeneric . cl--generic-find-defgeneric-regexp)
 (cl-defmethod . cl--generic-search-method)
 (nil . find-function-regexp)
 (defvar . find-variable-regexp)
 (defface . find-function--defface)
 (feature . find-feature-regexp)
 (defalias . find-alias-regexp)
 (ert-deftest . find-ert-deftest-regexp))

M-x customize-set-variable RET leaf-find-function-support RET n

leaf-find-function-support: nil

find-function-regexp-alist:

'((flycheck-checker . flycheck-find-checker-regexp)
 (define-type . cl--typedef-regexp)
 (cl-defgeneric . cl--generic-find-defgeneric-regexp)
 (cl-defmethod . cl--generic-search-method)
 (nil . find-function-regexp)
 (defvar . find-variable-regexp)
 (defface . find-function--defface)
 (feature . find-feature-regexp)
 (defalias . find-alias-regexp)
 (ert-deftest . find-ert-deftest-regexp))
1 个赞

还能这样?好神奇啊。那是不是说如果不使用customize而直接使用setq来设定这个值的话就没有办法让其正确设置变量了呢。

知道是个 custom-variable 却不用 customize-set-variable 能怪谁

是这样的,我将我的 char-table 使用了 defconst 来定义,但是在加载包的时候会报 void-variable 错误,我写的代码如下

(defcustom pinyinlib--char-table-type
  'wubi
  "Which char table type to use."
  :group 'pinyinlib
  :type '(choice :tag "Which char table to use"
                 (const :tag "Pinyin" pinyin)
                 (const :tag "Wubi" wubi))
  :set (lambda (sym val)
         (set sym val)
         (cl-case val
           ('wubi (setq pinyinlib--simplified-char-table pinyinlib--wubi-simplified-char-table)
                  (setq pinyinlib--traditional-char-table pinyinlib--wubi-traditional-char-table))
           ('pinyin
            (setq pinyinlib--simplified-char-table pinyinlib--pinyin-simplified-char-table)
            (setq pinyinlib--traditional-char-table pinyinlib--pinyin-traditional-char-table)))))

我已经将这些 defconst 的变量放在前面了。

建议写个完整的最小复现案例, 把 defconst 那些加进去,不然解决不了

感觉 Doom Debug 起来有点麻烦,有的时候明明写对了,但是因为有 Byte-compiled 的代码存在,所以就表现得和没有改变之前一样,需要手动将 build 目录下对应的 package 删除再 doom sync 一次才能看到效果 :cry:

今天晚上这个特性整得我有点烦了。而且现在的代码也已经能用,只是如果有人写了依赖 pinyinlib--{simplified,traditional}-char-table 的代码才会不兼容,但那本身就不是鼓励的使用方式,所以我想就到这里为止吧……

  1. 你希望向他的 repo 提交代码:和作者讨论要怎么改,而不是靠自己想

  2. 你不打算提交代码:完全不用考虑兼容问题

一语惊醒梦中人了,我还真没想过跟作者讨论的选项……