Skip to content

Commit

Permalink
feat(plugins): API to temporarily bind keys to send a message to a sp…
Browse files Browse the repository at this point in the history
…ecific plugin id (#3561)
  • Loading branch information
imsnif authored Aug 21, 2024
1 parent 905ce0a commit 08b6072
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 34 deletions.
79 changes: 46 additions & 33 deletions zellij-server/src/plugins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ pub enum PluginInstruction {
cwd: Option<PathBuf>,
skip_cache: bool,
cli_client_id: ClientId,
plugin_and_client_id: Option<(u32, ClientId)>,
},
CachePluginEvents {
plugin_id: PluginId,
Expand Down Expand Up @@ -624,42 +625,52 @@ pub(crate) fn plugin_thread_main(
cwd,
skip_cache,
cli_client_id,
plugin_and_client_id,
} => {
let should_float = floating.unwrap_or(true);
let mut pipe_messages = vec![];
match plugin {
Some(plugin_url) => {
// send to specific plugin(s)
pipe_to_specific_plugins(
PipeSource::Keybind,
&plugin_url,
&configuration,
&cwd,
skip_cache,
should_float,
&pane_id_to_replace,
&pane_title,
Some(cli_client_id),
&mut pipe_messages,
&name,
&payload,
&args,
&bus,
&mut wasm_bridge,
&plugin_aliases,
);
},
None => {
// no specific destination, send to all plugins
pipe_to_all_plugins(
PipeSource::Keybind,
&name,
&payload,
&args,
&mut wasm_bridge,
&mut pipe_messages,
);
},
if let Some((plugin_id, client_id)) = plugin_and_client_id {
let is_private = true;
pipe_messages.push((
Some(plugin_id),
Some(client_id),
PipeMessage::new(PipeSource::Keybind, name, &payload, &args, is_private),
));
} else {
match plugin {
Some(plugin_url) => {
// send to specific plugin(s)
pipe_to_specific_plugins(
PipeSource::Keybind,
&plugin_url,
&configuration,
&cwd,
skip_cache,
should_float,
&pane_id_to_replace,
&pane_title,
Some(cli_client_id),
&mut pipe_messages,
&name,
&payload,
&args,
&bus,
&mut wasm_bridge,
&plugin_aliases,
);
},
None => {
// no specific destination, send to all plugins
pipe_to_all_plugins(
PipeSource::Keybind,
&name,
&payload,
&args,
&mut wasm_bridge,
&mut pipe_messages,
);
},
}
}
wasm_bridge.pipe_messages(pipe_messages, shutdown_send.clone())?;
},
Expand Down Expand Up @@ -768,6 +779,8 @@ pub(crate) fn plugin_thread_main(
keybinds,
default_mode,
} => {
// TODO: notify plugins that this happened so that they can eg. rebind temporary keys that
// were lost
wasm_bridge
.reconfigure(client_id, keybinds, default_mode)
.non_fatal();
Expand Down
4 changes: 3 additions & 1 deletion zellij-server/src/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -921,12 +921,13 @@ pub(crate) fn route_action(
cwd,
pane_title,
launch_new,
plugin_id,
..
} => {
if let Some(name) = name.take() {
let should_open_in_place = in_place.unwrap_or(false);
let pane_id_to_replace = if should_open_in_place { pane_id } else { None };
if launch_new {
if launch_new && plugin_id.is_none() {
// we do this to make sure the plugin is unique (has a unique configuration parameter)
configuration
.get_or_insert_with(BTreeMap::new)
Expand All @@ -945,6 +946,7 @@ pub(crate) fn route_action(
pane_title,
skip_cache,
cli_client_id: client_id,
plugin_and_client_id: plugin_id.map(|plugin_id| (plugin_id, client_id)),
})
.with_context(err_context)?;
} else {
Expand Down
1 change: 1 addition & 0 deletions zellij-utils/src/input/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ pub enum Action {
payload: Option<String>,
args: Option<BTreeMap<String, String>>,
plugin: Option<String>,
plugin_id: Option<u32>, // supercedes plugin if present
configuration: Option<BTreeMap<String, String>>,
launch_new: bool,
skip_cache: bool,
Expand Down
66 changes: 66 additions & 0 deletions zellij-utils/src/kdl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,27 @@ pub fn kdl_arguments_that_are_strings<'a>(
Ok(args)
}

pub fn kdl_arguments_that_are_digits<'a>(
arguments: impl Iterator<Item = &'a KdlEntry>,
) -> Result<Vec<i64>, ConfigError> {
let mut args: Vec<i64> = vec![];
for kdl_entry in arguments {
match kdl_entry.value().as_i64() {
Some(digit_value) => {
args.push(digit_value);
},
None => {
return Err(ConfigError::new_kdl_error(
format!("Argument must be a digit"),
kdl_entry.span().offset(),
kdl_entry.span().len(),
));
},
}
}
Ok(args)
}

pub fn kdl_child_string_value_for_entry<'a>(
command_metadata: &'a KdlDocument,
entry_name: &'a str,
Expand Down Expand Up @@ -1010,7 +1031,12 @@ impl Action {
in_place,
cwd,
pane_title,
plugin_id,
} => {
if plugin_id.is_some() {
log::warn!("Not serializing temporary keybinding MessagePluginId");
return None;
}
let mut node = KdlNode::new("MessagePlugin");
let mut node_children = KdlDocument::new();
if let Some(plugin) = plugin {
Expand Down Expand Up @@ -1678,6 +1704,46 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
in_place: None, // TODO: support this
cwd,
pane_title: title,
plugin_id: None,
})
},
"MessagePluginId" => {
let arguments = action_arguments.iter().copied();
let mut args = kdl_arguments_that_are_digits(arguments)?;
let plugin_id = if args.is_empty() {
None
} else {
Some(args.remove(0) as u32)
};

let command_metadata = action_children.iter().next();
let launch_new = false;
let skip_cache = false;
let name = command_metadata
.and_then(|c_m| kdl_child_string_value_for_entry(c_m, "name"))
.map(|n| n.to_owned());
let payload = command_metadata
.and_then(|c_m| kdl_child_string_value_for_entry(c_m, "payload"))
.map(|p| p.to_owned());
let configuration = None;

let name = name
// if no name is provided, we use a uuid to at least have some sort of identifier for this message
.or_else(|| Some(Uuid::new_v4().to_string()));

Ok(Action::KeybindPipe {
name,
payload,
args: None, // TODO: consider supporting this if there's a need
plugin: None,
configuration,
launch_new,
skip_cache,
floating: None,
in_place: None, // TODO: support this
cwd: None,
pane_title: None,
plugin_id,
})
},
_ => Err(ConfigError::new_kdl_error(
Expand Down
1 change: 1 addition & 0 deletions zellij-utils/src/plugin_api/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,7 @@ impl TryFrom<ProtobufAction> for Action {
in_place: None,
cwd: None,
pane_title: None,
plugin_id: None,
}),
},
_ => Err("Unknown Action"),
Expand Down

0 comments on commit 08b6072

Please sign in to comment.