elisp-tree-sitter icon indicating copy to clipboard operation
elisp-tree-sitter copied to clipboard

Integration with expand-region

Open ubolonton opened this issue 4 years ago • 1 comments

The basic idea is simple: walking up the syntax tree from node at point.

Below is a simple implementation that expands region to the next bigger node:

(defun tree-sitter-mark-bigger-node ()
  (interactive)
  (let* ((p (point))
         (m (or (mark) p))
         (beg (min p m))
         (end (max p m))
         (root (ts-root-node tree-sitter-tree))
         (node (ts-get-descendant-for-position-range root beg end))
         (node-beg (ts-node-start-position node))
         (node-end (ts-node-end-position node)))
    ;; Node fits the region exactly. Try its parent node instead.
    (when (and (= beg node-beg) (= end node-end))
      (when-let ((node (ts-get-parent node)))
        (setq node-beg (ts-node-start-position node)
              node-end (ts-node-end-position node))))
    (set-mark node-end)
    (goto-char node-beg)))

(setq er/try-expand-list (append er/try-expand-list
                                 '(tree-sitter-mark-bigger-node)))

ubolonton avatar Feb 06 '20 17:02 ubolonton

Hi! This seems to work fine. Here's a small adjustment to use non-obsolete tree-sitter functions, etc.

(defun tree-sitter-mark-bigger-node ()
  (interactive)
  (let* ((root (tsc-root-node tree-sitter-tree))
         (node (tsc-get-descendant-for-position-range root (region-beginning) (region-end)))
         (node-start (tsc-node-start-position node))
         (node-end (tsc-node-end-position node)))
    ;; Node fits the region exactly. Try its parent node instead.
    (when (and (= (region-beginning) node-start) (= (region-end) node-end))
      (when-let ((node (tsc-get-parent node)))
        (setq node-start (tsc-node-start-position node)
              node-end (tsc-node-end-position node))))
    (set-mark node-end)
    (goto-char node-start)))

skrytebane avatar Dec 15 '22 07:12 skrytebane