58 lines
2.7 KiB
EmacsLisp
58 lines
2.7 KiB
EmacsLisp
;; -*- lexical-binding: t; -*-
|
|
|
|
;; Tree sitter is a fast parser that supports a number of programming languages
|
|
(use-package tree-sitter
|
|
:hook (after-init . global-tree-sitter-mode)
|
|
:config
|
|
(add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode)
|
|
(defun tree-sitter-first-matching-child (node pred)
|
|
"Returns the first child of `node' for which `pred' returns true."
|
|
(cl-loop for i from 0 below (tsc-count-children node)
|
|
for child = (tsc-get-nth-child node i)
|
|
if (funcall pred child) return child))
|
|
|
|
(defun tree-sitter-get-package-name ()
|
|
"Gets the identifier name of the current buffer's package (for languages that have them)."
|
|
;; TODO is there a better way to do this?
|
|
(condition-case nil
|
|
(let* ((root (tsc-root-node tree-sitter-tree))
|
|
(child (tsc-get-nth-named-child root 0)))
|
|
(when (eq (tsc-node-type child) 'package_declaration)
|
|
(tsc-node-text (tsc-get-nth-child child 1))))
|
|
(error nil)))
|
|
(defun tree-sitter-get-enclosing-function-name (pos)
|
|
"Gets the identifier name of the method or function enclosing the position `pos', if it exists."
|
|
(condition-case nil
|
|
(let ((func (tree-sitter-node-at-pos 'method_declaration pos)))
|
|
(tsc-node-text (tsc-get-child-by-field func :name)))
|
|
(error nil)))
|
|
|
|
(defun tree-sitter-get-enclosing-class-name (pos)
|
|
"Gets the identifier name of the class enclosing the position `pos', if it exists."
|
|
(condition-case nil
|
|
(let ((class (tree-sitter-node-at-pos 'class_declaration pos)))
|
|
(tsc-node-text (tsc-get-child-by-field class :name)))
|
|
(error nil)))
|
|
|
|
(defun tree-sitter-fully-qualified-class-name (pos)
|
|
"Gets the fully-qualified class name enclosing `pos', if it exists."
|
|
(when-let* ((package (tree-sitter-get-package-name))
|
|
(class (tree-sitter-get-enclosing-class-name pos)))
|
|
(format "%s.%s" package class)))
|
|
|
|
(defun tree-sitter-get-enclosing-annotations (pos)
|
|
"Returns a list of annotation name strings for the current method or class."
|
|
(when-let* ((node (or (tree-sitter-node-at-pos 'method_declaration pos)
|
|
(tree-sitter-node-at-pos 'class_declaration pos)))
|
|
(mods (tree-sitter-first-matching-child
|
|
node
|
|
(lambda (n) (eq (tsc-node-type n) 'modifiers)))))
|
|
(cl-loop for i from 0 below (tsc-count-children mods)
|
|
for child = (tsc-get-nth-child mods i)
|
|
if (not (null (tsc-get-child-by-field child :name)))
|
|
collect (tsc-node-text (tsc-get-child-by-field child :name))))))
|
|
|
|
(use-package tree-sitter-langs)
|
|
|
|
(provide 'init-tree-sitter)
|