Add more hooks

pull/523/head
Arijit Basu 2 years ago
parent fc798aad97
commit bafe15e25e
No known key found for this signature in database
GPG Key ID: 0F8EF5258DC38077

@ -80,21 +80,40 @@ You can also use nested tables such as
## Hooks
This section of the configuration cannot be overwritten by another config
file, as it is an optional lua return statement specific to each config
file. It can be used to define things that are append only, such as various
hooks and callbacks.
file or plugin, since this is an optional lua return statement specific to
each config file. It can be used to define things that should be explicit
for reasons like performance concerns, such as hooks.
Plugins should expose the hooks, and require users to subscribe to them
explicitly.
Example:
```lua
return {
-- Messages to send when the config file loads.
-- Add messages to send when the xplr loads.
-- This is similar to the `--on-load` command-line option.
--
-- Type: list of [Message](https://xplr.dev/en/message#message)s
on_load = {
{ LogInfo = "Hello xplr user," },
{ LogSuccess = "Configuration successfully loaded!" },
{ CallLuaSilently = "custom.some_plugin_with_hooks.on_load" },
},
-- Add messages to send when the directory changes.
--
-- Type: list of [Message](https://xplr.dev/en/message#message)s
on_directory_change = {
{ LogSuccess = "Changed directory" },
{ CallLuaSilently = "custom.some_plugin_with_hooks.on_directory_change" },
},
-- Add messages to send when the focus changes.
--
-- Type: list of [Message](https://xplr.dev/en/message#message)s
on_focus_change = {
{ LogSuccess = "Changed focus" },
{ CallLuaSilently = "custom.some_plugin_with_hooks.on_focus_change" },
}
}
```

@ -165,6 +165,7 @@ pub struct App {
pub bin: String,
pub version: String,
pub config: Config,
pub hooks: Hooks,
pub pwd: String,
pub directory_buffer: Option<DirectoryBuffer>,
pub last_focus: HashMap<String, Option<String>>,
@ -191,8 +192,9 @@ impl App {
lua: &mlua::Lua,
config_file: Option<PathBuf>,
extra_config_files: Vec<PathBuf>,
) -> Result<(Self, Option<Hooks>)> {
let (mut config, mut hooks) = lua::init(lua)?;
) -> Result<Self> {
let (mut config, hooks) = lua::init(lua)?;
let mut hooks = hooks.unwrap_or_default();
let config_file = if let Some(path) = config_file {
Some(path)
@ -221,10 +223,8 @@ impl App {
match lua::extend(lua, &config_file.to_string_lossy()) {
Ok((c, maybe_hooks)) => {
config = c;
match (hooks.as_mut(), maybe_hooks) {
(Some(h1), Some(h2)) => h1.on_load.extend(h2.on_load),
(None, Some(h2)) => hooks = Some(h2),
(_, _) => {}
if let Some(h) = maybe_hooks {
hooks = hooks.extend(h);
}
}
Err(e) => {
@ -323,6 +323,7 @@ impl App {
history: Default::default(),
last_modes: Default::default(),
hostname,
hooks,
};
let has_errs = !load_errs.is_empty();
@ -334,7 +335,7 @@ impl App {
app = app.switch_mode_builtin("debug_error")?;
}
Ok((app, hooks))
Ok(app)
}
pub fn focused_node(&self) -> Option<&Node> {

@ -618,4 +618,22 @@ pub struct Config {
pub struct Hooks {
#[serde(default)]
pub on_load: Vec<ExternalMsg>,
#[serde(default)]
pub on_directory_change: Vec<ExternalMsg>,
#[serde(default)]
pub on_focus_change: Vec<ExternalMsg>,
// TODO After cleanup or Runner::run
// #[serde(default)]
// pub before_quit: Vec<ExternalMsg>,
}
impl Hooks {
pub fn extend(mut self, other: Self) -> Self {
self.on_load.extend(other.on_load);
self.on_directory_change.extend(other.on_directory_change);
self.on_focus_change.extend(other.on_focus_change);
self
}
}

@ -2567,9 +2567,12 @@ xplr.fn.custom = {}
-- ## Hooks -------------------------------------------------------------------
--
-- This section of the configuration cannot be overwritten by another config
-- file, as it is an optional lua return statement specific to each config
-- file. It can be used to define things that are append only, such as various
-- hooks and callbacks.
-- file or plugin, since this is an optional lua return statement specific to
-- each config file. It can be used to define things that should be explicit
-- for reasons like performance concerns, such as hooks.
--
-- Plugins should expose the hooks, and require users to subscribe to them
-- explicitly.
--
-- Example:
--
@ -2580,12 +2583,30 @@ xplr.fn.custom = {}
-- --
-- -- Type: list of [Message](https://xplr.dev/en/message#message)s
-- on_load = {
-- { LogInfo = "Hello xplr user," },
-- { LogSuccess = "Configuration successfully loaded!" },
-- { CallLuaSilently = "custom.some_plugin_with_hooks.on_load" },
-- },
--
-- -- Add messages to send when the directory changes.
-- --
-- -- Type: list of [Message](https://xplr.dev/en/message#message)s
-- on_directory_change = {
-- { LogSuccess = "Changed directory" },
-- { CallLuaSilently = "custom.some_plugin_with_hooks.on_directory_change" },
-- },
--
-- -- Add messages to send when the focus changes.
-- --
-- -- Type: list of [Message](https://xplr.dev/en/message#message)s
-- on_focus_change = {
-- { LogSuccess = "Changed focus" },
-- { CallLuaSilently = "custom.some_plugin_with_hooks.on_focus_change" },
-- }
-- }
-- ```
return {
on_load = {},
on_directory_change = {},
on_focus_change = {},
}

@ -245,7 +245,7 @@ impl Runner {
pub fn run(self) -> Result<Option<String>> {
// Why unsafe? See https://github.com/sayanarijit/xplr/issues/309
let lua = unsafe { mlua::Lua::unsafe_new() };
let (mut app, hooks) = app::App::create(
let mut app = app::App::create(
self.bin,
self.pwd,
&lua,
@ -329,13 +329,8 @@ impl Runner {
event_reader.start();
// Enqueue on_load messages
for msg in hooks
.unwrap_or_default()
.on_load
.into_iter()
.chain(self.on_load)
{
tx_msg_in.send(app::Task::new(app::MsgIn::External(msg), None))?;
for msg in app.hooks.on_load.iter().chain(self.on_load.iter()) {
tx_msg_in.send(app::Task::new(app::MsgIn::External(msg.clone()), None))?;
}
// Refresh once after loading
@ -460,16 +455,25 @@ impl Runner {
}
Refresh => {
// Fifo
let focus = app.focused_node();
if focus != last_focus.as_ref() {
last_focus = focus.cloned();
// Fifo
if let Some(ref mut file) = fifo {
writeln!(file, "{}", app.focused_node_str())?;
};
last_focus = focus.cloned();
// Hooks
if !app.hooks.on_focus_change.is_empty() {
let msgs = app.hooks.on_focus_change.clone();
app = app.handle_batch_external_msgs(msgs)?
}
}
if app.pwd != last_pwd {
last_pwd = app.pwd.clone();
// $PWD watcher
tx_pwd_watcher.send(app.pwd.clone())?;
@ -483,7 +487,11 @@ impl Runner {
)?;
}
last_pwd = app.pwd.clone();
// Hooks
if !app.hooks.on_directory_change.is_empty() {
let msgs = app.hooks.on_directory_change.clone();
app = app.handle_batch_external_msgs(msgs)?
}
}
// UI

Loading…
Cancel
Save