diff options
author | Aram Drevekenin <aram@poor.dev> | 2022-10-05 07:44:00 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-05 07:44:00 +0200 |
commit | 79bf6ab868cbdab1f9a3827c9b70198f54548b44 (patch) | |
tree | 2d6fc4c1d8a79ebd727a1a5f8b6406617dd0de55 /zellij-client/src | |
parent | 917e9b2ff0f583183c0155060d243afd295770b9 (diff) |
feat(config): switch to kdl (#1759)
* chore(config): default kdl keybindings config
* tests
* work
* refactor(config): move stuff around
* work
* tab merge layout
* work
* work
* layouts working
* work
* layout tests
* work
* work
* feat(parsing): kdl layouts without config
* refactor(kdl): move stuff around
* work
* tests(layout): add cases and fix bugs
* work
* fix(kdl): various bugs
* chore(layouts): move all layouts to kdl
* feat(kdl): shared keybidns
* fix(layout): do not count fixed panes toward percentile
* fix(keybinds): missing keybinds and actions
* fix(config): adjust default tips
* refactor(config): move stuff around
* fix(tests): make e2e tests pass
* fix(kdl): add verbose parsing errors
* fix(kdl): focused tab
* fix(layout): corret default_tab_template behavior
* style(code): fix compile warnings
* feat(cli): send actions through the cli
* fix(cli): exit only when action is done
* fix(cli): open embedded pane from floating pane
* fix(cli): send actions to other sessions
* feat(cli): command alias
* feat(converter): convert old config
* feat(converter): convert old layout and theme files
* feat(kdl): pretty errors
* feat(client): convert old YAML files on startup
* fix: various bugs and styling issues
* fix: e2e tests
* fix(screen): propagate errors after merge
* style(clippy): lower clippy level
* fix(tests): own session_name variable
* style(fmt): rustfmt
* fix(cli): various action fixes
* style(fmt): rustfmt
* fix(themes): loading of theme files
* style(fmt): rustfmt
* fix(tests): theme fixtures
* fix(layouts): better errors on unknown nodes
* fix(kdl): clarify valid node terminator error
* fix(e2e): adjust close tab test
* fix(e2e): adjust close tab test again
* style(code): cleanup some comments
Diffstat (limited to 'zellij-client/src')
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>) { - |