feat: default explorer to compact directory tree

This commit is contained in:
Valdemar Lorenzen
2026-10-08 15:51:25 +02:00
parent 9ba8b38898
commit 6d7be0c169
9 changed files with 2036 additions and 145 deletions
+121 -2
View File
@@ -42,6 +42,18 @@ impl EditorSession {
config.file_explorer_side
));
}
if let Err(error) = editor.set_file_picker_view(&config.file_picker_view) {
notices.push(format!(
"file picker view {:?}: {error}",
config.file_picker_view
));
}
if let Err(error) = editor.set_file_explorer_view(&config.file_explorer_view) {
notices.push(format!(
"file explorer view {:?}: {error}",
config.file_explorer_view
));
}
let mut plugins = BTreeMap::new();
for path in config.plugins {
match RubyPlugin::start(&path) {
@@ -233,11 +245,22 @@ end
session.editor().file_picker().unwrap().presentation,
crate::files::FilePresentation::Docked
);
assert_eq!(
session.editor().file_picker().unwrap().view,
crate::files::FileView::Tree
);
assert!(!session.editor().file_picker().unwrap().searching);
session.handle(Input::Char('/'));
for ch in "dir e\u{301}".chars() {
session.handle(Input::Char(ch));
}
session.handle(Input::Backspace);
assert_eq!(session.editor().file_picker().unwrap().query, "dir ");
session.handle(Input::Ctrl('h'));
assert_eq!(session.editor().file_picker().unwrap().query, "dir ");
session.handle(Input::Escape);
assert!(!session.editor().file_picker().unwrap().searching);
assert!(session.editor().file_picker().unwrap().focused);
session.handle(Input::Escape);
assert!(!session.editor().file_picker().unwrap().focused);
session.handle(Input::Char('i'));
@@ -251,7 +274,11 @@ end
session.editor().file_picker().unwrap().presentation,
crate::files::FilePresentation::Floating
);
assert_eq!(session.editor().file_picker().unwrap().query, "dir ");
assert_eq!(
session.editor().file_picker().unwrap().view,
crate::files::FileView::List
);
assert_eq!(session.editor().file_picker().unwrap().query, "");
session.handle(Input::Escape);
assert!(session.editor().file_picker().is_none());
session.handle(Input::Char('u'));
@@ -259,13 +286,73 @@ end
}
#[test]
fn invalid_explorer_side_preserves_default_and_valid_bindings() {
fn configured_flat_dock_and_tree_picker_keep_control_h_distinct_from_backspace() {
let fixture = Fixture::new();
fixture.file("buffer.txt", "alpha");
let mut session = fixture.open(
r#"
Vamp.configure do |config|
config.file_explorer_view = "list"
config.file_picker_view = "tree"
config.bind "ctrl+f", config.core.right, mode: config.modes.tree
end
"#,
);
session.handle(Input::Char(' '));
session.handle(Input::Char('e'));
assert_eq!(
session.editor().file_picker().unwrap().view,
crate::files::FileView::List
);
for ch in "e\u{301}".chars() {
session.handle(Input::Char(ch));
}
session.handle(Input::Ctrl('h'));
assert_eq!(session.editor().file_picker().unwrap().query, "e\u{301}");
session.handle(Input::Backspace);
assert_eq!(session.editor().file_picker().unwrap().query, "");
session.handle(Input::Ctrl('w'));
session.handle(Input::Char(' '));
session.handle(Input::Char('o'));
assert_eq!(
session.editor().file_picker().unwrap().view,
crate::files::FileView::Tree
);
assert!(!session.editor().file_picker().unwrap().searching);
session.handle(Input::Char('x'));
assert_eq!(session.editor().file_picker().unwrap().query, "");
session.handle(Input::Char('/'));
session.handle(Input::Char('x'));
session.handle(Input::Ctrl('h'));
assert_eq!(session.editor().file_picker().unwrap().query, "x");
session.handle(Input::Escape);
assert!(!session.editor().file_picker().unwrap().searching);
assert!(session.editor().file_picker().unwrap().focused);
session.handle(Input::Ctrl('t'));
assert_eq!(
session.editor().file_picker().unwrap().view,
crate::files::FileView::List
);
session.handle(Input::Escape);
assert!(session.editor().file_picker().is_none());
session.handle(Input::Char('i'));
session.handle(Input::Char('x'));
session.handle(Input::Ctrl('h'));
assert_eq!(session.editor().lines(), &["xalpha"]);
session.handle(Input::Backspace);
assert_eq!(session.editor().lines(), &["alpha"]);
}
#[test]
fn invalid_explorer_preferences_preserve_defaults_and_valid_bindings() {
let fixture = Fixture::new();
fixture.file("buffer.txt", "abc");
let mut session = fixture.open(
r#"
Vamp.configure do |config|
config.file_explorer_side = "diagonal"
config.file_explorer_view = "grid"
config.file_picker_view = "grid"
config.bind "n", config.core.right
end
"#,
@@ -274,6 +361,14 @@ end
session.editor().file_explorer_side(),
crate::files::DockSide::Right
);
assert_eq!(
session.editor().file_explorer_view(),
crate::files::FileView::Tree
);
assert_eq!(
session.editor().file_picker_view(),
crate::files::FileView::List
);
session.handle(Input::Char('n'));
assert_eq!(
session.editor().cursor(),
@@ -1101,6 +1196,30 @@ end
r#"config.file_explorer_side = """#,
"file explorer side must not be empty",
),
(
"config.file_picker_view = 7",
"file picker view must be a String",
),
(
"config.file_picker_view = nil",
"file picker view must be a String",
),
(
r#"config.file_picker_view = """#,
"file picker view must not be empty",
),
(
"config.file_explorer_view = 7",
"file explorer view must be a String",
),
(
"config.file_explorer_view = nil",
"file explorer view must be a String",
),
(
r#"config.file_explorer_view = """#,
"file explorer view must not be empty",
),
(r#"config.bind "n", "core.insert""#, "TypeError"),
(r#"config.bind "n", nil, mode: "insert""#, "TypeError"),
(r#"config.bind "n", config.modes.insert"#, "TypeError"),