feat: expose typed action and mode configuration values

This commit is contained in:
Valdemar Lorenzen
2026-10-05 16:21:01 +02:00
parent bb242b35b6
commit 714f1ff4de
5 changed files with 125 additions and 45 deletions
+53 -25
View File
@@ -329,37 +329,27 @@ end
r#"
Vamp.configure do |config|
config.plugin "healthy.rb"
config.bind "n", "core.insert_first_nonblank"
config.bind "n", config.core.insert_first_nonblank
config.bind "i", nil
config.bind "ctrl+r", "core.redo"
config.bind "ctrl+c", "core.normal", mode: "insert"
config.bind "esc", nil, mode: "insert"
config.bind "!", "core.newline", mode: "insert"
config.bind "shift+x", nil, mode: "insert"
config.bind "ctrl+r", config.core.redo
config.bind "ctrl+c", config.core.normal, mode: config.modes.insert
config.bind "esc", nil, mode: config.modes.insert
config.bind "!", config.core.newline, mode: config.modes.insert
config.bind "shift+x", nil, mode: config.modes.insert
config.bind ":", nil
config.bind "space", "core.command"
config.bind "enter", nil, mode: "command"
config.bind "ctrl+x", "core.submit", mode: "command"
config.bind "ctrl+c", "core.normal", mode: "command"
config.bind "ctrl+h", "core.backspace", mode: "command"
config.bind "g", "core.undo"
config.bind "space", config.core.command
config.bind "enter", nil, mode: config.modes.command
config.bind "ctrl+x", config.core.submit, mode: config.modes.command
config.bind "ctrl+c", config.core.normal, mode: config.modes.command
config.bind "ctrl+h", config.core.backspace, mode: config.modes.command
config.bind "g", config.core.undo
config.bind "g", "healthy"
config.bind "n", "core.missing"
config.bind "n", "core.undo", mode: "missing"
config.bind "unknown", "core.undo"
config.bind "ctrl+f", "healthy", mode: "insert"
config.bind "n", config.core.newline
config.bind "unknown", config.core.undo
config.bind "ctrl+f", "healthy", mode: config.modes.insert
end
"#,
);
let message = session.editor().message();
for error in [
"Unknown action for NORMAL: core.missing",
"Unknown binding mode: missing",
"Invalid binding key",
"Ex/plugin commands can only be bound in Normal mode",
] {
assert!(message.contains(error), "{message}");
}
session.handle(Input::Char('i'));
assert_eq!(session.editor().mode(), crate::editor::Mode::Normal);
session.handle(Input::Char('n'));
@@ -414,6 +404,44 @@ end
assert!(session.editor().should_quit());
}
#[test]
fn typed_config_errors_discard_partial_bindings_and_leave_default_editing_available() {
let fixture = Fixture::new();
for (expression, error) in [
("config.core.reod", "NoMethodError"),
("config.modes.insret", "NoMethodError"),
(r#"config.bind "n", "core.insert""#, "TypeError"),
(r#"config.bind "n", nil, mode: "insert""#, "TypeError"),
(r#"config.bind "n", config.modes.insert"#, "TypeError"),
(
r#"config.bind "n", nil, mode: config.core.insert"#,
"TypeError",
),
(r#"config.core.redo.name = "core.undo""#, "FrozenError"),
(
r#"config.core.redo.name.replace("core.undo")"#,
"FrozenError",
),
(r#"config.modes.insert.name = "normal""#, "FrozenError"),
(
r#"config.modes.insert.name.replace("normal")"#,
"FrozenError",
),
] {
let mut session = fixture.open(&format!(
"Vamp.configure do |config|\n config.bind \"i\", nil\n {expression}\nend"
));
assert!(session.editor().message().contains(error), "{expression}");
session.handle(Input::Char('i'));
session.handle(Input::Char('界'));
session.handle(Input::Escape);
assert_eq!(session.editor().mode(), crate::editor::Mode::Normal);
assert_eq!(session.editor().lines(), &["界"], "{expression}");
session.handle(Input::Char('u'));
assert_eq!(session.editor().lines(), &[String::new()], "{expression}");
}
}
#[test]
fn broken_config_falls_back_to_core_without_failing_the_session() {
let fixture = Fixture::new();