diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index b8f0d0a84961..1111e4a14e9f 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -267,39 +267,54 @@ fn get_first_in_line(mut node: Node, byte_pos: usize, new_line: bool) -> Vec(query_node: &IndentQueryNode, node: Node<'a>, cursor: &mut TreeCursor<'a>) -> bool { match query_node { IndentQueryNode::SimpleNode(_) => true, IndentQueryNode::ComplexNode { kind: _, - field_name, + kind_not_in, parent_kind_in, + field_name_in, } => { + if let Some(kind_not_in) = kind_not_in { + let kind = node.kind(); + if kind_not_in.iter().any(|k| k == kind) { + return false; + } + } if let Some(parent_kind_in) = parent_kind_in { let parent_matches = node.parent().map_or(false, |p| { - parent_kind_in.iter().any(|kind| kind.as_str() == p.kind()) + let parent_kind = p.kind(); + parent_kind_in + .iter() + .any(|kind| kind.as_str() == parent_kind) }); if !parent_matches { return false; } } - if let Some(field_name) = field_name { + if let Some(field_name_in) = field_name_in { let parent = match node.parent() { None => { return false; } Some(p) => p, }; - let mut found_child = false; - for child in parent.children_by_field_name(field_name, cursor) { - if child == node { - found_child = true; + cursor.reset(parent); + debug_assert!(cursor.goto_first_child()); + loop { + if cursor.node() == node { + if let Some(cursor_name) = cursor.field_name() { + if !field_name_in.iter().any(|n| n == cursor_name) { + return false; + } + } else { + return false; + } break; } - } - if !found_child { - return false; + debug_assert!(cursor.goto_next_sibling()); } } true @@ -525,6 +540,25 @@ mod test { really_long_variable_name_using_up_the_line |= really_long_fn_that_should_definitely_go_on_the_next_line(); + let ( + a_long_variable_name_in_this_tuple, + b_long_variable_name_in_this_tuple, + c_long_variable_name_in_this_tuple, + d_long_variable_name_in_this_tuple, + e_long_variable_name_in_this_tuple, + ): (usize, usize, usize, usize, usize) = + if really_long_fn_that_should_definitely_go_on_the_next_line() { + ( + 03294239434, + 1213412342314, + 21231234134, + 834534234549898789, + 9879234234543853457, + ) + } else { + (0, 1, 2, 3, 4) + }; + let test_function = function_with_param(this_param, that_param ); diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 08ecbf7ccb77..42a2832c763c 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -114,8 +114,9 @@ pub enum IndentQueryNode { // A node given by a list of characteristics which must all be fulfilled in order to match ComplexNode { kind: Option, - field_name: Option, + kind_not_in: Option>, parent_kind_in: Option>, + field_name_in: Option>, }, } impl IndentQueryNode { diff --git a/runtime/queries/c/indents.toml b/runtime/queries/c/indents.toml index f4076e171c10..4da7a05bd856 100644 --- a/runtime/queries/c/indents.toml +++ b/runtime/queries/c/indents.toml @@ -1,4 +1,10 @@ -indent = [ +[indent] +all = [ + # Indent non-grouped bodies of if-, while- and do-while-statements. + # TODO Add indent for the for-statement (ideally the body of a for-statement should have a field name in the tree-sitter grammar) + { kind_not_in = ["compound_statement"], parent_kind_in = ["if_statement", "while_statement", "do_statement"], field_name_in = ["consequence", "body"] } +] +tail = [ "compound_statement", "field_declaration_list", "enumerator_list", @@ -9,7 +15,8 @@ indent = [ "expression_statement", ] -outdent = [ +[outdent] +all = [ "case", "}", "]", diff --git a/runtime/queries/cmake/indents.toml b/runtime/queries/cmake/indents.toml index 8b886a4fb3dc..590a25551641 100644 --- a/runtime/queries/cmake/indents.toml +++ b/runtime/queries/cmake/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ "if_condition", "foreach_loop", "while_loop", @@ -7,6 +7,6 @@ indent = [ "normal_command", ] -outdent = [ +outdent.all = [ ")" ] diff --git a/runtime/queries/cpp/indents.toml b/runtime/queries/cpp/indents.toml index 0ca2ed8bf7f7..46713c13ef8a 100644 --- a/runtime/queries/cpp/indents.toml +++ b/runtime/queries/cpp/indents.toml @@ -1,4 +1,10 @@ -indent = [ +[indent] +all = [ + # Indent non-grouped bodies of if-, while- and do-while-statements. + # TODO Add indent for the for-statement (ideally the body of a for-statement should have a field name in the tree-sitter grammar) + { kind_not_in = ["compound_statement"], parent_kind_in = ["if_statement", "while_statement", "do_statement"], field_name_in = ["consequence", "body"] } +] +tail = [ "compound_statement", "field_declaration_list", "enumerator_list", @@ -9,7 +15,8 @@ indent = [ "expression_statement", ] -outdent = [ +[outdent] +all = [ "case", "access_specifier", "}", diff --git a/runtime/queries/dart/indents.toml b/runtime/queries/dart/indents.toml index 5c11e05dd859..151dced156db 100644 --- a/runtime/queries/dart/indents.toml +++ b/runtime/queries/dart/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ "class_body", "function_body", "function_expression_body", @@ -13,7 +13,7 @@ indent = [ "arguments" ] -outdent = [ +outdent.all = [ "}", "]", ")" diff --git a/runtime/queries/fish/indents.toml b/runtime/queries/fish/indents.toml index 6f1e563ae069..88fbfd3a33f2 100644 --- a/runtime/queries/fish/indents.toml +++ b/runtime/queries/fish/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ "function_definition", "while_statement", "for_statement", @@ -7,6 +7,6 @@ indent = [ "switch_statement", ] -outdent = [ +outdent.all = [ "end" ] diff --git a/runtime/queries/glsl/indents.toml b/runtime/queries/glsl/indents.toml index a7fd499a9239..f7878baf40fd 100644 --- a/runtime/queries/glsl/indents.toml +++ b/runtime/queries/glsl/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ "init_declarator", "compound_statement", "preproc_arg", @@ -10,7 +10,7 @@ indent = [ "compound_literal_expression" ] -outdent = [ +outdent.all = [ "#define", "#ifdef", "#endif", diff --git a/runtime/queries/javascript/indents.toml b/runtime/queries/javascript/indents.toml index 9d711ab23d4c..5415726d01d4 100644 --- a/runtime/queries/javascript/indents.toml +++ b/runtime/queries/javascript/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ "array", "object", "arguments", @@ -21,7 +21,7 @@ indent = [ "object_type", ] -outdent = [ +outdent.all = [ "}", "]", ")" diff --git a/runtime/queries/json/indents.toml b/runtime/queries/json/indents.toml index 64a8d1757f09..80a91c345f24 100644 --- a/runtime/queries/json/indents.toml +++ b/runtime/queries/json/indents.toml @@ -1,9 +1,9 @@ -indent = [ +indent.tail = [ "object", "array" ] -outdent = [ +outdent.all = [ "]", "}" ] diff --git a/runtime/queries/llvm-mir-yaml/indents.toml b/runtime/queries/llvm-mir-yaml/indents.toml index ddc3578b1420..499994f7a190 100644 --- a/runtime/queries/llvm-mir-yaml/indents.toml +++ b/runtime/queries/llvm-mir-yaml/indents.toml @@ -1,3 +1,3 @@ -indent = [ +indent.tail = [ "block_mapping_pair", ] diff --git a/runtime/queries/llvm-mir/indents.toml b/runtime/queries/llvm-mir/indents.toml index 6a70e5adc2ab..f372dbb61df6 100644 --- a/runtime/queries/llvm-mir/indents.toml +++ b/runtime/queries/llvm-mir/indents.toml @@ -1,7 +1,7 @@ -indent = [ +indent.tail = [ "basic_block", ] -outdent = [ +outdent.all = [ "label", ] diff --git a/runtime/queries/llvm/indents.toml b/runtime/queries/llvm/indents.toml index 8cd603c8e668..ec2e2dfe293b 100644 --- a/runtime/queries/llvm/indents.toml +++ b/runtime/queries/llvm/indents.toml @@ -1,8 +1,8 @@ -indent = [ +indent.tail = [ "function_body", "instruction", ] -outdent = [ +outdent.all = [ "}", ] diff --git a/runtime/queries/lua/indents.toml b/runtime/queries/lua/indents.toml index df1a9752a043..e2cf429ede68 100644 --- a/runtime/queries/lua/indents.toml +++ b/runtime/queries/lua/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ "function_definition", "variable_declaration", "local_variable_declaration", diff --git a/runtime/queries/nix/indents.toml b/runtime/queries/nix/indents.toml index b92ab752df99..1d5c487187c6 100644 --- a/runtime/queries/nix/indents.toml +++ b/runtime/queries/nix/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ # "function", "bind", "assert", @@ -12,7 +12,7 @@ indent = [ "parenthesized", ] -outdent = [ +outdent.all = [ "}", "]", ] diff --git a/runtime/queries/ocaml/indents.toml b/runtime/queries/ocaml/indents.toml index 7586b83a0f42..660c34df0e9a 100644 --- a/runtime/queries/ocaml/indents.toml +++ b/runtime/queries/ocaml/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ "let_binding", "type_binding", "structure", @@ -8,6 +8,6 @@ indent = [ "match_case", ] -outdent = [ +outdent.all = [ "}", ] diff --git a/runtime/queries/perl/indents.toml b/runtime/queries/perl/indents.toml index 365e0663601d..6116b26b98c0 100644 --- a/runtime/queries/perl/indents.toml +++ b/runtime/queries/perl/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ "function", "identifier", "method_invocation", @@ -12,6 +12,6 @@ indent = [ "word_list_qw" ] -outdent = [ +outdent.all = [ "}" ] diff --git a/runtime/queries/php/indents.toml b/runtime/queries/php/indents.toml index 85c104db55cd..2f30c6d1829c 100644 --- a/runtime/queries/php/indents.toml +++ b/runtime/queries/php/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ "array_creation_expression", "arguments", "formal_parameters", diff --git a/runtime/queries/protobuf/indents.toml b/runtime/queries/protobuf/indents.toml index e655f8db6463..f0155d559524 100644 --- a/runtime/queries/protobuf/indents.toml +++ b/runtime/queries/protobuf/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ "messageBody", "enumBody", "oneofBody", @@ -7,6 +7,6 @@ indent = [ "msgLit", ] -outdent = [ +outdent.all = [ "}", ] diff --git a/runtime/queries/python/indents.toml b/runtime/queries/python/indents.toml index 6bc684864bbe..a458c5715666 100644 --- a/runtime/queries/python/indents.toml +++ b/runtime/queries/python/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ "list", "tuple", "dictionary", @@ -27,7 +27,7 @@ indent = [ "class_definition", ] -outdent = [ +outdent.all = [ ")", "]", "}", diff --git a/runtime/queries/ruby/indents.toml b/runtime/queries/ruby/indents.toml index b417751fc80c..5549739028e1 100644 --- a/runtime/queries/ruby/indents.toml +++ b/runtime/queries/ruby/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ "argument_list", "array", "begin", @@ -16,7 +16,7 @@ indent = [ "singleton_method", ] -outdent = [ +outdent.all = [ ")", "}", "]", diff --git a/runtime/queries/rust/indents.toml b/runtime/queries/rust/indents.toml index bdf0e10a99dd..07c5b8f45560 100644 --- a/runtime/queries/rust/indents.toml +++ b/runtime/queries/rust/indents.toml @@ -1,7 +1,7 @@ [indent] all = [ - { parent_kind_in = ["assignment_expression", "compound_assignment_expr"], field_name = "right"}, - { parent_kind_in = ["let_declaration"], field_name = "value" } + { parent_kind_in = ["assignment_expression", "compound_assignment_expr"], field_name_in = ["right"]}, + { parent_kind_in = ["let_declaration"], field_name_in = ["value"] } ] tail = [ "use_list", diff --git a/runtime/queries/scala/indents.toml b/runtime/queries/scala/indents.toml index 6de548442ab2..a34f0f2992ff 100644 --- a/runtime/queries/scala/indents.toml +++ b/runtime/queries/scala/indents.toml @@ -1,5 +1,5 @@ -indent = [ +indent.tail = [ "block", "arguments", "parameter", @@ -16,7 +16,7 @@ indent = [ "match_expression" ] -outdent = [ +outdent.all = [ "}", "]", ")" diff --git a/runtime/queries/svelte/indents.toml b/runtime/queries/svelte/indents.toml index 693db8e3dab2..b04247d7557e 100644 --- a/runtime/queries/svelte/indents.toml +++ b/runtime/queries/svelte/indents.toml @@ -1,11 +1,11 @@ -indent = [ +indent.tail = [ "element" "if_statement" "each_statement" "await_statement" ] -outdent = [ +outdent.all = [ "end_tag" "else_statement" "if_end_expr" diff --git a/runtime/queries/tablegen/indents.toml b/runtime/queries/tablegen/indents.toml index 43532f4d4ad6..abea12f2e54c 100644 --- a/runtime/queries/tablegen/indents.toml +++ b/runtime/queries/tablegen/indents.toml @@ -1,7 +1,7 @@ -indent = [ +indent.tail = [ "statement", ] -outdent = [ +outdent.all = [ "}", ] diff --git a/runtime/queries/yaml/indents.toml b/runtime/queries/yaml/indents.toml index ddc3578b1420..499994f7a190 100644 --- a/runtime/queries/yaml/indents.toml +++ b/runtime/queries/yaml/indents.toml @@ -1,3 +1,3 @@ -indent = [ +indent.tail = [ "block_mapping_pair", ] diff --git a/runtime/queries/zig/indents.toml b/runtime/queries/zig/indents.toml index 36ba8e55895c..234992dec957 100644 --- a/runtime/queries/zig/indents.toml +++ b/runtime/queries/zig/indents.toml @@ -1,4 +1,4 @@ -indent = [ +indent.tail = [ "Block", "BlockExpr", "ContainerDecl", @@ -9,7 +9,7 @@ indent = [ "InitList" ] -outdent = [ +outdent.all = [ "}", "]", ")"