fix(ux): LaunchPlugin and some cwd fixes (#2916)

* LaunchPlugin and some cwd fixes

* style(fmt): rustfmt

* fix e2e tests and some cleanups

* fmt
This commit is contained in:
Aram Drevekenin 2023-11-08 11:37:06 +01:00 committed by GitHub
parent d4657a2fd1
commit ea5e6aa8d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 239 additions and 17 deletions

View file

@ -184,7 +184,8 @@ pub(crate) fn plugin_thread_main(
client_id, client_id,
size, size,
cwd, cwd,
) => match wasm_bridge.load_plugin(&run, tab_index, size, cwd, Some(client_id)) { ) => match wasm_bridge.load_plugin(&run, tab_index, size, cwd.clone(), Some(client_id))
{
Ok(plugin_id) => { Ok(plugin_id) => {
drop(bus.senders.send_to_screen(ScreenInstruction::AddPlugin( drop(bus.senders.send_to_screen(ScreenInstruction::AddPlugin(
should_float, should_float,
@ -194,6 +195,7 @@ pub(crate) fn plugin_thread_main(
tab_index, tab_index,
plugin_id, plugin_id,
pane_id_to_replace, pane_id_to_replace,
cwd,
Some(client_id), Some(client_id),
))); )));
}, },
@ -231,6 +233,7 @@ pub(crate) fn plugin_thread_main(
plugin_id, plugin_id,
None, None,
None, None,
None,
))); )));
}, },
Err(e) => { Err(e) => {

View file

@ -805,6 +805,7 @@ impl<'a> PluginLoader<'a> {
client_attributes: self.client_attributes.clone(), client_attributes: self.client_attributes.clone(),
default_shell: self.default_shell.clone(), default_shell: self.default_shell.clone(),
default_layout: self.default_layout.clone(), default_layout: self.default_layout.clone(),
plugin_cwd: self.zellij_cwd.clone(),
}; };
let subscriptions = Arc::new(Mutex::new(HashSet::new())); let subscriptions = Arc::new(Mutex::new(HashSet::new()));

View file

@ -227,6 +227,7 @@ pub struct PluginEnv {
pub client_attributes: ClientAttributes, pub client_attributes: ClientAttributes,
pub default_shell: Option<TerminalAction>, pub default_shell: Option<TerminalAction>,
pub default_layout: Box<Layout>, pub default_layout: Box<Layout>,
pub plugin_cwd: PathBuf,
} }
impl PluginEnv { impl PluginEnv {

View file

@ -5398,7 +5398,7 @@ pub fn run_command_plugin_command() {
)])); )]));
background_jobs_thread.join().unwrap(); // this might take a while if the cache is cold background_jobs_thread.join().unwrap(); // this might take a while if the cache is cold
teardown(); teardown();
let new_tab_event = received_background_jobs_instructions let new_background_job = received_background_jobs_instructions
.lock() .lock()
.unwrap() .unwrap()
.iter() .iter()
@ -5410,7 +5410,7 @@ pub fn run_command_plugin_command() {
} }
}) })
.clone(); .clone();
assert_snapshot!(format!("{:#?}", new_tab_event)); assert!(format!("{:#?}", new_background_job).contains("user_value_1"));
} }
#[test] #[test]

View file

