Emacs 要如何实现 Vscdoe 中 Python 那种折叠效果

试了 hs-minor-modeorigami 但总是有些折叠不了地方。而且这些 mode 的设置方法实在是摸不懂。

不知道大佬们能否分享一下设置好的 Python 折叠设置?

1 个赞

可以試試看我寫的 ts-fold, 因為使用 tree-sitter 所以非常準確! :smile:

4 个赞

谢谢大佬推荐。

试用了一下,确实要比其它的要好上许多,对于 Python 能识别出字典 {} 和列表 []。

但是,不知道是不是我使用的姿势不对,对于文档字符串 “”" “”" 似乎不能很好的识别。比如下面这个

image

treesit对于python三种引号识别是很有问题的。

我的括号插件遇到很多问题都和treesit在字符串识有关。

原因是因為根本沒有加 :sweat_smile:, 我導入了 → feature(parser): Add support for python docstring by jcs090218 · Pull Request #58 · emacs-tree-sitter/ts-fold · GitHub

有興趣的話可以提 Issue 或 PR, 這個本身算很好擴充的套件了! :wink:

我現在用是沒有問題. 可能要試著更新 parser 到最新? :thinking:

不知道vscode折叠是啥效果,不过有个yafolding,我记得是根据缩进来折叠,应该比较适合python用。

不是的,treesit还有很长路要走,一些细节还是要多磨合才行。

新增的效果:

摺疊前:

摺疊後:

你是說 module 本身嗎? 我還沒試過呢. 不過 tree-sitter.el 本身還不錯. :smiley:

ts-fold 有個 treesit.el 的 fork, 看這裡. 看了一下代碼, 我以為大同小異. :thinking:

什么时候支持29版本内置的tree-sitter

進度我會貼在這邊, Treesit.el Support · Issue #48 · emacs-tree-sitter/ts-fold · GitHub.

我計畫等 29.1 出來後再折騰. :wink:

1 个赞

谢谢大佬,不过不知道是不是我设置的问题。我这边在折叠三字符词的时候,提示 void-function ts-docstr-find-children

已提 issue: Error: (void-function ts-docstr-find-children) · Issue #59 · emacs-tree-sitter/ts-fold · GitHub


ts-docstr-find-children 改成 ts-fold-find-children 倒是可以实现大佬展示的效果,可以折叠三引号的文档字符串。但是对于下列的赋值语句,却没有折叠效果。

PopTempSegmentAsm = """\
// {command}
    @{index}  // address = 5 + index
    D = A
    @5
    D = D + A
    @R13 
    M = D
    @SP  // Get data in the stack
    M = M - 1
    A = M
    D = M
    @R13
    A = M
    M = D
"""

是不是我的安装有问题,漏掉了 ts-docstr-find-children 这个函数?

阿 我寫太快了. 跟 ts-docstr 的模塊搞混了. :sweat: 已修復了!

另外三引号折疊的話, 我目前只有支援 document string. 我還不太熟悉 python, 不過你的代碼串被 tree-sitter 分類為 assignment, 看 AST的話:

expression_statement:
  assignment:
    identifier:
    string:

目前只支援:

expression_statement:
  string:

我好奇一般 assignment 是否也應該摺疊? :thinking: (有興趣的話可以提 feature request, GitHub上面有些人會給予意見討論)

後來我直接加了這個功能, 看 feat(python): Support assignment string · emacs-tree-sitter/ts-fold@1d690b8 · GitHub. :wink:

可以用了,非常流畅。谢谢大佬 :wave: :clap:

在 Vscode 里面是可以折叠的,之前用习惯了,所以就觉得应该能折叠。

看大佬改代码真得能学到很多东西呀,我觉得我似乎是已经了解了怎么自己加东西了 :dog:

1 个赞

大佬,我如果想自己定义一些折叠样式。

比如加入 if elif else 的折叠,除了修改 ts-fold-parsers-python 这个函数,是不是还要定义类似于 ts-fold-range-python-def 这样的函数。

我把 ts-fold-parsers-python 修改成了下面这个样子,可以对 if-statement 并没有效果

(defun ts-fold-parsers-python ()
  "Rule set for Python."
  '((function_definition  . ts-fold-range-python-def)
    (class_definition     . ts-fold-range-python-def)
    (list                 . ts-fold-range-seq)
    (dictionary           . ts-fold-range-seq)
    (if_statement         . ts-fold-range-python-def)
    (expression_statement . ts-fold-range-python-expression-statement)
    (comment
     . (lambda (node offset)
         (ts-fold-range-line-comment node offset "#")))))

函數不是即時的 (對, 這不是個好設計 :sweat:), 你必須在設置一次 ts-fold-range-alist:

(setq ts-fold-range-alist `((python-mode . ,(ts-fold-parsers-python))))  ; 更新一次

詳細的可以看這裡, https://github.com/emacs-tree-sitter/ts-fold#-folding-on-new-nodes. :wink:

Edit: if, elif, else 應該會更複雜一些. 你可以參考看看其他的語言怎麼做, Lua, C-macros, 等等. 或也可以等我抽空來弄! :slight_smile:

谢谢大佬,我第一次在 lisp 中见这种类似于 Python 更新字典值的赋值方式,学到了 :smile:

我现在 if 可以出效果了,但是要自己写一下类似于 ts-fold-range-python-expression-statement 的函数,坐等大佬弄出来后学习学习 :hugs:

1 个赞

感谢大佬,包用起来非常不错,我现在正好在用tree-sitter, 而非内置的tree-sit

1 个赞