Add ruby support to origami-treesit and make folding level configurable
This commit is contained in:
parent
0209cf16c5
commit
a0c0f6d1e2
@ -113,6 +113,8 @@
|
||||
:straight (:type built-in)
|
||||
:ensure nil
|
||||
:load-path "packages/origami-treesit"
|
||||
:after origami)
|
||||
:after origami
|
||||
:custom
|
||||
(origami-treesit-level 4))
|
||||
|
||||
(provide 'init-treesit)
|
||||
|
@ -29,6 +29,12 @@
|
||||
(require 'cl-lib)
|
||||
(require 'dash)
|
||||
|
||||
(defcustom origami-treesit-level 2
|
||||
"The level of folding to use for origami-treesit."
|
||||
:type 'integer
|
||||
:group 'origami
|
||||
:options '(1 2 3 4))
|
||||
|
||||
(cl-defun make-treesit-parser (create
|
||||
lang
|
||||
&key
|
||||
@ -38,20 +44,24 @@
|
||||
(let* ((parser (treesit-parser-create lang))
|
||||
(root (treesit-parser-root-node parser)))
|
||||
(cl-labels ((get-node-folds (node)
|
||||
(if (funcall node-matcher-fn node)
|
||||
(cl-destructuring-bind (start end offset child-nodes) (funcall fold-fn node)
|
||||
(list (funcall create start end offset (-mapcat #'get-node-folds child-nodes))))
|
||||
(if (funcall node-matcher-fn node origami-treesit-level)
|
||||
(cl-destructuring-bind
|
||||
(start end offset child-nodes &optional sibling-nodes)
|
||||
(funcall fold-fn node)
|
||||
(cons (funcall create start end offset (-mapcat #'get-node-folds child-nodes))
|
||||
(-mapcat #'get-node-folds sibling-nodes)))
|
||||
(-mapcat #'get-node-folds (treesit-node-children node)))))
|
||||
(get-node-folds root)))))
|
||||
|
||||
(defun origami-yaml-treesit-parser (create)
|
||||
(make-treesit-parser create 'yaml
|
||||
:node-matcher-fn (lambda (node)
|
||||
(member (treesit-node-type node)
|
||||
'("block_mapping_pair"
|
||||
"flow_mapping"
|
||||
"flow_pair"
|
||||
"flow_sequence")))
|
||||
:node-matcher-fn (lambda (node _level)
|
||||
(and (treesit-node-check node 'named)
|
||||
(member (treesit-node-type node)
|
||||
'("block_mapping_pair"
|
||||
"flow_mapping"
|
||||
"flow_pair"
|
||||
"flow_sequence"))))
|
||||
:fold-fn (lambda (node)
|
||||
(pcase (treesit-node-type node)
|
||||
((or "block_mapping_pair" "flow_pair")
|
||||
@ -83,9 +93,102 @@
|
||||
(child-nodes (treesit-node-children node)))
|
||||
(list start end offset child-nodes)))))))
|
||||
|
||||
(defun origami-ruby-treesit-parser (create)
|
||||
(make-treesit-parser create 'ruby
|
||||
:node-matcher-fn
|
||||
(lambda (node level)
|
||||
(let ((foldable-node-types '()))
|
||||
(when (>= level 1)
|
||||
(setq foldable-node-types
|
||||
(append foldable-node-types
|
||||
'("class" "method" "do_block" "hash" "array"))))
|
||||
(when (>= level 2)
|
||||
(setq foldable-node-types
|
||||
(append foldable-node-types
|
||||
'("block" "then" "else"))))
|
||||
(when (>= level 3)
|
||||
(setq foldable-node-types
|
||||
(append foldable-node-types
|
||||
'("call" "assignment"))))
|
||||
(and (treesit-node-check node 'named)
|
||||
(member (treesit-node-type node) foldable-node-types)
|
||||
(or (not (member (treesit-node-type node)
|
||||
'("class"
|
||||
"method"
|
||||
"do_block"
|
||||
"block")))
|
||||
(treesit-node-child-by-field-name node "body"))
|
||||
(or (not (equal (treesit-node-type node) "hash"))
|
||||
(treesit-search-subtree
|
||||
node
|
||||
(lambda (n)
|
||||
(equal (treesit-node-type n) "pair"))))
|
||||
(or (not (equal (treesit-node-type node) "call"))
|
||||
(treesit-node-child-by-field-name node "arguments"))
|
||||
(or (not (member (treesit-node-type node) '("then" "else")))
|
||||
(treesit-node-children node)))))
|
||||
:fold-fn
|
||||
(lambda (node)
|
||||
(pcase (treesit-node-type node)
|
||||
("class" (let* ((start (treesit-node-start node))
|
||||
(end (- (treesit-node-end node) 4))
|
||||
(body (treesit-node-child-by-field-name node "body"))
|
||||
(offset (save-excursion
|
||||
(goto-char start)
|
||||
(forward-line)
|
||||
(back-to-indentation)
|
||||
(- (point) start)))
|
||||
(child-nodes (treesit-node-children node)))
|
||||
(list start end offset child-nodes)))
|
||||
((or "method" "do_block" "block")
|
||||
(let* ((body
|
||||
(treesit-node-child-by-field-name node "body"))
|
||||
(start (treesit-node-start node))
|
||||
(end (treesit-node-end body))
|
||||
(offset (- (treesit-node-start body) start))
|
||||
(child-nodes (treesit-node-children node)))
|
||||
(list start end offset child-nodes)))
|
||||
("hash" (let* ((pairs (-filter (lambda (n)
|
||||
(equal (treesit-node-type n) "pair"))
|
||||
(treesit-node-children node)))
|
||||
(start (treesit-node-start node))
|
||||
(end (treesit-node-end (car (last pairs))))
|
||||
(offset (- (treesit-node-start (first pairs)) start))
|
||||
(child-nodes (treesit-node-children node)))
|
||||
(list start end offset child-nodes)))
|
||||
("array" (let* ((start (treesit-node-start node))
|
||||
(end (- (treesit-node-end node) 1))
|
||||
(offset 1)
|
||||
(child-nodes (treesit-node-children node)))
|
||||
(list start end offset child-nodes)))
|
||||
("call" (let* ((args (treesit-node-child-by-field-name node "arguments"))
|
||||
(method (treesit-node-child-by-field-name node "method"))
|
||||
(start (treesit-node-start method))
|
||||
(end (- (treesit-node-end args) 1))
|
||||
(offset (1+ (- (treesit-node-start args) start)))
|
||||
(child-nodes (list args))
|
||||
(sibling-nodes (when-let
|
||||
((block
|
||||
(treesit-node-child-by-field-name node "block")))
|
||||
(list block))))
|
||||
(list start end offset child-nodes sibling-nodes)))
|
||||
((or "then" "else") (let* ((child-nodes (treesit-node-children node))
|
||||
(start (treesit-node-start node))
|
||||
(end (treesit-node-end (car (last child-nodes))))
|
||||
(offset (- (treesit-node-start (first child-nodes)) start)))
|
||||
(list start end offset child-nodes)))
|
||||
("assignment" (let* ((right (treesit-node-child-by-field-name node "right"))
|
||||
(start (treesit-node-start node))
|
||||
(end (treesit-node-end node))
|
||||
(offset (- (treesit-node-start right) start))
|
||||
(child-nodes (list right)))
|
||||
(list start end offset child-nodes)))))))
|
||||
|
||||
(with-eval-after-load 'origami
|
||||
(add-to-list 'origami-parser-alist '(yaml-ts-mode . origami-yaml-treesit-parser))
|
||||
(add-to-list 'origami-parser-alist '(yaml-mode . origami-yaml-treesit-parser)))
|
||||
(add-to-list 'origami-parser-alist '(yaml-mode . origami-yaml-treesit-parser))
|
||||
(add-to-list 'origami-parser-alist '(ruby-ts-mode . origami-ruby-treesit-parser))
|
||||
(add-to-list 'origami-parser-alist '(ruby-mode . origami-ruby-treesit-parser)))
|
||||
|
||||
(provide 'origami-treesit)
|
||||
;;; origami-treesit.el ends here
|
||||
|
Loading…
Reference in New Issue
Block a user