refactor: centralize editor plugin lifecycle ownership
This commit is contained in:
+5
-55
@@ -1,10 +1,6 @@
|
||||
use std::{collections::BTreeMap, env, path::PathBuf};
|
||||
use std::{env, path::PathBuf};
|
||||
|
||||
use vamp::{
|
||||
editor::Editor,
|
||||
ruby::{Config, RubyPlugin, load_config},
|
||||
tui,
|
||||
};
|
||||
use vamp::{session::EditorSession, tui};
|
||||
|
||||
const HELP: &str = "vamp — modal editor with isolated Ruby plugins
|
||||
|
||||
@@ -69,59 +65,13 @@ fn run() -> Result<(), String> {
|
||||
let Some(options) = options()? else {
|
||||
return Ok(());
|
||||
};
|
||||
let mut editor = Editor::open(
|
||||
let mut session = EditorSession::open(
|
||||
options.file,
|
||||
tui::CAPABILITIES.iter().map(|s| (*s).to_owned()).collect(),
|
||||
options.config.as_deref(),
|
||||
)
|
||||
.map_err(|error| format!("cannot open file: {error}"))?;
|
||||
let mut notices = Vec::new();
|
||||
let config = match options.config {
|
||||
Some(path) => load_config(&path).unwrap_or_else(|error| {
|
||||
notices.push(format!("config disabled: {error}"));
|
||||
Config::default()
|
||||
}),
|
||||
None => Config::default(),
|
||||
};
|
||||
let mut plugins = BTreeMap::new();
|
||||
for path in config.plugins {
|
||||
match RubyPlugin::start(&path) {
|
||||
Ok((plugin, feature)) => {
|
||||
let name = feature.name.clone();
|
||||
match editor.register(feature) {
|
||||
Ok(()) => {
|
||||
plugins.insert(name, plugin);
|
||||
}
|
||||
Err(error) => notices.push(format!("{}: {error}", path.display())),
|
||||
}
|
||||
}
|
||||
Err(error) => notices.push(format!("{}: {error}", path.display())),
|
||||
}
|
||||
}
|
||||
for (key, command) in config.bindings {
|
||||
if let Err(error) = editor.bind(key, command) {
|
||||
notices.push(format!("binding {key:?}: {error}"));
|
||||
}
|
||||
}
|
||||
if notices.is_empty() {
|
||||
editor.set_message("i: insert • Esc: normal • :w save • :q quit • :plugins");
|
||||
} else {
|
||||
editor.set_message(notices.join(" | "));
|
||||
}
|
||||
tui::run(&mut editor, |editor, invocation| {
|
||||
let result = match plugins.get_mut(&invocation.plugin) {
|
||||
Some(plugin) => plugin
|
||||
.invoke(&invocation.command, &invocation.args, &editor.context())
|
||||
.and_then(|effects| editor.apply(effects)),
|
||||
None => Err("plugin host is unavailable".into()),
|
||||
};
|
||||
if let Err(error) = result {
|
||||
if let Some(mut plugin) = plugins.remove(&invocation.plugin) {
|
||||
plugin.disable();
|
||||
}
|
||||
editor.disable_plugin(&invocation.plugin, &error);
|
||||
}
|
||||
})
|
||||
.map_err(|error| format!("terminal error: {error}"))
|
||||
tui::run(&mut session).map_err(|error| format!("terminal error: {error}"))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
Reference in New Issue
Block a user