origami 如何自定义代码折叠?

对 elisp 不是特别熟悉 GitHub - gregsexton/origami.el: A folding minor mode for Emacs
虽然他提供了一个实例,但我还是不知道怎么做,不知道有没有大佬能做个示范

 (defun my-amazing-parser (create)
   (lambda (content)
     (list (funcall create beginning-of-the-fold-node-point-position ; inclusive
                           end-of-the-fold-node-point-position ; exclusive
                           offset  ; this allows you to show some of the start of the folded text
                           child-nodes))))

我这里需要缩进 Julia 代码,缩进的块有

  1. function
function name(args ...)
# body
end
  1. begin … end
begin
# body
end
  1. let … end
let
#body
end
  1. if , end
if condition
#body
end
  1. while … end
while condition
# body
end
  1. macro
macro name(args...)
# body
end

文档里建议看 origami-parsers.el.

origami.el 很複雜, 效能差. 還是用 TreeSitter based 的插件比較好! 例如 ts-fold, GitHub - emacs-tree-sitter/ts-fold: Code-folding using tree-sitter.

但是 origami.el 支持自定义 marker 进行 folding, 比如 {{{}}}, ts-fold 能否做到呢? 另外我暂时没感觉 origami.el 到性能差, 或许是因为我用 origami 的文件都比较小.

可以, 但目前沒有新增的想法.

這個要看你怎麼想了, origami.el 是 regex based; 效能瓶頸就擺在那裡. 重點是稍微複雜一點的文法就會出錯. 主要的問題有三:

  1. 效能 (因個人經驗可能有些不同)
  2. 不夠準確
  3. 不容易擴充

第 1 點主要是因為 regex 本身. 第 2 點跟文法的複雜度成正比. 第 3 點是主要是 regex 很難完美的完成這些需求. 擴充的複雜度也很高, 相對維護成本也會提高. 也間接導致新語言和功能導入也很慢; 基本上已經沒再更新了. 我自己有做一個 fork — GitHub - elp-revive/origami.el: A folding minor mode for Emacs. 但我已經看到了極限. 所以改用 TreeSitter based 的答案; 以上痛點一次全部搞定. :yum:

當然, 我是因為用過很多種 folding 包才得出這種結論. 不代表 origami.el 不好. 只是有了更棒的替代品! 我的 ts-fold 也有好幾位受不了 origami.el 本身的受限, 然後跑來使用 ts-fold.

2 个赞

是要折叠还是要缩进?

目前Emacs的fold还真没找到特别好的package,这个功能还是希望能内置,效率会高很多,ts也许能成。

1 个赞

我的看法跟 @jcs090218 差不多:

origami 折叠之前需要全文扫描一遍,性能注定好不了。

origami 的折叠实现大致可以分为两种:

  1. 基于对称标记,比如 {}/**/。这种方式比较简单,把对称标记赋给 origami-build-pair-tree 差不多就完成了。

    我用这种方式试了一下 julia 是可以的(需要改造 origami-build-pair-tree):

    image

    但是很多场景如果只折叠头尾,会导致关键信息被隐藏,多段折叠就很有必要了,例如:

    if x > y...
    elseif x < y...
    else...end
    

    仅凭一对正则表达式显然很难做到。

  2. 不依赖对称标记,比如 python,它是把全文放到一个 temp buffer 里再启用 major mode 然后扫描(这是嫌性能太好了吗?),这种方式自主性更高,不受限于正则表达式,但是要从头开始写 parser。自带的 python parser 算简单了,功能也有限,只能折叠函数。

    想要实现 julia 折叠可以参考这个 ruby parser,毕竟语法更接近些,但它也只能折叠函数,而且很容易就试出了 bug。

1 个赞

未來應該是會往這方向走才對. 不過內置的 treesit 我還沒試過. 我還在等他成熟穩定些 :eyes: