diff --git a/Cargo.lock b/Cargo.lock index 896902cfc1..f0dbf7c688 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7050,6 +7050,7 @@ dependencies = [ "pet-fs", "pet-poetry", "pet-reporter", + "pretty_assertions", "project", "regex", "rope", diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index dd798f4877..b47e2ba78b 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -2897,12 +2897,19 @@ impl BufferSnapshot { let mut indent_from_prev_row = false; let mut outdent_from_prev_row = false; let mut outdent_to_row = u32::MAX; + let mut from_regex = false; while let Some((indent_row, delta)) = indent_changes.peek() { match indent_row.cmp(&row) { Ordering::Equal => match delta { - Ordering::Less => outdent_from_prev_row = true, - Ordering::Greater => indent_from_prev_row = true, + Ordering::Less => { + from_regex = true; + outdent_from_prev_row = true + } + Ordering::Greater => { + indent_from_prev_row = true; + from_regex = true + } _ => {} }, @@ -2935,32 +2942,32 @@ impl BufferSnapshot { Some(IndentSuggestion { basis_row: prev_row, delta: Ordering::Equal, - within_error, + within_error: within_error && !from_regex, }) } else if indent_from_prev_row { Some(IndentSuggestion { basis_row: prev_row, delta: Ordering::Greater, - within_error, + within_error: within_error && !from_regex, }) } else if outdent_to_row < prev_row { Some(IndentSuggestion { basis_row: outdent_to_row, delta: Ordering::Equal, - within_error, + within_error: within_error && !from_regex, }) } else if outdent_from_prev_row { Some(IndentSuggestion { basis_row: prev_row, delta: Ordering::Less, - within_error, + within_error: within_error && !from_regex, }) } else if config.auto_indent_using_last_non_empty_line || !self.is_line_blank(prev_row) { Some(IndentSuggestion { basis_row: prev_row, delta: Ordering::Equal, - within_error, + within_error: within_error && !from_regex, }) } else { None diff --git a/crates/languages/Cargo.toml b/crates/languages/Cargo.toml index 23f59beb17..3d51f748c1 100644 --- a/crates/languages/Cargo.toml +++ b/crates/languages/Cargo.toml @@ -94,3 +94,4 @@ tree-sitter-go.workspace = true tree-sitter-c.workspace = true tree-sitter-css.workspace = true tree-sitter-bash.workspace = true +pretty_assertions.workspace = true diff --git a/crates/languages/src/bash.rs b/crates/languages/src/bash.rs index ef9a18a9c5..3f37926d48 100644 --- a/crates/languages/src/bash.rs +++ b/crates/languages/src/bash.rs @@ -22,6 +22,8 @@ mod tests { use language::{language_settings::AllLanguageSettings, AutoindentMode, Buffer}; use settings::SettingsStore; use std::num::NonZeroU32; + use unindent::Unindent; + use util::test::marked_text_offsets; #[gpui::test] async fn test_bash_autoindent(cx: &mut TestAppContext) { @@ -111,6 +113,40 @@ mod tests { "foo() {\n echo \"Hello, World!\"\n}", ); + let (input, offsets) = marked_text_offsets( + &r#" + if foo; then + 1ˇ + else + 3 + fi + "# + .unindent(), + ); + + buffer.edit([(0..buffer.len(), input)], None, cx); + buffer.edit( + [(offsets[0]..offsets[0], "\n")], + Some(AutoindentMode::EachLine), + cx, + ); + buffer.edit( + [(offsets[0] + 3..offsets[0] + 3, "elif")], + Some(AutoindentMode::EachLine), + cx, + ); + let expected = r#" + if foo; then + 1 + elif + else + 3 + fi + "# + .unindent(); + + pretty_assertions::assert_eq!(buffer.text(), expected); + buffer }); } diff --git a/crates/languages/src/bash/config.toml b/crates/languages/src/bash/config.toml index 91d01d6270..9f1cfe4a35 100644 --- a/crates/languages/src/bash/config.toml +++ b/crates/languages/src/bash/config.toml @@ -24,5 +24,5 @@ brackets = [ ### fi ### ``` increase_indent_pattern = "(\\s*|;)(do|then|in|else|elif)\\b.*$" -decrease_indent_pattern = "(\\s*|;)(fi|done|esac|else|elif)\\b.*$" +decrease_indent_pattern = "(\\s*|;)\\b(fi|done|esac|else|elif)\\b.*$" # make sure to test each line mode & block mode