Allow auto-indenting with syntax errors when using regex-based indent matches to improve bash auto-indent behavior (#24160)
- 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>
This commit is contained in:
parent
66d0cdfd91
commit
8742c18107
5 changed files with 53 additions and 8 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -7050,6 +7050,7 @@ dependencies = [
|
||||||
"pet-fs",
|
"pet-fs",
|
||||||
"pet-poetry",
|
"pet-poetry",
|
||||||
"pet-reporter",
|
"pet-reporter",
|
||||||
|
"pretty_assertions",
|
||||||
"project",
|
"project",
|
||||||
"regex",
|
"regex",
|
||||||
"rope",
|
"rope",
|
||||||
|
|
|
@ -2897,12 +2897,19 @@ impl BufferSnapshot {
|
||||||
let mut indent_from_prev_row = false;
|
let mut indent_from_prev_row = false;
|
||||||
let mut outdent_from_prev_row = false;
|
let mut outdent_from_prev_row = false;
|
||||||
let mut outdent_to_row = u32::MAX;
|
let mut outdent_to_row = u32::MAX;
|
||||||
|
let mut from_regex = false;
|
||||||
|
|
||||||
while let Some((indent_row, delta)) = indent_changes.peek() {
|
while let Some((indent_row, delta)) = indent_changes.peek() {
|
||||||
match indent_row.cmp(&row) {
|
match indent_row.cmp(&row) {
|
||||||
Ordering::Equal => match delta {
|
Ordering::Equal => match delta {
|
||||||
Ordering::Less => outdent_from_prev_row = true,
|
Ordering::Less => {
|
||||||
Ordering::Greater => indent_from_prev_row = true,
|
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 {
|
Some(IndentSuggestion {
|
||||||
basis_row: prev_row,
|
basis_row: prev_row,
|
||||||
delta: Ordering::Equal,
|
delta: Ordering::Equal,
|
||||||
within_error,
|
within_error: within_error && !from_regex,
|
||||||
})
|
})
|
||||||
} else if indent_from_prev_row {
|
} else if indent_from_prev_row {
|
||||||
Some(IndentSuggestion {
|
Some(IndentSuggestion {
|
||||||
basis_row: prev_row,
|
basis_row: prev_row,
|
||||||
delta: Ordering::Greater,
|
delta: Ordering::Greater,
|
||||||
within_error,
|
within_error: within_error && !from_regex,
|
||||||
})
|
})
|
||||||
} else if outdent_to_row < prev_row {
|
} else if outdent_to_row < prev_row {
|
||||||
Some(IndentSuggestion {
|
Some(IndentSuggestion {
|
||||||
basis_row: outdent_to_row,
|
basis_row: outdent_to_row,
|
||||||
delta: Ordering::Equal,
|
delta: Ordering::Equal,
|
||||||
within_error,
|
within_error: within_error && !from_regex,
|
||||||
})
|
})
|
||||||
} else if outdent_from_prev_row {
|
} else if outdent_from_prev_row {
|
||||||
Some(IndentSuggestion {
|
Some(IndentSuggestion {
|
||||||
basis_row: prev_row,
|
basis_row: prev_row,
|
||||||
delta: Ordering::Less,
|
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)
|
} else if config.auto_indent_using_last_non_empty_line || !self.is_line_blank(prev_row)
|
||||||
{
|
{
|
||||||
Some(IndentSuggestion {
|
Some(IndentSuggestion {
|
||||||
basis_row: prev_row,
|
basis_row: prev_row,
|
||||||
delta: Ordering::Equal,
|
delta: Ordering::Equal,
|
||||||
within_error,
|
within_error: within_error && !from_regex,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -94,3 +94,4 @@ tree-sitter-go.workspace = true
|
||||||
tree-sitter-c.workspace = true
|
tree-sitter-c.workspace = true
|
||||||
tree-sitter-css.workspace = true
|
tree-sitter-css.workspace = true
|
||||||
tree-sitter-bash.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 language::{language_settings::AllLanguageSettings, AutoindentMode, Buffer};
|
||||||
use settings::SettingsStore;
|
use settings::SettingsStore;
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
|
use unindent::Unindent;
|
||||||
|
use util::test::marked_text_offsets;
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_bash_autoindent(cx: &mut TestAppContext) {
|
async fn test_bash_autoindent(cx: &mut TestAppContext) {
|
||||||
|
@ -111,6 +113,40 @@ mod tests {
|
||||||
"foo() {\n echo \"Hello, World!\"\n}",
|
"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
|
buffer
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,5 +24,5 @@ brackets = [
|
||||||
### fi
|
### fi
|
||||||
### ```
|
### ```
|
||||||
increase_indent_pattern = "(\\s*|;)(do|then|in|else|elif)\\b.*$"
|
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
|
# make sure to test each line mode & block mode
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue