fix: unify docked picker leader actions and focus toggle

This commit is contained in:
Valdemar Lorenzen
2026-10-12 16:17:50 +02:00
parent 1fd5f98256
commit 526e243a5f
2 changed files with 88 additions and 4 deletions
+86 -4
View File
@@ -4999,6 +4999,24 @@ impl Editor {
fn open_file_picker(&mut self, presentation: FilePresentation) {
self.pane_close_picker_origin = None;
if presentation == FilePresentation::Docked
&& self.file_picker().is_some_and(|picker| {
picker.focused
&& picker.presentation == FilePresentation::Docked
&& picker.view == FileView::Tree
&& !picker.searching
})
{
let return_focus = self.diff_bound.map(|bound| bound.2);
self.blur_file_picker();
if let Some(diff) = &mut self.diff
&& let Some(focus) = return_focus
{
diff.focus = focus;
diff.normalize_focus();
}
return;
}
let view = match presentation {
FilePresentation::Floating => self.file_picker_view,
FilePresentation::Docked => self.file_explorer_view,
@@ -5288,7 +5306,14 @@ impl Editor {
if (picker_focused || self.palette.is_some()) && self.handle_selection_binding(&input) {
return None;
}
if picker_focused && !matches!(input, Input::Char(_)) && self.start_sequence(mode, &input) {
let picker_browsing = self
.file_picker
.as_ref()
.is_some_and(|picker| picker.view == FileView::Tree && !picker.searching);
if picker_focused
&& (!matches!(input, Input::Char(_)) || picker_browsing)
&& self.start_sequence(mode, &input)
{
return None;
}
if picker_focused
@@ -5307,6 +5332,8 @@ impl Editor {
| Action::TabNext
| Action::TabClose
| Action::TabForceClose
| Action::FilePicker
| Action::FileExplorer
)
{
let action = *action;
@@ -9435,6 +9462,58 @@ mod tests {
assert_eq!(editor.active.view.targets, targets);
}
#[test]
fn docked_picker_leaders_replace_or_blur_consistently_without_stealing_filter_text() {
let directory = Directory::new();
fs::write(directory.path("file.txt"), "source").unwrap();
for comparison in [false, true] {
let mut editor = editor();
editor.project_root = directory.0.clone();
if comparison {
historical_diff(
&mut editor,
&directory.0,
vec!["before".into()],
vec!["after".into()],
);
}
type_text(&mut editor, " e");
assert!(editor.file_picker().unwrap().focused);
assert!(!editor.file_picker().unwrap().searching);
type_text(&mut editor, " o");
assert_eq!(
editor.file_picker().unwrap().presentation,
FilePresentation::Floating
);
assert!(editor.file_picker().unwrap().searching);
editor.handle(Input::Escape);
editor.handle(Input::Escape);
type_text(&mut editor, " e");
let selected = editor.file_picker().unwrap().selected;
editor.handle(Input::Escape);
let escape_focus = editor.diff().map(|diff| diff.focus);
type_text(&mut editor, " e");
assert!(editor.file_picker().unwrap().focused);
type_text(&mut editor, " e");
assert!(!editor.file_picker().unwrap().focused);
assert_eq!(
editor.file_picker().unwrap().presentation,
FilePresentation::Docked
);
assert_eq!(editor.file_picker().unwrap().selected, selected);
assert_eq!(editor.diff().map(|diff| diff.focus), escape_focus);
type_text(&mut editor, " e");
editor.handle(Input::Char('i'));
type_text(&mut editor, " o e");
assert_eq!(editor.file_picker().unwrap().query, " o e");
assert!(editor.file_picker().unwrap().searching);
assert_eq!(
editor.file_picker().unwrap().presentation,
FilePresentation::Docked
);
}
}
#[test]
fn focused_text_fields_keep_printable_normal_bindings_as_text() {
let directory = Directory::new();
@@ -10812,7 +10891,9 @@ mod tests {
}
let owner = (editor.tab_id(), editor.pane_id());
let comparison_id = editor.diff().and_then(|diff| diff.comparison_id);
editor.act(Action::FileExplorer);
if !editor.file_picker().is_some_and(|picker| picker.focused) {
editor.act(Action::FileExplorer);
}
editor.handle(Input::Ctrl('p'));
assert!(editor.pane_close_picker_origin.is_some());
assert!(editor.palette().is_some());
@@ -10880,7 +10961,9 @@ mod tests {
if comparison {
working_diff(&mut editor, &directory.0, &["file.txt"]);
}
editor.act(Action::FileExplorer);
if !editor.file_picker().is_some_and(|picker| picker.focused) {
editor.act(Action::FileExplorer);
}
editor.handle(Input::Ctrl('p'));
assert!(editor.pane_close_picker_origin.is_some());
assert!(editor.palette().is_some());
@@ -11033,7 +11116,6 @@ mod tests {
editor.apply(vec![Effect::Insert("dirty".into())]).unwrap();
let source = editor.buffer_id();
working_diff(&mut editor, &directory.0, &["file.txt"]);
editor.act(Action::FileExplorer);
editor.handle(Input::Ctrl('p'));
assert!(editor.pane_close_picker_origin.is_some());
assert!(editor.palette().is_some());