@@ -6,7 +6,7 @@ use crate::{
66 chars::{char_is_line_ending, char_is_whitespace},
77 find_first_non_whitespace_char,
88 graphemes::{grapheme_width, tab_width_at},
9− syntax::{LanguageConfiguration, RopeProvider, Syntax},
9+ syntax::{IndentationHeuristic, LanguageConfiguration, RopeProvider, Syntax},
1010 tree_sitter::Node,
1111 Rope, RopeGraphemes, RopeSlice,
1212};
@@ -931,6 +931,7 @@ pub fn treesitter_indent_for_pos<'a>(
931931pub fn indent_for_newline(
932932 language_config: Option<&LanguageConfiguration>,
933933 syntax: Option<&Syntax>,
934+ indent_heuristic: &IndentationHeuristic,
934935 indent_style: &IndentStyle,
935936 tab_width: usize,
936937 text: RopeSlice,
@@ -939,7 +940,12 @@ pub fn indent_for_newline(
939940 current_line: usize,
940941) -> String {
941942 let indent_width = indent_style.indent_width(tab_width);
942− if let (Some(query), Some(syntax)) = (
943+ if let (
944+ IndentationHeuristic::TreeSitter | IndentationHeuristic::Hybrid,
945+ Some(query),
946+ Some(syntax),
947+ ) = (
948+ indent_heuristic,
943949 language_config.and_then(|config| config.indent_query()),
944950 syntax,
945951 ) {
@@ -953,49 +959,51 @@ pub fn indent_for_newline(
953959 line_before_end_pos,
954960 true,
955961 ) {
956− // We want to compute the indentation not only based on the
957− // syntax tree but also on the actual indentation of a previous
958− // line. This makes indentation computation more resilient to
959− // incomplete queries, incomplete source code & differing indentation
960− // styles for the same language.
961− // However, using the indent of a previous line as a baseline may not
962− // make sense, e.g. if it has a different alignment than the new line.
963− // In order to prevent edge cases with long running times, we only try
964− // a constant number of (non-empty) lines.
965− const MAX_ATTEMPTS: usize = 2;
966− let mut num_attempts = 0;
967− for line_idx in (0..=line_before).rev() {
968− let line = text.line(line_idx);
969− let first_non_whitespace_char = match find_first_non_whitespace_char(line) {
970− Some(i) => i,
971− None => {
972− continue;
962+ if let IndentationHeuristic::Hybrid = indent_heuristic {
963+ // We want to compute the indentation not only based on the
964+ // syntax tree but also on the actual indentation of a previous
965+ // line. This makes indentation computation more resilient to
966+ // incomplete queries, incomplete source code & differing indentation
967+ // styles for the same language.
968+ // However, using the indent of a previous line as a baseline may not
969+ // make sense, e.g. if it has a different alignment than the new line.
970+ // In order to prevent edge cases with long running times, we only try
971+ // a constant number of (non-empty) lines.
972+ const MAX_ATTEMPTS: usize = 2;
973+ let mut num_attempts = 0;
974+ for line_idx in (0..=line_before).rev() {
975+ let line = text.line(line_idx);
976+ let first_non_whitespace_char = match find_first_non_whitespace_char(line) {
977+ Some(i) => i,
978+ None => {
979+ continue;
980+ }
981+ };
982+ if let Some(indent) = (|| {
983+ let computed_indent = treesitter_indent_for_pos(
984+ query,
985+ syntax,
986+ tab_width,
987+ indent_width,
988+ text,
989+ line_idx,
990+ text.line_to_char(line_idx) + first_non_whitespace_char,
991+ false,
992+ )?;
993+ let leading_whitespace = line.slice(0..first_non_whitespace_char);
994+ indent.relative_indent(
995+ &computed_indent,
996+ leading_whitespace,
997+ indent_style,
998+ tab_width,
999+ )
1000+ })() {
1001+ return indent;
1002+ }
1003+ num_attempts += 1;
1004+ if num_attempts == MAX_ATTEMPTS {
1005+ break;
9731006 }
974− };
975− if let Some(indent) = (|| {
976− let computed_indent = treesitter_indent_for_pos(
977− query,
978− syntax,
979− tab_width,
980− indent_width,
981− text,
982− line_idx,
983− text.line_to_char(line_idx) + first_non_whitespace_char,
984− false,
985− )?;
986− let leading_whitespace = line.slice(0..first_non_whitespace_char);
987− indent.relative_indent(
988− &computed_indent,
989− leading_whitespace,
990− indent_style,
991− tab_width,
992− )
993− })() {
994− return indent;
995− }
996− num_attempts += 1;
997− if num_attempts == MAX_ATTEMPTS {
998− break;
9991007 }
10001008 }
10011009 return indent.to_string(indent_style, tab_width);