Allow multiple `#not-kind-eq?` predicates in indent queries

This fixes a regression from the switch to tree-house with one of the
custom predicates in indent queries: `#not-kind-eq?`. This predicate
should be allowed to be written multiple times in a pattern. For example
in the Go indents:

    ; Switches and selects aren't indented, only their case bodies are.
    ; Outdent all closing braces except those closing switches or selects.
    (
        (_ "}" @outdent) @outer
        (#not-kind-eq? @outer "select_statement")
        (#not-kind-eq? @outer "type_switch_statement")
        (#not-kind-eq? @outer "expression_switch_statement")
    )

So instead of an `Option<T>` of one we need a `Vec<T>` and we need to
check that all of these predicates are individually satisfied (basically
`iter().all(/* node kind is not expected kind for that capture */)`).
pull/13675/merge
Michael Davis 2025-06-06 12:10:44 -04:00
parent 25b299abc5
commit b1f4717356
No known key found for this signature in database
1 changed files with 9 additions and 9 deletions

View File

@ -297,7 +297,7 @@ fn is_first_in_line(node: &Node, text: RopeSlice, new_line_byte_pos: Option<u32>
#[derive(Debug, Default)]
pub struct IndentQueryPredicates {
not_kind_eq: Option<(Capture, Box<str>)>,
not_kind_eq: Vec<(Capture, Box<str>)>,
same_line: Option<(Capture, Capture, bool)>,
one_line: Option<(Capture, bool)>,
}
@ -309,12 +309,9 @@ impl IndentQueryPredicates {
text: RopeSlice,
new_line_byte_pos: Option<u32>,
) -> bool {
if let Some((capture, not_expected_kind)) = self.not_kind_eq.as_ref() {
if !match_
.nodes_for_capture(*capture)
.next()
.is_some_and(|node| node.kind() != not_expected_kind.as_ref())
{
for (capture, not_expected_kind) in self.not_kind_eq.iter() {
let node = match_.nodes_for_capture(*capture).next();
if node.is_some_and(|n| n.kind() == not_expected_kind.as_ref()) {
return false;
}
}
@ -394,8 +391,11 @@ impl IndentQuery {
let capture = predicate.capture_arg(0)?;
let not_expected_kind = predicate.str_arg(1)?;
predicates.entry(pattern).or_default().not_kind_eq =
Some((capture, not_expected_kind.to_string().into_boxed_str()));
predicates
.entry(pattern)
.or_default()
.not_kind_eq
.push((capture, not_expected_kind.into()));
Ok(())
}
"same-line?" | "not-same-line?" => {