mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-25 01:34:02 +00:00
Fix panic when hitting tab at the beginning of a line with mixed tab/space indent
This commit is contained in:
parent
9156d488ca
commit
9cbb698b96
4 changed files with 72 additions and 23 deletions
|
@ -1566,7 +1566,7 @@ async fn test_tab(cx: &mut gpui::TestAppContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_tab_on_blank_line_auto_indents(cx: &mut gpui::TestAppContext) {
|
async fn test_tab_in_leading_whitespace_auto_indents_lines(cx: &mut gpui::TestAppContext) {
|
||||||
let mut cx = EditorTestContext::new(cx);
|
let mut cx = EditorTestContext::new(cx);
|
||||||
let language = Arc::new(
|
let language = Arc::new(
|
||||||
Language::new(
|
Language::new(
|
||||||
|
@ -1623,6 +1623,43 @@ async fn test_tab_on_blank_line_auto_indents(cx: &mut gpui::TestAppContext) {
|
||||||
"});
|
"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_tab_with_mixed_whitespace(cx: &mut gpui::TestAppContext) {
|
||||||
|
let mut cx = EditorTestContext::new(cx);
|
||||||
|
let language = Arc::new(
|
||||||
|
Language::new(
|
||||||
|
LanguageConfig::default(),
|
||||||
|
Some(tree_sitter_rust::language()),
|
||||||
|
)
|
||||||
|
.with_indents_query(r#"(_ "{" "}" @end) @indent"#)
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
cx.update_buffer(|buffer, cx| buffer.set_language(Some(language), cx));
|
||||||
|
|
||||||
|
cx.update(|cx| {
|
||||||
|
cx.update_global::<Settings, _, _>(|settings, _| {
|
||||||
|
settings.editor_overrides.tab_size = Some(4.try_into().unwrap());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.set_state(indoc! {"
|
||||||
|
fn a() {
|
||||||
|
if b {
|
||||||
|
\t ˇc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"});
|
||||||
|
|
||||||
|
cx.update_editor(|e, cx| e.tab(&Tab, cx));
|
||||||
|
cx.assert_editor_state(indoc! {"
|
||||||
|
fn a() {
|
||||||
|
if b {
|
||||||
|
ˇc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"});
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_indent_outdent(cx: &mut gpui::TestAppContext) {
|
async fn test_indent_outdent(cx: &mut gpui::TestAppContext) {
|
||||||
let mut cx = EditorTestContext::new(cx);
|
let mut cx = EditorTestContext::new(cx);
|
||||||
|
|
|
@ -1068,32 +1068,40 @@ impl Buffer {
|
||||||
self.edit(edits, None, cx);
|
self.edit(edits, None, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a minimal edit that will cause the the given row to be indented
|
||||||
|
// with the given size. After applying this edit, the length of the line
|
||||||
|
// will always be at least `new_size.len`.
|
||||||
pub fn edit_for_indent_size_adjustment(
|
pub fn edit_for_indent_size_adjustment(
|
||||||
row: u32,
|
row: u32,
|
||||||
current_size: IndentSize,
|
current_size: IndentSize,
|
||||||
new_size: IndentSize,
|
new_size: IndentSize,
|
||||||
) -> Option<(Range<Point>, String)> {
|
) -> Option<(Range<Point>, String)> {
|
||||||
if new_size.kind != current_size.kind && current_size.len > 0 {
|
if new_size.kind != current_size.kind {
|
||||||
return None;
|
Some((
|
||||||
}
|
Point::new(row, 0)..Point::new(row, current_size.len),
|
||||||
|
iter::repeat(new_size.char())
|
||||||
|
.take(new_size.len as usize)
|
||||||
|
.collect::<String>(),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
match new_size.len.cmp(¤t_size.len) {
|
||||||
|
Ordering::Greater => {
|
||||||
|
let point = Point::new(row, 0);
|
||||||
|
Some((
|
||||||
|
point..point,
|
||||||
|
iter::repeat(new_size.char())
|
||||||
|
.take((new_size.len - current_size.len) as usize)
|
||||||
|
.collect::<String>(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
match new_size.len.cmp(¤t_size.len) {
|
Ordering::Less => Some((
|
||||||
Ordering::Greater => {
|
Point::new(row, 0)..Point::new(row, current_size.len - new_size.len),
|
||||||
let point = Point::new(row, 0);
|
String::new(),
|
||||||
Some((
|
)),
|
||||||
point..point,
|
|
||||||
iter::repeat(new_size.char())
|
Ordering::Equal => None,
|
||||||
.take((new_size.len - current_size.len) as usize)
|
|
||||||
.collect::<String>(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ordering::Less => Some((
|
|
||||||
Point::new(row, 0)..Point::new(row, current_size.len - new_size.len),
|
|
||||||
String::new(),
|
|
||||||
)),
|
|
||||||
|
|
||||||
Ordering::Equal => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,7 @@ cat <<MESSAGE
|
||||||
Prepared new Zed versions locally.
|
Prepared new Zed versions locally.
|
||||||
|
|
||||||
To push this:
|
To push this:
|
||||||
|
|
||||||
git push origin \\
|
git push origin \\
|
||||||
${preview_tag_name} \\
|
${preview_tag_name} \\
|
||||||
${stable_tag_name} \\
|
${stable_tag_name} \\
|
||||||
|
@ -100,9 +101,11 @@ To push this:
|
||||||
main
|
main
|
||||||
|
|
||||||
To undo this:
|
To undo this:
|
||||||
|
|
||||||
git reset --hard ${old_main_sha} && git push -f . \\
|
git reset --hard ${old_main_sha} && git push -f . \\
|
||||||
:${preview_tag_name} \\
|
:${preview_tag_name} \\
|
||||||
:${stable_tag_name} \\
|
:${stable_tag_name} \\
|
||||||
:${minor_branch_name} \\
|
:${minor_branch_name} \\
|
||||||
${old_prev_minor_sha}:${prev_minor_branch_name}
|
${old_prev_minor_sha}:${prev_minor_branch_name}
|
||||||
|
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
|
@ -28,10 +28,11 @@ cat <<MESSAGE
|
||||||
Locally committed and tagged ${package} version ${new_version}
|
Locally committed and tagged ${package} version ${new_version}
|
||||||
|
|
||||||
To push this:
|
To push this:
|
||||||
git push origin \\
|
|
||||||
${tag_name} \\
|
git push origin ${tag_name} ${branch_name}
|
||||||
${branch_name}
|
|
||||||
|
|
||||||
To undo this:
|
To undo this:
|
||||||
|
|
||||||
git reset --hard ${old_sha} && git tag -d ${tag_name}
|
git reset --hard ${old_sha} && git tag -d ${tag_name}
|
||||||
|
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
Loading…
Reference in a new issue