Make origami-treesit more generic

This commit is contained in:
jdormit 2024-05-04 22:02:51 -04:00
parent 81106aae04
commit f7c927bca1
3 changed files with 100 additions and 27 deletions

View File

@ -149,6 +149,9 @@
(when-let ((path (origami-fold-find-path-containing tree point)))
(let ((parent (origami-fold-parent path)))
(dolist (fold (origami-fold-children parent))
(origami-toggle-node buffer (origami-fold-beg fold))))))))
(origami-toggle-node buffer (origami-fold-beg fold)))))))
(defun origami-setup ()
(evil-local-set-key 'normal (kbd "zM") #'origami-toggle-all-nodes-same-level))
(add-hook 'origami-mode-hook #'origami-setup))
(provide 'init-editing)

View File

@ -107,32 +107,12 @@
(->> (treesit-query-capture args '((string (string_content) @name)))
(-filter (lambda (n) (eq (car n) 'name)))
(-map #'cdr)
(-mapcat (lambda (n) (treesit-node-text n t))))))
(-mapcat (lambda (n) (treesit-node-text n t)))))))
(defun origami-yaml-treesit-parser (create)
(lambda (content)
(let* ((parser (treesit-parser-create 'yaml))
(root (treesit-parser-root-node parser)))
(cl-labels ((get-node-folds (node)
(if (equal (treesit-node-type node) "block_mapping_pair")
(let ((key-node (treesit-node-child-by-field-name node "key"))
(value-node (treesit-node-child-by-field-name node "value")))
(list (funcall create
(save-excursion
(goto-char (treesit-node-start node))
(line-beginning-position))
(treesit-node-end node)
(save-excursion
(goto-char (treesit-node-start key-node))
(+ 1 (- (treesit-node-end key-node) (line-beginning-position))))
(-mapcat #'get-node-folds (treesit-node-children value-node)))))
(-mapcat #'get-node-folds (treesit-node-children node)))))
(get-node-folds root)))))
(with-eval-after-load 'origami
(add-to-list 'origami-parser-alist '(yaml-ts-mode . origami-yaml-treesit-parser))
(defun yaml-ts-origami-setup ()
(evil-local-set-key 'normal (kbd "zM") #'origami-toggle-all-nodes-same-level))
(add-hook 'yaml-ts-mode-hook #'yaml-ts-origami-setup)))
(use-package origami-treesit
:straight (:type built-in)
:ensure nil
:load-path "packages/origami-treesit"
:after origami)
(provide 'init-treesit)

View File

@ -0,0 +1,90 @@
;;; origami-treesit.el --- treesit.el integration with origami.el text folding -*- lexical-binding: t; -*-
;; Copyright (C) 2024 Jeremy Dormitzer
;; Author: Jeremy Dormitzer <jeremy.dormitzer@gmail.com>
;; Version: 0.1.0
;; Package-Requires: ((emacs "29.1") (origami "1.0") (dash "2.19.1") (cl-lib "1.0"))
;; Keywords: tools
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; Adds origami parsers based on tree-sitter.
;;; Code:
(require 'treesit)
(require 'cl-lib)
(require 'dash)
(cl-defun make-treesit-parser (create
lang
&key
node-matcher-fn
fold-fn)
(lambda (content)
(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))))
(-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")))
:fold-fn (lambda (node)
(pcase (treesit-node-type node)
((or "block_mapping_pair" "flow_pair")
(let* ((key-node (treesit-node-child-by-field-name node "key"))
(value-node (treesit-node-child-by-field-name node "value"))
(line-beginning (save-excursion
(goto-char (treesit-node-start node))
(line-beginning-position)))
(on-own-line? (= (save-excursion
(goto-char (treesit-node-start node))
(back-to-indentation)
(point))
(treesit-node-start node)))
(start (save-excursion
(goto-char (treesit-node-start node))
(if on-own-line?
line-beginning
(treesit-node-start node))))
(end (treesit-node-end node))
(offset (+ 1 (if on-own-line?
(- (treesit-node-end key-node) line-beginning)
(length (treesit-node-text key-node t)))))
(child-nodes (treesit-node-children value-node)))
(list start end offset child-nodes)))
((or "flow_mapping" "flow_sequence")
(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)))))))
(with-eval-after-load 'origami
(add-to-list 'origami-parser-alist '(yaml-ts-mode . origami-yaml-treesit-parser)))
(provide 'origami-treesit)
;;; origami-treesit.el ends here