比如原本是 go-mode, 现在我用了 treesit 是 go-ts-mode, 创建 new snippet 它会提示我创建到 go-ts-mode 目录下, 但我希望它就创建到 go-mode 下. 虽然我想到可以用 symbolic, 就是让 go-ts-mode 指向 go-mode, 但这种方法我觉得不好, 一个明显的缺点是, 比如现在我添加到 go-ts-mode 了, 但是 org babel 中对于 go src block, 是 go-mode, 它查找不到这个 snippet.
*-mode
和 *-ts-mode
完全可以共用,放一个地方就好了。
;; 在 *-ts-mode 下加载 *-mode 的 snippets
(advice-add 'yas--modes-to-activate :around
(defun yas--get-snippet-tables@reverse-ts-mode (orig-fn &optional mode)
(funcall orig-fn
(or (car (rassq (or mode major-mode) major-mode-remap-alist))
mode))))
;; 在 *-ts-mode 下保存 snippets 到 *-mode 目录 (也可以试试直接在 yas--table-get-create 上 advice 看看有没有不良影响)
(advice-add 'yas-new-snippet :around
(defun yas-new-snippet@reverse-ts-mode (&rest args)
(cl-letf* ((yas--orig-table-get-create (symbol-function 'yas--table-get-create))
((symbol-function 'yas--table-get-create)
(lambda (mode)
(funcall yas--orig-table-get-create
(or (car (rassq (or mode major-mode) major-mode-remap-alist))
mode)))))
(apply args))))
2 个赞
我原来也使用 .yas-parent, 后来发现直接软链就得了。。。
对这段代码我有个语法问题不理解, 我理解的是一个 symbol 可以有一个 value binding 也可以有一个 function binding, 这里 yas-new-snippet@reverse-ts-mode
使用了 cl-letf, 这个宏如果不加 symbol-function 我理解的是它进行的是 value binding, 那么 yas--orig-table-get-create
就应该是 value binding, 但 funcall yas--orig-table-get-create
funcall 应该用的是第一个参数的 function binding, 但 cl-letf 不是进行的是 value binding 么? 我觉得按我的想法会出错, 我想请教是我哪里想错了呢?
虽然我用了 treesit-auto, 但发现 major-mode-remap-alist
为 nil, 于是我修改为:
(setq my/yas-major-mode-remap-alist (treesit-auto--build-major-mode-remap-alist))
然后把 major-mode-remap-alist
改为 my/yas-major-mode-remap-alist
. 不知道有无必要.
岔个题,有人用tempel吗,感受如何?
symbol-function
返回的即是 value 也是 place,就当作是指针吧。
看一下 cl-left
宏的原型 (cl-letf ((PLACE VALUE) ...) BODY...)
,就是把 (symbol-function 'xxx)
位置的 value 替换为指定的值。所以你可以提前把该位置的 value 备份起来。