@ -374,10 +374,14 @@ fn open_file(env: &ForeignFunctionEnv, file_to_open: FileToOpen) {
let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name()); let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name());
let floating = false; let floating = false;
let in_place = false; let in_place = false;
let path = env.plugin_env.plugin_cwd.join(file_to_open.path);
let cwd = file_to_open
.cwd
.map(|cwd| env.plugin_env.plugin_cwd.join(cwd));
let action = Action::EditFile( let action = Action::EditFile(
file_to_open.path, path,
file_to_open.line_number, file_to_open.line_number,
file_to_open.cwd, cwd,
None, None,
floating, floating,
in_place, in_place,
@ -389,10 +393,14 @@ fn open_file_floating(env: &ForeignFunctionEnv, file_to_open: FileToOpen) {
let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name()); let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name());
let floating = true; let floating = true;
let in_place = false; let in_place = false;
let path = env.plugin_env.plugin_cwd.join(file_to_open.path);
let cwd = file_to_open
.cwd
.map(|cwd| env.plugin_env.plugin_cwd.join(cwd));
let action = Action::EditFile( let action = Action::EditFile(
file_to_open.path, path,
file_to_open.line_number, file_to_open.line_number,
file_to_open.cwd, cwd,
None, None,
floating, floating,
in_place, in_place,
@ -404,10 +412,14 @@ fn open_file_in_place(env: &ForeignFunctionEnv, file_to_open: FileToOpen) {
let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name()); let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name());
let floating = false; let floating = false;
let in_place = true; let in_place = true;
let path = env.plugin_env.plugin_cwd.join(file_to_open.path);
let cwd = file_to_open
.cwd
.map(|cwd| env.plugin_env.plugin_cwd.join(cwd));
let action = Action::EditFile( let action = Action::EditFile(
file_to_open.path, path,
file_to_open.line_number, file_to_open.line_number,
file_to_open.cwd, cwd,
None, None,
floating, floating,
in_place, in_place,
@ -417,6 +429,7 @@ fn open_file_in_place(env: &ForeignFunctionEnv, file_to_open: FileToOpen) {
fn open_terminal(env: &ForeignFunctionEnv, cwd: PathBuf) { fn open_terminal(env: &ForeignFunctionEnv, cwd: PathBuf) {
let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name()); let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name());
let cwd = env.plugin_env.plugin_cwd.join(cwd);
let mut default_shell = env let mut default_shell = env
.plugin_env .plugin_env
.default_shell .default_shell
@ -433,6 +446,7 @@ fn open_terminal(env: &ForeignFunctionEnv, cwd: PathBuf) {
fn open_terminal_floating(env: &ForeignFunctionEnv, cwd: PathBuf) { fn open_terminal_floating(env: &ForeignFunctionEnv, cwd: PathBuf) {
let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name()); let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name());
let cwd = env.plugin_env.plugin_cwd.join(cwd);
let mut default_shell = env let mut default_shell = env
.plugin_env .plugin_env
.default_shell .default_shell
@ -449,6 +463,7 @@ fn open_terminal_floating(env: &ForeignFunctionEnv, cwd: PathBuf) {
fn open_terminal_in_place(env: &ForeignFunctionEnv, cwd: PathBuf) { fn open_terminal_in_place(env: &ForeignFunctionEnv, cwd: PathBuf) {
let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name()); let error_msg = || format!("failed to open file in plugin {}", env.plugin_env.name());
let cwd = env.plugin_env.plugin_cwd.join(cwd);
let mut default_shell = env let mut default_shell = env
.plugin_env .plugin_env
.default_shell .default_shell
@ -466,7 +481,9 @@ fn open_terminal_in_place(env: &ForeignFunctionEnv, cwd: PathBuf) {
fn open_command_pane(env: &ForeignFunctionEnv, command_to_run: CommandToRun) { fn open_command_pane(env: &ForeignFunctionEnv, command_to_run: CommandToRun) {
let error_msg = || format!("failed to open command in plugin {}", env.plugin_env.name()); let error_msg = || format!("failed to open command in plugin {}", env.plugin_env.name());
let command = command_to_run.path; let command = command_to_run.path;
let cwd = command_to_run.cwd; let cwd = command_to_run
.cwd
.map(|cwd| env.plugin_env.plugin_cwd.join(cwd));
let args = command_to_run.args; let args = command_to_run.args;
let direction = None; let direction = None;
let hold_on_close = true; let hold_on_close = true;
@ -487,7 +504,9 @@ fn open_command_pane(env: &ForeignFunctionEnv, command_to_run: CommandToRun) {
fn open_command_pane_floating(env: &ForeignFunctionEnv, command_to_run: CommandToRun) { fn open_command_pane_floating(env: &ForeignFunctionEnv, command_to_run: CommandToRun) {
let error_msg = || format!("failed to open command in plugin {}", env.plugin_env.name()); let error_msg = || format!("failed to open command in plugin {}", env.plugin_env.name());
let command = command_to_run.path; let command = command_to_run.path;
let cwd = command_to_run.cwd; let cwd = command_to_run
.cwd
.map(|cwd| env.plugin_env.plugin_cwd.join(cwd));
let args = command_to_run.args; let args = command_to_run.args;
let direction = None; let direction = None;
let hold_on_close = true; let hold_on_close = true;
@ -508,7 +527,9 @@ fn open_command_pane_floating(env: &ForeignFunctionEnv, command_to_run: CommandT
fn open_command_pane_in_place(env: &ForeignFunctionEnv, command_to_run: CommandToRun) { fn open_command_pane_in_place(env: &ForeignFunctionEnv, command_to_run: CommandToRun) {
let error_msg = || format!("failed to open command in plugin {}", env.plugin_env.name()); let error_msg = || format!("failed to open command in plugin {}", env.plugin_env.name());
let command = command_to_run.path; let command = command_to_run.path;
let cwd = command_to_run.cwd; let cwd = command_to_run
.cwd
.map(|cwd| env.plugin_env.plugin_cwd.join(cwd));
let args = command_to_run.args; let args = command_to_run.args;
let direction = None; let direction = None;
let hold_on_close = true; let hold_on_close = true;
@ -621,6 +642,7 @@ fn run_command(
log::error!("Command cannot be empty"); log::error!("Command cannot be empty");
} else { } else {
let command = command_line.remove(0); let command = command_line.remove(0);
let cwd = env.plugin_env.plugin_cwd.join(cwd);
let _ = env let _ = env
.plugin_env .plugin_env
.senders .senders

View file

@ -705,6 +705,17 @@ pub(crate) fn route_action(
)) ))
.with_context(err_context)?; .with_context(err_context)?;
}, },
Action::LaunchPlugin(run_plugin, should_float, should_open_in_place) => {
senders
.send_to_screen(ScreenInstruction::LaunchPlugin(
run_plugin,
should_float,
should_open_in_place,
pane_id,
client_id,
))
.with_context(err_context)?;
},
Action::CloseTerminalPane(terminal_pane_id) => { Action::CloseTerminalPane(terminal_pane_id) => {
senders senders
.send_to_screen(ScreenInstruction::ClosePane( .send_to_screen(ScreenInstruction::ClosePane(

View file

@ -286,6 +286,7 @@ pub enum ScreenInstruction {
usize, // tab index usize, // tab index
u32, // plugin id u32, // plugin id
Option<PaneId>, Option<PaneId>,
Option<PathBuf>, // cwd
Option<ClientId>, Option<ClientId>,
), ),
UpdatePluginLoadingStage(u32, LoadingIndication), // u32 - plugin_id UpdatePluginLoadingStage(u32, LoadingIndication), // u32 - plugin_id
@ -293,6 +294,7 @@ pub enum ScreenInstruction {
ProgressPluginLoadingOffset(u32), // u32 - plugin id ProgressPluginLoadingOffset(u32), // u32 - plugin id
RequestStateUpdateForPlugins, RequestStateUpdateForPlugins,
LaunchOrFocusPlugin(RunPlugin, bool, bool, bool, Option<PaneId>, ClientId), // bools are: should_float, move_to_focused_tab, should_open_in_place Option<PaneId> is the pane id to replace LaunchOrFocusPlugin(RunPlugin, bool, bool, bool, Option<PaneId>, ClientId), // bools are: should_float, move_to_focused_tab, should_open_in_place Option<PaneId> is the pane id to replace
LaunchPlugin(RunPlugin, bool, bool, Option<PaneId>, ClientId), // bools are: should_float, should_open_in_place Option<PaneId> is the pane id to replace
SuppressPane(PaneId, ClientId), // bool is should_float SuppressPane(PaneId, ClientId), // bool is should_float
FocusPaneWithId(PaneId, bool, ClientId), // bool is should_float FocusPaneWithId(PaneId, bool, ClientId), // bool is should_float
RenamePane(PaneId, Vec<u8>), RenamePane(PaneId, Vec<u8>),
@ -481,6 +483,7 @@ impl From<&ScreenInstruction> for ScreenContext {
ScreenContext::RequestStateUpdateForPlugins ScreenContext::RequestStateUpdateForPlugins
}, },
ScreenInstruction::LaunchOrFocusPlugin(..) => ScreenContext::LaunchOrFocusPlugin, ScreenInstruction::LaunchOrFocusPlugin(..) => ScreenContext::LaunchOrFocusPlugin,
ScreenInstruction::LaunchPlugin(..) => ScreenContext::LaunchPlugin,
ScreenInstruction::SuppressPane(..) => ScreenContext::SuppressPane, ScreenInstruction::SuppressPane(..) => ScreenContext::SuppressPane,
ScreenInstruction::FocusPaneWithId(..) => ScreenContext::FocusPaneWithId, ScreenInstruction::FocusPaneWithId(..) => ScreenContext::FocusPaneWithId,
ScreenInstruction::RenamePane(..) => ScreenContext::RenamePane, ScreenInstruction::RenamePane(..) => ScreenContext::RenamePane,
@ -3242,10 +3245,17 @@ pub(crate) fn screen_thread_main(
tab_index, tab_index,
plugin_id, plugin_id,
pane_id_to_replace, pane_id_to_replace,
cwd,
client_id, client_id,
) => { ) => {
let pane_title = let pane_title = pane_title.unwrap_or_else(|| {
pane_title.unwrap_or_else(|| run_plugin_location.location.to_string()); format!(
"({}) - {}",
cwd.map(|cwd| cwd.display().to_string())
.unwrap_or(".".to_owned()),
run_plugin_location.location
)
});
let run_plugin = Run::Plugin(run_plugin_location); let run_plugin = Run::Plugin(run_plugin_location);
if should_be_in_place { if should_be_in_place {
@ -3399,6 +3409,70 @@ pub(crate) fn screen_thread_main(
} }
}, },
}, },
ScreenInstruction::LaunchPlugin(
run_plugin,
should_float,
should_open_in_place,
pane_id_to_replace,
client_id,
) => match pane_id_to_replace {
Some(pane_id_to_replace) => match screen.active_tab_indices.values().next() {
Some(tab_index) => {
let size = Size::default();
screen
.bus
.senders
.send_to_pty(PtyInstruction::FillPluginCwd(
Some(should_float),
should_open_in_place,
None,
run_plugin,
*tab_index,
Some(pane_id_to_replace),
client_id,
size,
))?;
},
None => {
log::error!(
"Could not find an active tab - is there at least 1 connected user?"
);
},
},
None => {
let client_id = if screen.active_tab_indices.contains_key(&client_id) {
Some(client_id)
} else {
screen.get_first_client_id()
};
let client_id_and_focused_tab = client_id.and_then(|client_id| {
screen
.active_tab_indices
.get(&client_id)
.map(|tab_index| (*tab_index, client_id))
});
match client_id_and_focused_tab {
Some((tab_index, client_id)) => {
screen
.bus
.senders
.send_to_pty(PtyInstruction::FillPluginCwd(
Some(should_float),
should_open_in_place,
None,
run_plugin,
tab_index,
None,
client_id,
Size::default(),
))?;
},
None => {
log::error!("No connected clients found - cannot load or focus plugin")
},
}
},
},
ScreenInstruction::SuppressPane(pane_id, client_id) => { ScreenInstruction::SuppressPane(pane_id, client_id) => {
let all_tabs = screen.get_tabs_mut(); let all_tabs = screen.get_tabs_mut();
for tab in all_tabs.values_mut() { for tab in all_tabs.values_mut() {

View file

@ -5,7 +5,7 @@ pub struct Action {
pub name: i32, pub name: i32,
#[prost( #[prost(
oneof = "action::OptionalPayload", oneof = "action::OptionalPayload",
tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45" tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46"
)] )]
pub optional_payload: ::core::option::Option<action::OptionalPayload>, pub optional_payload: ::core::option::Option<action::OptionalPayload>,
} }
@ -102,6 +102,8 @@ pub mod action {
RenameTabPayload(super::IdAndName), RenameTabPayload(super::IdAndName),
#[prost(string, tag = "45")] #[prost(string, tag = "45")]
RenameSessionPayload(::prost::alloc::string::String), RenameSessionPayload(::prost::alloc::string::String),
#[prost(message, tag = "46")]
LaunchPluginPayload(super::LaunchOrFocusPluginPayload),
} }
} }
#[allow(clippy::derive_partial_eq_without_eq)] #[allow(clippy::derive_partial_eq_without_eq)]
@ -403,6 +405,7 @@ pub enum ActionName {
BreakPaneRight = 78, BreakPaneRight = 78,
BreakPaneLeft = 79, BreakPaneLeft = 79,
RenameSession = 80, RenameSession = 80,
LaunchPlugin = 81,
} }
impl ActionName { impl ActionName {
/// String value of the enum field names used in the ProtoBuf definition. /// String value of the enum field names used in the ProtoBuf definition.
@ -492,6 +495,7 @@ impl ActionName {
ActionName::BreakPaneRight => "BreakPaneRight", ActionName::BreakPaneRight => "BreakPaneRight",
ActionName::BreakPaneLeft => "BreakPaneLeft", ActionName::BreakPaneLeft => "BreakPaneLeft",
ActionName::RenameSession => "RenameSession", ActionName::RenameSession => "RenameSession",
ActionName::LaunchPlugin => "LaunchPlugin",
} }
} }
/// Creates an enum from field names used in the ProtoBuf definition. /// Creates an enum from field names used in the ProtoBuf definition.
@ -578,6 +582,7 @@ impl ActionName {
"BreakPaneRight" => Some(Self::BreakPaneRight), "BreakPaneRight" => Some(Self::BreakPaneRight),
"BreakPaneLeft" => Some(Self::BreakPaneLeft), "BreakPaneLeft" => Some(Self::BreakPaneLeft),
"RenameSession" => Some(Self::RenameSession), "RenameSession" => Some(Self::RenameSession),
"LaunchPlugin" => Some(Self::LaunchPlugin),
_ => None, _ => None,
} }
} }

View file

@ -527,6 +527,15 @@ pub enum CliAction {
#[clap(short, long, value_parser)] #[clap(short, long, value_parser)]
configuration: Option<PluginUserConfiguration>, configuration: Option<PluginUserConfiguration>,
}, },
LaunchPlugin {
#[clap(short, long, value_parser)]
floating: bool,
#[clap(short, long, value_parser)]
in_place: bool,
url: Url,
#[clap(short, long, value_parser)]
configuration: Option<PluginUserConfiguration>,
},
RenameSession { RenameSession {
name: String, name: String,
}, },

View file

@ -335,6 +335,7 @@ pub enum ScreenContext {
StartPluginLoadingIndication, StartPluginLoadingIndication,
RequestStateUpdateForPlugins, RequestStateUpdateForPlugins,
LaunchOrFocusPlugin, LaunchOrFocusPlugin,
LaunchPlugin,
SuppressPane, SuppressPane,
FocusPaneWithId, FocusPaneWithId,
RenamePane, RenamePane,

View file

@ -211,6 +211,8 @@ pub enum Action {
MiddleClick(Position), MiddleClick(Position),
LaunchOrFocusPlugin(RunPlugin, bool, bool, bool), // bools => should float, LaunchOrFocusPlugin(RunPlugin, bool, bool, bool), // bools => should float,
// move_to_focused_tab, should_open_in_place // move_to_focused_tab, should_open_in_place
LaunchPlugin(RunPlugin, bool, bool), // bools => should float,
// should_open_in_place
LeftMouseRelease(Position), LeftMouseRelease(Position),
RightMouseRelease(Position), RightMouseRelease(Position),
MiddleMouseRelease(Position), MiddleMouseRelease(Position),
@ -259,6 +261,7 @@ impl Action {
match (self, other_action) { match (self, other_action) {
(Action::NewTab(..), Action::NewTab(..)) => true, (Action::NewTab(..), Action::NewTab(..)) => true,
(Action::LaunchOrFocusPlugin(..), Action::LaunchOrFocusPlugin(..)) => true, (Action::LaunchOrFocusPlugin(..), Action::LaunchOrFocusPlugin(..)) => true,
(Action::LaunchPlugin(..), Action::LaunchPlugin(..)) => true,
_ => self == other_action, _ => self == other_action,
} }
} }
@ -538,6 +541,22 @@ impl Action {
in_place, in_place,
)]) )])
}, },
CliAction::LaunchPlugin {
url,
floating,
in_place,
configuration,
} => {
let current_dir = get_current_dir();
let run_plugin_location = RunPluginLocation::parse(url.as_str(), Some(current_dir))
.map_err(|e| format!("Failed to parse plugin location: {}", e))?;
let run_plugin = RunPlugin {
location: run_plugin_location,
_allow_exec_host_cmd: false,
configuration: configuration.unwrap_or_default(),
};
Ok(vec![Action::LaunchPlugin(run_plugin, floating, in_place)])
},
CliAction::RenameSession { name } => Ok(vec![Action::RenameSession(name)]), CliAction::RenameSession { name } => Ok(vec![Action::RenameSession(name)]),
} }
} }

