feat: open floating explorer as Tree in Insert mode

This commit is contained in:
Valdemar Lorenzen
2026-10-08 16:41:16 +02:00
parent 49242bb6e4
commit 86395cf5ce
8 changed files with 99 additions and 25 deletions
+76 -6
View File
@@ -771,7 +771,7 @@ impl Editor {
project_root: std::env::current_dir()?,
file_picker: None,
file_explorer_side: DockSide::Right,
file_picker_view: FileView::List,
file_picker_view: FileView::Tree,
file_explorer_view: FileView::Tree,
count: None,
};
@@ -1450,6 +1450,13 @@ impl Editor {
}
}
}
if presentation == FilePresentation::Floating
&& view == FileView::Tree
&& let Some(picker) = &mut self.file_picker
&& !picker.searching
{
picker.start_search();
}
self.palette = None;
self.count = None;
self.clear_leader();
@@ -3340,6 +3347,50 @@ mod tests {
editor
}
#[test]
fn floating_default_tree_starts_filtering_then_escape_navigates_before_close() {
let directory = Directory::new();
fs::create_dir(directory.path("dir")).unwrap();
fs::write(directory.path("dir/first.txt"), "first").unwrap();
fs::write(directory.path("dir/second.txt"), "second").unwrap();
let mut editor = project_editor(&directory);
type_text(&mut editor, " osecond.txt");
let picker = editor.file_picker().unwrap();
assert_eq!(picker.view, FileView::Tree);
assert!(picker.focused && picker.searching);
assert_eq!(picker.query, "second.txt");
assert_eq!(
picker.entries().nth(picker.selected).unwrap().path,
Path::new("dir/second.txt")
);
editor.handle(Input::Escape);
let picker = editor.file_picker().unwrap();
assert!(picker.focused && !picker.searching);
assert_eq!(
picker.entries().nth(picker.selected).unwrap().path,
Path::new("dir")
);
editor.handle(Input::Char('l'));
assert!(
editor
.file_picker()
.unwrap()
.entries()
.next()
.unwrap()
.expanded
);
editor.handle(Input::Escape);
assert!(editor.file_picker().is_none());
assert_eq!(editor.lines(), &[String::new()]);
editor.set_file_picker_view("list").unwrap();
type_text(&mut editor, " osecond.txt");
assert_eq!(editor.file_picker().unwrap().view, FileView::List);
editor.handle(Input::Enter);
assert_eq!(editor.lines(), &["second"]);
assert!(editor.file_picker().is_none());
}
#[test]
fn selection_navigation_wraps_without_touching_any_underlying_mode() {
let directory = Directory::new();
@@ -3705,6 +3756,7 @@ mod tests {
fs::write(directory.path(name), "text").unwrap();
}
let mut editor = project_editor(&directory);
editor.set_file_picker_view("list").unwrap();
type_text(&mut editor, " o");
editor.handle(Input::Ctrl('K'));
assert_eq!(editor.file_picker().unwrap().selected, 2);
@@ -3788,6 +3840,8 @@ mod tests {
type_text(&mut editor, " o");
assert_eq!(editor.file_picker().unwrap().query, "");
editor.handle(Input::Escape);
assert!(editor.file_picker().unwrap().focused);
editor.handle(Input::Escape);
assert!(editor.file_picker().is_none());
}
@@ -3867,6 +3921,7 @@ mod tests {
assert!(editor.file_picker().unwrap().error.is_none());
editor.handle(Input::Escape);
editor.handle(Input::Escape);
editor.handle(Input::Escape);
editor.handle(Input::Char('i'));
type_text(&mut editor, "X");
editor.open_file_picker(FilePresentation::Docked);
@@ -3970,6 +4025,8 @@ mod tests {
editor.open_file_picker(FilePresentation::Floating);
editor.handle(Input::Paste("ignored".into()));
editor.handle(Input::Escape);
assert!(editor.file_picker().unwrap().focused);
editor.handle(Input::Escape);
assert_eq!(editor.mode(), Mode::Insert);
assert!(editor.active.insert_start.is_some());
assert_eq!(editor.context().text, "X");
@@ -4023,8 +4080,6 @@ mod tests {
fs::create_dir(directory.path("folder")).unwrap();
fs::write(directory.path("file.txt"), "text").unwrap();
let mut editor = project_editor(&directory);
assert_eq!(editor.file_picker_view(), FileView::List);
assert_eq!(editor.file_explorer_view(), FileView::Tree);
editor.open_file_picker(FilePresentation::Docked);
assert_eq!(editor.file_picker().unwrap().view, FileView::Tree);
editor.set_file_picker_view("TREE").unwrap();
@@ -4066,6 +4121,9 @@ mod tests {
let mut editor = project_editor(&directory);
editor.set_file_picker_view("tree").unwrap();
editor.open_file_picker(presentation);
if presentation == FilePresentation::Floating {
editor.handle(Input::Escape);
}
let selected = |editor: &Editor| {
let picker = editor.file_picker().unwrap();
picker
@@ -4179,6 +4237,9 @@ mod tests {
let undo = editor.active.undo.len();
editor.set_file_picker_view("tree").unwrap();
editor.open_file_picker(presentation);
if presentation == FilePresentation::Floating {
editor.handle(Input::Escape);
}
type_text(&mut editor, "123 b xyz");
editor.handle(Input::Paste("ignored".into()));
editor.handle(Input::Backspace);
@@ -4392,7 +4453,10 @@ mod tests {
let mut editor = project_editor(&directory);
editor.set_file_picker_view("tree").unwrap();
editor.open_file_picker(presentation);
type_text(&mut editor, "ineedle.txt");
if presentation == FilePresentation::Docked {
editor.handle(Input::Char('i'));
}
type_text(&mut editor, "needle.txt");
let picker = editor.file_picker().unwrap();
assert_eq!(
picker.entries().nth(picker.selected).unwrap().path,
@@ -4407,7 +4471,10 @@ mod tests {
editor.open_file_picker(presentation);
editor.handle(Input::Ctrl('w'));
editor.open_file_picker(presentation);
type_text(&mut editor, "imodule");
if presentation == FilePresentation::Docked {
editor.handle(Input::Char('i'));
}
type_text(&mut editor, "module");
assert!(
editor
.file_picker()
@@ -4453,7 +4520,10 @@ mod tests {
editor.edit_buffer(b.clone(), false).unwrap();
fs::write(&a, b"\xff").unwrap();
editor.open_file_picker(presentation);
type_text(&mut editor, "isame");
if presentation == FilePresentation::Docked {
editor.handle(Input::Char('i'));
}
type_text(&mut editor, "same");
let picker = editor.file_picker.as_mut().unwrap();
let labels = picker
.entries()