feat: support macOS modified backspace deletion

This commit is contained in:
2026-10-12 17:36:43 +02:00
parent 5e6b602127
commit 2260817fc0
6 changed files with 522 additions and 60 deletions
+52 -4
View File
@@ -1,4 +1,4 @@
use crate::editor::Input;
use crate::editor::{BackspaceKind, Input};
use crate::files::{FilePicker, FilePresentation, FileView};
use std::{
collections::BTreeSet,
@@ -506,9 +506,11 @@ impl DiffState {
Input::Home => self.selected = 0,
Input::End => self.selected = self.visible.len().saturating_sub(1),
Input::Enter if !self.loading => self.choose(),
Input::Backspace => {
if let Some((byte, _)) = self.query.grapheme_indices(true).next_back() {
self.query.truncate(byte);
input if BackspaceKind::from_input(&input).is_some() => {
if BackspaceKind::from_input(&input)
.expect("guard checked backspace input")
.truncate(&mut self.query)
{
self.refilter();
}
}
@@ -2113,6 +2115,52 @@ mod tests {
assert_eq!(editor.diff().unwrap().selected, 1);
}
#[test]
fn selector_word_and_line_deletion_preserve_source_in_both_stages() {
for after in [false, true] {
let mut editor = editor();
editor
.apply(vec![Effect::Replace("source text".into())])
.unwrap();
let source = editor.context().text;
let revision = editor.text_revision();
let carets = editor.carets();
open(&mut editor);
if after {
editor.handle(Input::Enter);
}
let phase = if after { Phase::After } else { Phase::Before };
text(&mut editor, "FIX missing");
assert_eq!(editor.diff().unwrap().entries().len(), 1);
editor.handle(Input::AltBackspace);
assert_eq!(editor.diff().unwrap().query, "FIX ");
assert_eq!(editor.diff().unwrap().entries().len(), 2);
editor.handle(Input::SuperBackspace);
assert!(editor.diff().unwrap().query.is_empty());
assert_eq!(
editor
.diff()
.unwrap()
.entries()
.map(|entry| entry.label.as_str())
.collect::<Vec<_>>(),
[
"Working checkout",
"abcdef123",
"fedcba321",
"Load history from origin"
]
);
for input in [Input::Backspace, Input::AltBackspace, Input::SuperBackspace] {
editor.handle(input);
}
assert_eq!(editor.diff().unwrap().phase, phase);
assert_eq!(editor.context().text, source);
assert_eq!(editor.text_revision(), revision);
assert_eq!(editor.carets(), carets);
}
}
#[test]
fn loader_preserves_after_step_query_category_and_selection_then_compares() {
let mut editor = editor();