From 7ac578c57ce14a6f5e4568712ec16ebcbc9cc9ba Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Thu, 13 Feb 2025 21:49:55 -0800 Subject: [PATCH] Use a heuristic to support method chaining in c-ts-common Test for "." at the beginning of a line to detect chained method. * lisp/progmodes/c-ts-common.el: (c-ts-common--standalone-predicate): New function. (c-ts-common--standalone-parent): (c-ts-common--prev-standalone-sibling): Use the new heuristic. --- lisp/progmodes/c-ts-common.el | 44 +++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/lisp/progmodes/c-ts-common.el b/lisp/progmodes/c-ts-common.el index 7d3ea76cb1b..c3a965b8e94 100644 --- a/lisp/progmodes/c-ts-common.el +++ b/lisp/progmodes/c-ts-common.el @@ -554,6 +554,32 @@ const a = [ 4, 5, 6, ];") +(defun c-ts-common--standalone-predicate (node) + "Return an anchor if NODE is on the start of a line. + +Return nil if not. Handles method chaining. Caller needs to cal +`save-excursion'." + (goto-char (treesit-node-start node)) + (or (and (looking-back (rx bol (* whitespace) (? ".")) + (line-beginning-position)) + (point)) + ;; The above check is not enough, because often in a method + ;; chaining, the method name is part of a node, and the arg list + ;; is another node: + ;; + ;; func ---> func.method is one node. + ;; .method({ + ;; return 1; ({ return 1; }) is another node + ;; }) + ;; + ;; So when we go up the parse tree, we go through the block + ;; ({...}), then the next parent is already the whole call + ;; expression, and we never stops at the beginning of "method". + ;; Therefore we need this heuristic. + (and (progn (back-to-indentation) + (eq (char-after) ?.)) + (point)))) + (defun c-ts-common--standalone-parent (parent) "Find the first parent that starts on a new line. Start searching from PARENT, so if PARENT satisfies the condition, it'll @@ -574,12 +600,11 @@ for determining standlone line." (catch 'term (while parent (goto-char (treesit-node-start parent)) - (when (if treesit-simple-indent-standalone-predicate - (setq anchor + (when (setq anchor + (if treesit-simple-indent-standalone-predicate (funcall treesit-simple-indent-standalone-predicate - parent)) - (looking-back (rx bol (* whitespace) (? ".")) - (line-beginning-position))) + parent) + (c-ts-common--standalone-predicate parent))) (throw 'term (if (numberp anchor) anchor (point)))) (setq parent (treesit-node-parent parent))))))) @@ -602,13 +627,12 @@ for determining standlone line." (let (anchor) (while (and node (goto-char (treesit-node-start node)) - (not (if treesit-simple-indent-standalone-predicate - (setq anchor + (not (setq anchor + (if treesit-simple-indent-standalone-predicate (funcall treesit-simple-indent-standalone-predicate - node)) - (looking-back (rx bol (* whitespace) (? ".")) - (pos-bol))))) + parent) + (c-ts-common--standalone-predicate parent))))) (setq node (treesit-node-prev-sibling node 'named)))) (if (numberp anchor) anchor (treesit-node-start node))))