Skip to main content

trail/plugin/
mod.rs

1//! Plugin system: Lua scripting surface via `mlua`.
2//!
3//! Provides hooks (`on_select`, `on_enter_dir`, `register_action`) for
4//! user-defined commands and custom preview providers. In v1 the scripting
5//! engine is Lua (`mlua` with embedded Lua 5.4); WASM/`extism` is deferred
6//! to v2 (decision log).
7//!
8//! The bookmark store (`bookmarks`) is a pure-Rust companion module that
9//! the example bookmarks plugin delegates to for persistence.
10
11pub mod bookmarks;
12pub mod lua_api;
13
14// clippy: unused_imports — API consumed by plugin developers
15#[allow(unused_imports)]
16pub use lua_api::{PluginEngine, PluginError};
17
18/// The example bookmarks plugin, embedded as a Lua source string so that no
19/// external file is required.
20///
21/// This plugin is automatically available; enable it by adding `"bookmarks"`
22/// to `[plugins].enabled` in `trail.toml`.
23pub const EXAMPLE_BOOKMARKS_PLUGIN: &str = include_str!("example_bookmarks.lua");
24
25/// Loads all plugins listed in `enabled` into `engine`.
26///
27/// Each name is resolved in the following order:
28/// 1. The built-in embedded plugin (currently only `"bookmarks"`).
29/// 2. A file path in the user's Trail config directory, with `.lua` appended.
30///
31/// Failures to load a single plugin are logged at `debug` level and do not
32/// prevent other plugins from loading.
33pub fn load_enabled_plugins(engine: &mut PluginEngine, enabled: &[String]) {
34    for name in enabled {
35        match name.as_str() {
36            "bookmarks" => {
37                if let Err(e) = engine.load_plugin_str("bookmarks", EXAMPLE_BOOKMARKS_PLUGIN) {
38                    tracing::debug!("failed to load built-in bookmarks plugin: {e}");
39                } else {
40                    tracing::debug!("loaded built-in plugin: bookmarks");
41                }
42            }
43            other => {
44                // Try to load as a file from the user's plugin dir.
45                let plugin_path = match crate::paths::config_dir() {
46                    Some(dir) => dir.join(other).with_extension("lua"),
47                    None => std::path::PathBuf::from(other).with_extension("lua"),
48                };
49
50                if let Err(e) = engine.load_plugin(&plugin_path) {
51                    tracing::debug!("failed to load plugin '{other}': {e}");
52                } else {
53                    tracing::debug!("loaded plugin: {other}");
54                }
55            }
56        }
57    }
58}