View file

@ -953,6 +953,39 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
should_open_in_place, should_open_in_place,
)) ))
}, },
"LaunchPlugin" => {
let arguments = action_arguments.iter().copied();
let mut args = kdl_arguments_that_are_strings(arguments)?;
if args.is_empty() {
return Err(ConfigError::new_kdl_error(
"No plugin found to launch in LaunchPlugin".into(),
kdl_action.span().offset(),
kdl_action.span().len(),
));
}
let plugin_path = args.remove(0);
let command_metadata = action_children.iter().next();
let should_float = command_metadata
.and_then(|c_m| kdl_child_bool_value_for_entry(c_m, "floating"))
.unwrap_or(false);
let should_open_in_place = command_metadata
.and_then(|c_m| kdl_child_bool_value_for_entry(c_m, "in_place"))
.unwrap_or(false);
let current_dir = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
let location = RunPluginLocation::parse(&plugin_path, Some(current_dir))?;
let configuration = KdlLayoutParser::parse_plugin_user_configuration(&kdl_action)?;
let run_plugin = RunPlugin {
location,
_allow_exec_host_cmd: false,
configuration,
};
Ok(Action::LaunchPlugin(
run_plugin,
should_float,
should_open_in_place,
))
},
"PreviousSwapLayout" => Ok(Action::PreviousSwapLayout), "PreviousSwapLayout" => Ok(Action::PreviousSwapLayout),
"NextSwapLayout" => Ok(Action::NextSwapLayout), "NextSwapLayout" => Ok(Action::NextSwapLayout),
"BreakPane" => Ok(Action::BreakPane), "BreakPane" => Ok(Action::BreakPane),

