Add treesit-simple-indent-standalone-predicate (bug#74386)
* lisp/treesit.el: (treesit-simple-indent-standalone-predicate): New variable. (treesit-simple-indent-presets): Use the predicate. (treesit-simple-indent-presets): Update docstring. * lisp/progmodes/c-ts-common.el: (c-ts-common--standalone-parent): (c-ts-common--prev-standalone-sibling): Use the predicate if non-nil. Also, handle method chaining by default. * doc/lispref/modes.texi (Parser-based Indentation): Add documentation.
This commit is contained in:
parent
b8c8ae92db
commit
4b020b936c
3 changed files with 86 additions and 15 deletions
|
@ -5416,11 +5416,14 @@ on the line which @var{parent}'s start is on.
|
|||
|
||||
@item standalone-parent
|
||||
This anchor is a function that is called with 3 arguments: @var{node},
|
||||
@var{parent}, and @var{bol}. It finds the first ancestor node
|
||||
(parent, grandparent, etc.@:) of @var{node} that starts on its own
|
||||
line, and return the start of that node. ``Starting on its own line''
|
||||
means there is only whitespace character before the node on the line
|
||||
which the node's start is on.
|
||||
@var{parent}, and @var{bol}. It finds the first ancestor node (parent,
|
||||
grandparent, etc.@:) of @var{node} that starts on its own line, and
|
||||
return the start of that node. ``Starting on its own line'' means there
|
||||
is only whitespace character before the node on the line which the
|
||||
node's start is on. The exact definition of ``Starting on its own
|
||||
line'' can be relaxed by setting
|
||||
@code{treesit-simple-indent-standalone-predicate}, some major mode might
|
||||
want to do that for easier indentation for method chaining.
|
||||
|
||||
@item prev-sibling
|
||||
This anchor is a function that is called with 3 arguments: @var{node},
|
||||
|
|
|
@ -558,26 +558,52 @@ const a = [
|
|||
"Find the first parent that starts on a new line.
|
||||
Start searching from PARENT, so if PARENT satisfies the condition, it'll
|
||||
be returned. Return the starting position of the parent, return nil if
|
||||
no parent satisfies the condition."
|
||||
no parent satisfies the condition.
|
||||
|
||||
Unlike simple-indent's standalone preset, this function handles method
|
||||
chaining like
|
||||
|
||||
func
|
||||
.method() <-- Considered standalone even if there's a \".\" in
|
||||
.method() front of the node.
|
||||
|
||||
But ff `treesit-simple-indent-standalone-predicate' is non-nil, use that
|
||||
for determining standlone line."
|
||||
(save-excursion
|
||||
(catch 'term
|
||||
(while parent
|
||||
(goto-char (treesit-node-start parent))
|
||||
(when (looking-back (rx bol (* whitespace))
|
||||
(line-beginning-position))
|
||||
(when (if treesit-simple-indent-standalone-predicate
|
||||
(funcall treesit-simple-indent-standalone-predicate
|
||||
parent)
|
||||
(looking-back (rx bol (* whitespace) (? "."))
|
||||
(line-beginning-position)))
|
||||
(throw 'term (point)))
|
||||
(setq parent (treesit-node-parent parent))))))
|
||||
|
||||
(defun c-ts-common--prev-standalone-sibling (node)
|
||||
"Return the previous sibling of NODE that starts on a new line.
|
||||
Return nil if no sibling satisfies the condition."
|
||||
Return nil if no sibling satisfies the condition.
|
||||
|
||||
Unlike simple-indent's standalone preset, this function handles method
|
||||
chaining like
|
||||
|
||||
func
|
||||
.method() <-- Considered standalone even if there's a \".\" in
|
||||
.method() front of the node.
|
||||
|
||||
But ff `treesit-simple-indent-standalone-predicate' is non-nil, use that
|
||||
for determining standlone line."
|
||||
(save-excursion
|
||||
(setq node (treesit-node-prev-sibling node 'named))
|
||||
(goto-char (treesit-node-start node))
|
||||
(while (and node
|
||||
(goto-char (treesit-node-start node))
|
||||
(not (looking-back (rx bol (* whitespace))
|
||||
(pos-bol))))
|
||||
(not (if treesit-simple-indent-standalone-predicate
|
||||
(funcall treesit-simple-indent-standalone-predicate
|
||||
node)
|
||||
(looking-back (rx bol (* whitespace) (? "."))
|
||||
(pos-bol)))))
|
||||
(setq node (treesit-node-prev-sibling node 'named)))
|
||||
node))
|
||||
|
||||
|
@ -629,7 +655,13 @@ This rule tries to be smart and ignore proprocessor node in some
|
|||
situations. By default, any node that has \"proproc\" in its type are
|
||||
considered a preprocessor node. If that heuristic is inaccurate, define
|
||||
a `preproc' thing in `treesit-thing-settings', and this rule will use
|
||||
the thing definition instead."
|
||||
the thing definition instead.
|
||||
|
||||
The rule also handles method chaining like
|
||||
|
||||
func
|
||||
.method() <-- Considered \"starts at a newline\" even if there's
|
||||
.method() a \".\" in front of the node."
|
||||
(let ((prev-line-node (treesit--indent-prev-line-node bol))
|
||||
(offset (symbol-value c-ts-common-indent-offset)))
|
||||
(cond
|
||||
|
|
|
@ -1792,6 +1792,37 @@ over `treesit-simple-indent-rules'.")
|
|||
(back-to-indentation)
|
||||
(treesit--indent-largest-node-at (point)))))
|
||||
|
||||
(defvar treesit-simple-indent-standalone-predicate nil
|
||||
"Function used to determine if a node is \"standalone\".
|
||||
|
||||
\"Standalone\" means the node starts on a new line. For example, if we
|
||||
look at the opening bracket, then it's standalone in this case:
|
||||
|
||||
{ <-- Standalone.
|
||||
return 1;
|
||||
}
|
||||
|
||||
but not in this case:
|
||||
|
||||
if (true) { <-- Not standalone.
|
||||
return 1;
|
||||
}
|
||||
|
||||
The value of this variable affects the `standalone-parent' indent preset
|
||||
for treesit-simple-indent. If the value is nil, the standlone condition
|
||||
is as described. Some major mode might want to relax the condition a
|
||||
little bit, so that it ignores some punctuation like \".\". For
|
||||
example, a Javascript mode might want to consider the method call below
|
||||
to be standalone too:
|
||||
|
||||
obj
|
||||
.method(() => { <-- Consider \".method\" to be standalone,
|
||||
return 1; <-- so this line anchors on \".method\".
|
||||
});
|
||||
|
||||
The value should be a function that takes a node, and return t if it's
|
||||
standalone.")
|
||||
|
||||
(defvar treesit-simple-indent-presets
|
||||
(list (cons 'match
|
||||
(lambda
|
||||
|
@ -1931,8 +1962,10 @@ over `treesit-simple-indent-rules'.")
|
|||
(catch 'term
|
||||
(while parent
|
||||
(goto-char (treesit-node-start parent))
|
||||
(when (looking-back (rx bol (* whitespace))
|
||||
(line-beginning-position))
|
||||
(when (if (null treesit-simple-indent-standalone-predicate)
|
||||
(looking-back (rx bol (* whitespace))
|
||||
(line-beginning-position))
|
||||
(funcall parent))
|
||||
(throw 'term (point)))
|
||||
(setq parent (treesit-node-parent parent)))))))
|
||||
(cons 'prev-sibling (lambda (node parent bol &rest _)
|
||||
|
@ -2065,7 +2098,10 @@ parent-bol
|
|||
standalone-parent
|
||||
|
||||
Finds the first ancestor node (parent, grandparent, etc.) that
|
||||
starts on its own line, and returns the start of that node.
|
||||
starts on its own line, and returns the start of that node. The
|
||||
definition of \"standalone\" can be customized by setting
|
||||
`treesit-simple-indent-standalone-predicate'. Some major mode might
|
||||
want to do that for easier indentation for method chaining.
|
||||
|
||||
prev-sibling
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue