楼上说了我再补充几句可能涉及一些“高级Elisp技巧的东西”
-
Emacs 27 用
json-parse-string
性能更好,这是基于 libjansson C 库的 JSON 解析,json-read-from-string
是用 Lisp 实现的 JSON 解析。另外 JSON array 我建议直接按默认变成 vector,然后用(aref array index)
来访问元素,因为转成链表之后虽然方便了,但是访问比较靠后的元素是没有 vector 的下标访问快的 -
用 comint 确实不太优雅,但是用 start-process 应该没法直接发送 Python expression 去给 Python eval。我的建议是学习一下 Emacs 的异步进程机制。先写一个 Python wrapper,从 stdin 接受字符串,然后把分词结果发送到 stdout。
-
cnhl-last-sentence
是一个很耗时的函数,放在after-change-functions
里面,每次变更都要运行,浪费时间。我的建议是加入 debounce – 每次触发时,放到一个 timer 里面,延迟 100ms 左右再执行,如果 timer 正在计时中,那就删除掉原来的 timer 重新计时,可以有效减少这种耗费时间的操作的执行。 -
上面提到
(second item)
是一个 pattern, 这时候可以引入 struct 来抽象化访问,比如用cl-defstruct
定义一个结构,然后写一个函数把 JSON 解析成这个结构,就可以通过 结构的 accessor 访问,更清晰。 -
chnl
里面有一个 cond, 里面有很多(member (second item) '("n" "ns" "ni" "nz" "r" "j")
这样的结构,这里可以使用pcase
模式匹配,让程序更易读。如
(cond
((member (second item) '("n" "ns" "ni" "nz" "r" "j" "np")) 'cnhl-shades-n-r-j)
((member (second item) '("u" "y" "h" "k" "e" "o")) 'cnhl-shades-u-y-h-k-e-o)
((member (second item) '("v" "id" "i")) 'cnhl-shades-v-i-id)
((member (second item) '("d" "c" "p")) 'cnhl-shades-d-c-p)
((member (second item) '("a" "f" "s" "t" "m" "q" "mq")) 'cnhl-shades-a-f-s-t-m-q-mq)
(t 'cnhl-shades-g-w-x))
重构为
(pcase (second item)
((or "n" "ns" "ni" "nz" "r" "j" "np")
'cnhl-shades-n-r-j)
((or "u" "y" "h" "k" "e" "o")
'cnhl-shades-u-y-h-k-e-o)
((or "v" "id" "i")
'cnhl-shades-v-i-id)
((or "d" "c" "p")
'cnhl-shades-d-c-p)
((or "a" "f" "s" "t" "m" "q" "mq")
'cnhl-shades-a-f-s-t-m-q-mq)
(_
'cnhl-shades-g-w-x))
关于 pcase, 论坛里有一个帖子
- 正则表达式用
rx
宏来写,更易懂
参见
那串正则可以改成
(rx
(or (group ",")
(group "。")
(group "?")
(group ";")
(group ":")
(group "、")
(group "‘")
(group "’")
(group "“")
(group "”")
(group "…")
(group "!")
(group "(")
(group ")")
(seq
(group "~")
"|"
(group "*"))))