feat: make keybindings configurable

This commit is contained in:
Valdemar Lorenzen
2026-10-05 15:57:33 +02:00
parent 368442ba29
commit 3fd89fcbed
7 changed files with 466 additions and 137 deletions
+7 -16
View File
@@ -16,7 +16,7 @@ const INVOKE_TIMEOUT: Duration = Duration::from_millis(500);
#[derive(Debug, Default)]
pub struct Config {
pub plugins: Vec<PathBuf>,
pub bindings: Vec<(char, String)>,
pub bindings: Vec<Binding>,
}
/// Relative plugin paths are resolved against the configuration file's directory.
@@ -37,16 +37,7 @@ pub fn load_config(path: &Path) -> Result<Config, String> {
}
config.plugins.push(directory.join(plugin));
}
for binding in bindings {
let mut chars = binding.key.chars();
let key = chars
.next()
.ok_or("Ruby binding key must be one character")?;
if chars.next().is_some() || binding.command.is_empty() {
return Err("Ruby binding requires one character and a nonempty command".into());
}
config.bindings.push((key, binding.command));
}
config.bindings = bindings;
Ok(config)
}
Response::Error {
@@ -224,11 +215,12 @@ impl Response {
}
}
#[derive(Deserialize)]
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
struct Binding {
key: String,
command: String,
pub struct Binding {
pub mode: String,
pub key: String,
pub command: Option<String>,
}
#[derive(Deserialize)]
@@ -546,7 +538,6 @@ end
);
let loaded = load_config(&config).unwrap();
assert_eq!(loaded.plugins, [fixture.0.join("plugins/greeting.rb")]);
assert_eq!(loaded.bindings, [('g', "greet".into())]);
let invalid = fixture.file("invalid.rb", "Vamp.configure { |config| config.plugin 7 }");
assert!(
load_config(&invalid)