View file

@ -52,6 +52,7 @@ message Action {
IdAndName rename_plugin_pane_payload = 43; IdAndName rename_plugin_pane_payload = 43;
IdAndName rename_tab_payload = 44; IdAndName rename_tab_payload = 44;
string rename_session_payload = 45; string rename_session_payload = 45;
LaunchOrFocusPluginPayload launch_plugin_payload = 46;
} }
} }
@ -223,6 +224,7 @@ enum ActionName {
BreakPaneRight = 78; BreakPaneRight = 78;
BreakPaneLeft = 79; BreakPaneLeft = 79;
RenameSession = 80; RenameSession = 80;
LaunchPlugin = 81;
} }
message Position { message Position {

View file

@ -413,6 +413,32 @@ impl TryFrom<ProtobufAction> for Action {
_ => Err("Wrong payload for Action::LaunchOrFocusPlugin"), _ => Err("Wrong payload for Action::LaunchOrFocusPlugin"),
} }
}, },
Some(ProtobufActionName::LaunchPlugin) => match protobuf_action.optional_payload {
Some(OptionalPayload::LaunchOrFocusPluginPayload(payload)) => {
let run_plugin_location =
RunPluginLocation::parse(&payload.plugin_url, None)
.map_err(|_| "Malformed LaunchOrFocusPlugin payload")?;
let configuration: PluginUserConfiguration = payload
.plugin_configuration
.and_then(|p| PluginUserConfiguration::try_from(p).ok())
.unwrap_or_default();
let run_plugin = RunPlugin {
_allow_exec_host_cmd: false,
location: run_plugin_location,
configuration,
};
let should_float = payload.should_float;
let _move_to_focused_tab = payload.move_to_focused_tab; // not actually used in
// this action
let should_open_in_place = payload.should_open_in_place;
Ok(Action::LaunchPlugin(
run_plugin,
should_float,
should_open_in_place,
))
},
_ => Err("Wrong payload for Action::LaunchOrFocusPlugin"),
},
Some(ProtobufActionName::LeftMouseRelease) => match protobuf_action.optional_payload { Some(ProtobufActionName::LeftMouseRelease) => match protobuf_action.optional_payload {
Some(OptionalPayload::LeftMouseReleasePayload(payload)) => { Some(OptionalPayload::LeftMouseReleasePayload(payload)) => {
let position = payload.try_into()?; let position = payload.try_into()?;
@ -996,6 +1022,21 @@ impl TryFrom<Action> for ProtobufAction {
)), )),
}) })
}, },
Action::LaunchPlugin(run_plugin, should_float, should_open_in_place) => {
let url: Url = Url::from(&run_plugin.location);
Ok(ProtobufAction {
name: ProtobufActionName::LaunchPlugin as i32,
optional_payload: Some(OptionalPayload::LaunchOrFocusPluginPayload(
LaunchOrFocusPluginPayload {
plugin_url: url.into(),
should_float,
move_to_focused_tab: false,
should_open_in_place,
plugin_configuration: Some(run_plugin.configuration.try_into()?),
},
)),
})
},
Action::LeftMouseRelease(position) => { Action::LeftMouseRelease(position) => {
let position: ProtobufPosition = position.try_into()?; let position: ProtobufPosition = position.try_into()?;
Ok(ProtobufAction { Ok(ProtobufAction {