Cargo.lock 🔗
@@ -7050,6 +7050,7 @@ dependencies = [
"pet-fs",
"pet-poetry",
"pet-reporter",
+ "pretty_assertions",
"project",
"regex",
"rope",
Ben Kunkle and Conrad Irwin created
- Fixes auto-indent issues around `elif` caused by auto-indent being prevented due to syntax errors generated before `elif` clause completed
Release Notes:
- Fixed an issue where inserting an elif before an else in bash would
not properly auto-indent
---------
Co-authored-by: Conrad Irwin <conrad@zed.dev>
Cargo.lock | 1
crates/language/src/buffer.rs | 21 +++++++++++-----
crates/languages/Cargo.toml | 1
crates/languages/src/bash.rs | 36 +++++++++++++++++++++++++++++
crates/languages/src/bash/config.toml | 2
5 files changed, 53 insertions(+), 8 deletions(-)
@@ -7050,6 +7050,7 @@ dependencies = [
"pet-fs",
"pet-poetry",
"pet-reporter",
+ "pretty_assertions",
"project",
"regex",
"rope",
@@ -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
@@ -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
@@ -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
});
}
@@ -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