summaryrefslogtreecommitdiffstats
path: root/zellij-client/src
diff options
context:
space:
mode:
Diffstat (limited to 'zellij-client/src')
-rw-r--r--zellij-client/src/cli_client.rs34
-rw-r--r--zellij-client/src/fake_client.rs184
-rw-r--r--zellij-client/src/input_handler.rs92
-rw-r--r--zellij-client/src/lib.rs20
-rw-r--r--zellij-client/src/old_config_converter/convert_old_yaml_files.rs332
-rw-r--r--zellij-client/src/old_config_converter/mod.rs6
-rw-r--r--zellij-client/src/old_config_converter/old_config.rs1292
-rw-r--r--zellij-client/src/old_config_converter/old_layout.rs557
-rw-r--r--zellij-client/src/old_config_converter/unit/convert_config_tests.rs126
-rw-r--r--zellij-client/src/old_config_converter/unit/convert_layout_tests.rs142
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/multiple_tabs_layout.yaml90
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/multiple_tabs_layout_htop_command.yaml93
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/old_default_yaml_config.yaml639
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/old_default_yaml_layout.yaml22
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/old_yaml_config_with_custom_options.yaml639
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/old_yaml_config_with_env_variables.yaml644
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/old_yaml_config_with_global_keybind_unbinds.yaml639
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/old_yaml_config_with_themes.yaml677
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/old_yaml_config_with_ui.yaml643
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/old_yaml_config_with_unbind_all_keys_per_mode.yaml639
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/old_yaml_config_with_unbinds_in_mode.yaml640
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/old_yaml_layout_with_config.yaml34
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/old_yaml_layout_with_config_and_session_name.yaml36
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/old_yaml_layout_with_session_name.yaml24
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/old_yaml_layout_with_session_name_and_attach_false.yaml25
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/run_htop_layout.yaml21
-rw-r--r--zellij-client/src/old_config_converter/unit/fixtures/run_htop_layout_with_plugins.yaml35
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_config__convert_config_test__convert_config_with_custom_options.snap411
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_config__convert_config_test__convert_config_with_env_variables.snap415
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_config__convert_config_test__convert_config_with_global_keybind_unbinds.snap411
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_config__convert_config_test__convert_config_with_keybind_unbinds_in_mode.snap411
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_config__convert_config_test__convert_config_with_themes_config.snap451
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_config__convert_config_test__convert_config_with_ui_config.snap416
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_config__convert_config_test__convert_config_with_unbind_all_keys_per_mode.snap410
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_config__convert_config_test__properly_convert_default_config.snap410
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_layout__convert_layout_test__properly_convert_default_layout.snap14
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_layout__convert_layout_test__properly_convert_layout_example_1.snap61
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_layout__convert_layout_test__properly_convert_layout_example_2.snap60
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_layout__convert_layout_test__properly_convert_layout_example_3.snap19
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_layout__convert_layout_test__properly_convert_layout_example_4.snap27
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_layout__convert_layout_test__properly_convert_layout_with_config.snap24
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_layout__convert_layout_test__properly_convert_layout_with_config_and_session_name.snap26
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_layout__convert_layout_test__properly_convert_layout_with_session_name.snap16
-rw-r--r--zellij-client/src/old_config_converter/unit/snapshots/zellij_client__old_config_converter__old_layout__convert_layout_test__properly_convert_layout_with_session_name_and_attach_false.snap16
-rw-r--r--zellij-client/src/sessions.rs18
45 files changed, 11639 insertions, 302 deletions
diff --git a/zellij-client/src/cli_client.rs b/zellij-client/src/cli_client.rs
new file mode 100644
index 000000000..95cd9d133
--- /dev/null
+++ b/zellij-client/src/cli_client.rs
@@ -0,0 +1,34 @@
+//! The `[cli_client]` is used to attach to a running server session
+//! and dispatch actions, that are specified through the command line.
+use std::process;
+use std::{fs, path::PathBuf};
+
+use crate::os_input_output::ClientOsApi;
+use zellij_utils::{
+ input::actions::Action,
+ ipc::{ClientToServerMsg, ServerToClientMsg},
+};
+
+pub fn start_cli_client(os_input: Box<dyn ClientOsApi>, session_name: &str, actions: Vec<Action>) {
+ let zellij_ipc_pipe: PathBuf = {
+ let mut sock_dir = zellij_utils::consts::ZELLIJ_SOCK_DIR.clone();
+ fs::create_dir_all(&sock_dir).unwrap();
+ zellij_utils::shared::set_permissions(&sock_dir, 0o700).unwrap();
+ sock_dir.push(session_name);
+ sock_dir
+ };
+ os_input.connect_to_server(&*zellij_ipc_pipe);
+ for action in actions {
+ let msg = ClientToServerMsg::Action(action, None);
+ os_input.send_to_server(msg);
+ }
+ loop {
+ match os_input.recv_from_server() {
+ Some((ServerToClientMsg::UnblockInputThread, _)) => {
+ os_input.send_to_server(ClientToServerMsg::ClientExited);
+ process::exit(0);
+ },
+ _ => {},
+ }
+ }
+}
diff --git a/zellij-client/src/fake_client.rs b/zellij-client/src/fake_client.rs
deleted file mode 100644
index 475298e95..000000000
--- a/zellij-client/src/fake_client.rs
+++ /dev/null
@@ -1,184 +0,0 @@
-//! The `[fake_client]` is used to attach to a running server session
-//! and dispatch actions, that are specified through the command line.
-//! Multiple actions at the same time can be dispatched.
-use log::debug;
-use std::sync::{Arc, Mutex};
-use std::{fs, path::PathBuf, thread};
-
-use crate::{
- command_is_executing::CommandIsExecuting, input_handler::input_actions,
- os_input_output::ClientOsApi, stdin_ansi_parser::StdinAnsiParser, stdin_handler::stdin_loop,
- ClientInfo, ClientInstruction, InputInstruction,
-};
-use zellij_utils::{
- channels::{self, ChannelWithContext, SenderWithContext},
- cli::CliArgs,
- data::{ClientId, Style},
- errors::ContextType,
- input::{actions::Action, config::Config, layout::LayoutFromYaml, options::Options},
- ipc::{ClientAttributes, ClientToServerMsg, ServerToClientMsg},
-};
-
-pub fn start_fake_client(
- os_input: Box<dyn ClientOsApi>,
- _opts: CliArgs,
- config: Config,
- config_options: Options,
- info: ClientInfo,
- _layout: Option<LayoutFromYaml>,
- actions: Vec<Action>,
-) {
- debug!("Starting fake Zellij client!");
- let session_name = info.get_session_name();
-
- // TODO: Ideally the `fake_client` would not need to specify these options,
- // but the `[NewTab:]` action depends on this state being
- // even in this client.
- let palette = config.themes.clone().map_or_else(
- || os_input.load_palette(),
- |t| {
- t.theme_config(&config_options)
- .unwrap_or_else(|| os_input.load_palette())
- },
- );
-
- let full_screen_ws = os_input.get_terminal_size_using_fd(0);
- let client_attributes = ClientAttributes {
- size: full_screen_ws,
- style: Style {
- colors: palette,
- rounded_corners: config.ui.unwrap_or_default().pane_frames.rounded_corners,
- },
- keybinds: config.keybinds.clone(),
- };
-
- let first_msg = ClientToServerMsg::AttachClient(client_attributes, config_options.clone());
-
- let zellij_ipc_pipe: PathBuf = {
- let mut sock_dir = zellij_utils::consts::ZELLIJ_SOCK_DIR.clone();
- fs::create_dir_all(&sock_dir).unwrap();
- zellij_utils::shared::set_permissions(&sock_dir, 0o700).unwrap();
- sock_dir.push(session_name);
- sock_dir
- };
- os_input.connect_to_server(&*zellij_ipc_pipe);
- os_input.send_to_server(first_msg);
-
- let mut command_is_executing = CommandIsExecuting::new();
-
- let (send_client_instructions, receive_client_instructions): ChannelWithContext<
- ClientInstruction,
- > = channels::bounded(50);
- let send_client_instructions = SenderWithContext::new(send_client_instructions);
-
- let (send_input_instructions, receive_input_instructions): ChannelWithContext<
- InputInstruction,
- > = channels::bounded(50);
- let send_input_instructions = SenderWithContext::new(send_input_instructions);
-
- std::panic::set_hook({
- use zellij_utils::errors::handle_panic;
- let send_client_instructions = send_client_instructions.clone();
- Box::new(move |info| {
- handle_panic(info, &send_client_instructions);
- })
- });
-
- let stdin_ansi_parser = Arc::new(Mutex::new(StdinAnsiParser::new()));
- let _stdin_thread = thread::Builder::new()
- .name("stdin_handler".to_string())
- .spawn({
- let os_input = os_input.clone();
- let send_input_instructions = send_input_instructions.clone();
- move || stdin_loop(os_input, send_input_instructions, stdin_ansi_parser)
- });
-
- let clients: Vec<ClientId>;
- os_input.send_to_server(ClientToServerMsg::ListClients);
- #[allow(clippy::collapsible_match)]
- loop {
- if let Some((msg, _)) = os_input.recv_from_server() {
- if let ServerToClientMsg::ActiveClients(active_clients) = msg {
- clients = active_clients;
- break;
- }
- }
- }
- debug!("The connected client id's are: {:?}.", clients);
-
- let _input_thread = thread::Builder::new()
- .name("input_handler".to_string())
- .spawn({
- let send_client_instructions = send_client_instructions.clone();
- let command_is_executing = command_is_executing.clone();
- let os_input = os_input.clone();
- let default_mode = config_options.default_mode.unwrap_or_default();
- let session_name = session_name.to_string();
- move || {
- input_actions(
- os_input,
- config,
- config_options,
- command_is_executing,
- clients,
- send_client_instructions,
- default_mode,
- receive_input_instructions,
- actions,
- session_name,
- )
- }
- });
-
- let router_thread = thread::Builder::new()
- .name("router".to_string())
- .spawn({
- let os_input = os_input.clone();
- let mut should_break = false;
- move || loop {
- if let Some((instruction, err_ctx)) = os_input.recv_from_server() {
- err_ctx.update_thread_ctx();
- if let ServerToClientMsg::Exit(_) = instruction {
- should_break = true;
- }
- send_client_instructions.send(instruction.into()).unwrap();
- if should_break {
- break;
- }
- }
- }
- })
- .unwrap();
-
- loop {
- let (client_instruction, mut err_ctx) = receive_client_instructions
- .recv()
- .expect("failed to receive app instruction on channel");
-
- err_ctx.add_call(ContextType::Client((&client_instruction).into()));
- match client_instruction {
- ClientInstruction::Exit(_) => {
- os_input.send_to_server(ClientToServerMsg::ClientExited);
- break;
- },
- ClientInstruction::Error(_) => {
- let _ = os_input.send_to_server(ClientToServerMsg::Action(Action::Quit, None));
- // handle_error(backtrace);
- },
- ClientInstruction::Render(_) => {
- // This is a fake client, that doesn't render, but
- // dispatches actions.
- },
- ClientInstruction::UnblockInputThread => {
- command_is_executing.unblock_input_thread();
- },
- ClientInstruction::SwitchToMode(input_mode) => {
- send_input_instructions
- .send(InputInstruction::SwitchToMode(input_mode))
- .unwrap();
- },
- _ => {},
- }
- }
- router_thread.join().unwrap();
-}
diff --git a/zellij-client/src/input_handler.rs b/zellij-client/src/input_handler.rs
index bebf1ee77..076ab35d6 100644
--- a/zellij-client/src/input_handler.rs
+++ b/zellij-client/src/input_handler.rs
@@ -11,7 +11,6 @@ use zellij_utils::{
actions::Action,
cast_termwiz_key,
config::Config,
- keybinds::Keybinds,
mouse::{MouseButton, MouseEvent},
options::Options,
},
@@ -133,7 +132,9 @@ impl InputHandler {
}
fn handle_key(&mut self, key: &Key, raw_bytes: Vec<u8>) {
let keybinds = &self.config.keybinds;
- for action in Keybinds::key_to_actions(key, raw_bytes, &self.mode, keybinds) {
+ for action in
+ keybinds.get_actions_for_key_in_mode_or_default_action(&self.mode, key, raw_bytes)
+ {
let should_exit = self.dispatch_action(action, None);
if should_exit {
self.should_exit = true;
@@ -230,65 +231,6 @@ impl InputHandler {
},
}
}
- fn handle_actions(&mut self, actions: Vec<Action>, session_name: &str, clients: Vec<ClientId>) {
- let mut detached = false;
- for action in actions {
- match action {
- Action::Quit => {
- crate::sessions::kill_session(session_name);
- break;
- },
- Action::Detach => {
- let first = clients.first().unwrap();
- let last = clients.last().unwrap();
- self.os_input
- .send_to_server(ClientToServerMsg::DetachSession(vec![*first, *last]));
- detached = true;
- break;
- },
- // Actions, that are independent from the specific client
- // and not session idempotent should be specified here
- Action::NewTab(_)
- | Action::Run(_)
- | Action::NewPane(_)
- | Action::WriteChars(_)
- | Action::EditScrollback
- | Action::DumpScreen(_)
- | Action::ToggleActiveSyncTab
- | Action::ToggleFloatingPanes
- | Action::TogglePaneEmbedOrFloating
- | Action::TogglePaneFrames
- | Action::ToggleFocusFullscreen
- | Action::Write(_) => {
- let client_id = clients.first().unwrap();
- log::debug!("Sending action to client: {}", client_id);
- self.dispatch_action(action, Some(*client_id));
- },
- Action::CloseFocus | Action::CloseTab => {
- let client_id = clients.first().unwrap();
- log::debug!("Sending action to client: {}", client_id);
- log::warn!("Running this action from the focused pane, can lead to unexpected behaviour.");
- self.dispatch_action(action, Some(*client_id));
- },
- _ => {
- // FIXME: If a specific `session_id` is specified,
- // then only send the actions to that specific `client_id`
- for client_id in &clients {
- self.dispatch_action(action.clone(), Some(*client_id));
- }
- },
- }
- }
- self.dispatch_ac