diff options
author | a-kenji <aks.kenji@protonmail.com> | 2022-06-15 11:20:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-15 11:20:06 +0200 |
commit | 0b6001305b38359d013e7119f1a649b417b22e59 (patch) | |
tree | 1f86b0bac32eea489f8f832b792ee962954b1de4 /src | |
parent | 253a14080496ba065399b94c6f6d8ba063e08f43 (diff) |
feat: add capability to dispatch actions from cli (#1265)
* feat: add capability to dispatch actions from cli
Add capability to dispatch actions from the cli.
Can be invoked through `zellij action [actions]`
Automatically sends the action either to the current session,
or if there is only one session to the single session.
If there are multiple sessions, and no session is specified it will
error out.
Example:
1.
```
zellij action "[NewTab: , NewTab: ]"
```
2.
```
zellij -s fluffy-cat action '[NewPane: , WriteChars: "echo Purrr\n" ]'
```
3.
```
zellij -s fluffy-cat action '[ CloseTab, ]
```
* add: error message on malformed input
Add an error message on malformed input, for the `action`'s dispatch.
Rather than resulting in a panic.
* add: function to query the client id
* add: send specific actions to certain clients
Adds ability to send actions, that don't impact the server state
to all connected clients. For example `MoveFocus`
* add: client_id to non blocking actions
* chore(fmt): `cargo fmt`
* add: pick correct session, if there is exactly one
* add: use correct `client_id` for detach action
* add: make `[ ]` opaque to the user
* add: miette to toplevel to improve error message
* add: fake client reading configuration
Add the fake client reading configuration files,
this allows actions, that rely on configuration work
correctly. This is an intermediate solution, and should ideally not
be needed. It would be better if most of this state would be handled
by the server itself.
* chore(fmt): rustmt
* add: ability to detach multiple clients
Add ability to detach multiple clients at the same time.
* remove: obsolete functionality
* remove: unused functionality
* add: send correct action upon exiting
* chore(update): cargo update
Diffstat (limited to 'src')
-rw-r--r-- | src/commands.rs | 68 | ||||
-rw-r--r-- | src/main.rs | 3 |
2 files changed, 71 insertions, 0 deletions
diff --git a/src/commands.rs b/src/commands.rs index f92ba8b43..7715d4353 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -6,12 +6,14 @@ use crate::sessions::{ session_exists, ActiveSession, SessionNameMatch, }; use dialoguer::Confirm; +use miette::{IntoDiagnostic, Result}; use std::path::PathBuf; use std::process; use zellij_client::start_client as start_client_impl; use zellij_client::{os_input_output::get_client_os_input, ClientInfo}; use zellij_server::os_input_output::get_server_os_input; use zellij_server::start_server as start_server_impl; +use zellij_utils::input::actions::ActionsFromYaml; use zellij_utils::input::options::Options; use zellij_utils::nix; use zellij_utils::{ @@ -112,6 +114,72 @@ fn find_indexed_session( } } +/// Send a vec of `[Action]` to a currently running session. +pub(crate) fn send_action_to_session(opts: zellij_utils::cli::CliArgs) { + match get_active_session() { + ActiveSession::None => { + eprintln!("There is no active session!"); + std::process::exit(1); + }, + ActiveSession::One(session_name) => { + attach_with_fake_client(opts, &session_name); + }, + ActiveSession::Many => { + if let Some(session_name) = opts.session.clone() { + attach_with_fake_client(opts, &session_name); + } else if let Ok(session_name) = envs::get_session_name() { + attach_with_fake_client(opts, &session_name); + } else { + println!("Please specify the session name to send actions to. The following sessions are active:"); + print_sessions(get_sessions().unwrap()); + std::process::exit(1); + } + }, + }; +} + +fn attach_with_fake_client(opts: zellij_utils::cli::CliArgs, name: &str) { + if let Some(zellij_utils::cli::Command::Sessions(zellij_utils::cli::Sessions::Action { + action, + })) = opts.command.clone() + { + if let Some(action) = action.clone() { + let action = format!("[{}]", action); + match zellij_utils::serde_yaml::from_str::<ActionsFromYaml>(&action).into_diagnostic() { + Ok(parsed) => { + let (config, _, config_options) = match Setup::from_options(&opts) { + Ok(results) => results, + Err(e) => { + eprintln!("{}", e); + process::exit(1); + }, + }; + let os_input = + get_os_input(zellij_client::os_input_output::get_client_os_input); + + let actions = parsed.actions().to_vec(); + log::debug!("Starting fake Zellij client!"); + zellij_client::fake_client::start_fake_client( + Box::new(os_input), + opts, + *Box::new(config), + config_options, + ClientInfo::New(name.to_string()), + None, + actions, + ); + log::debug!("Quitting fake client now."); + std::process::exit(0); + }, + Err(e) => { + eprintln!("{:?}", e); + std::process::exit(1); + }, + }; + } + }; +} + fn attach_with_session_index(config_options: Options, index: usize, create: bool) -> ClientInfo { // Ignore the session_name when `--index` is provided match get_sessions_sorted_by_mtime() { diff --git a/src/main.rs b/src/main.rs index 98b27581a..6e5cd9e95 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,9 @@ fn main() { if let Some(Command::Sessions(Sessions::ListSessions)) = opts.command { commands::list_sessions(); + } + if let Some(Command::Sessions(Sessions::Action { .. })) = opts.command { + commands::send_action_to_session(opts); } else if let Some(Command::Sessions(Sessions::KillAllSessions { yes })) = opts.command { commands::kill_all_sessions(yes); } else if let Some(Command::Sessions(Sessions::KillSession { ref target_session })) = |