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 /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 'src')
33 files changed, 246 insertions, 419 deletions
diff --git a/src/commands.rs b/src/commands.rs index 58a464d77..b4e2e1da2 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -6,13 +6,18 @@ use crate::sessions::{ session_exists, ActiveSession, SessionNameMatch, }; use dialoguer::Confirm; -use miette::Result; +use miette::{Report, Result}; use std::path::PathBuf; use std::process; +use zellij_client::old_config_converter::{ + config_yaml_to_config_kdl, convert_old_yaml_files, layout_yaml_to_layout_kdl, +}; 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::Action; +use zellij_utils::input::config::ConfigError; use zellij_utils::input::options::Options; use zellij_utils::nix; use zellij_utils::{ @@ -21,10 +26,7 @@ use zellij_utils::{ setup::{get_default_data_dir, Setup}, }; -#[cfg(feature = "unstable")] -use miette::IntoDiagnostic; -#[cfg(feature = "unstable")] -use zellij_utils::input::actions::ActionsFromYaml; +use std::{fs::File, io::prelude::*}; pub(crate) use crate::sessions::list_sessions; @@ -118,69 +120,133 @@ fn find_indexed_session( } } -/// Send a vec of `[Action]` to a currently running session. -#[cfg(feature = "unstable")] -pub(crate) fn send_action_to_session(opts: zellij_utils::cli::CliArgs) { +pub(crate) fn send_action_to_session( + cli_action: zellij_utils::cli::CliAction, + requested_session_name: Option<String>, +) { 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); + if let Some(requested_session_name) = requested_session_name { + if requested_session_name != session_name { + eprintln!( + "Session '{}' not found. The following sessions are active:", + requested_session_name + ); + eprintln!("{}", session_name); + std::process::exit(1); + } + } + attach_with_cli_client(cli_action, &session_name); }, ActiveSession::Many => { - if let Some(session_name) = opts.session.clone() { - attach_with_fake_client(opts, &session_name); + let existing_sessions = get_sessions().unwrap(); + if let Some(session_name) = requested_session_name { + if existing_sessions.contains(&session_name) { + attach_with_cli_client(cli_action, &session_name); + } else { + eprintln!( + "Session '{}' not found. The following sessions are active:", + session_name + ); + print_sessions(existing_sessions); + std::process::exit(1); + } } else if let Ok(session_name) = envs::get_session_name() { - attach_with_fake_client(opts, &session_name); + attach_with_cli_client(cli_action, &session_name); } else { - println!("Please specify the session name to send actions to. The following sessions are active:"); - print_sessions(get_sessions().unwrap()); + eprintln!("Please specify the session name to send actions to. The following sessions are active:"); + print_sessions(existing_sessions); std::process::exit(1); } }, }; } +pub(crate) fn convert_old_config_file(old_config_file: PathBuf) { + match File::open(&old_config_file) { + Ok(mut handle) => { + let mut raw_config_file = String::new(); + let _ = handle.read_to_string(&mut raw_config_file); + match config_yaml_to_config_kdl(&raw_config_file, false) { + Ok(kdl_config) => { + println!("{}", kdl_config); + process::exit(0); + }, + Err(e) => { + eprintln!("Failed to convert config: {}", e); + process::exit(1); + }, + } + }, + Err(e) => { + eprintln!("Failed to open file: {}", e); + process::exit(1); + }, + } +} -#[cfg(feature = "unstable")] -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: Some(action), - })) = opts.command.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); +pub(crate) fn convert_old_layout_file(old_layout_file: PathBuf) { + match File::open(&old_layout_file) { + Ok(mut handle) => { + let mut raw_layout_file = String::new(); + let _ = handle.read_to_string(&mut raw_layout_file); + match layout_yaml_to_layout_kdl(&raw_layout_file) { + Ok(kdl_layout) => { + println!("{}", kdl_layout); + process::exit(0); + }, + Err(e) => { + eprintln!("Failed to convert layout: {}", e); + process::exit(1); + }, + } + }, + Err(e) => { + eprintln!("Failed to open file: {}", e); + process::exit(1); + }, + } +} - 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); - }, - }; - }; +pub(crate) fn convert_old_theme_file(old_theme_file: PathBuf) { + match File::open(&old_theme_file) { + Ok(mut handle) => { + let mut raw_config_file = String::new(); + let _ = handle.read_to_string(&mut raw_config_file); + match config_yaml_to_config_kdl(&raw_config_file, true) { + Ok(kdl_config) => { + println!("{}", kdl_config); + process::exit(0); + }, + Err(e) => { + eprintln!("Failed to convert config: {}", e); + process::exit(1); + }, + } + }, + Err(e) => { + eprintln!("Failed to open file: {}", e); + process::exit(1); + }, + } +} + +fn attach_with_cli_client(cli_action: zellij_utils::cli::CliAction, session_name: &str) { + let os_input = get_os_input(zellij_client::os_input_output::get_client_os_input); + match Action::actions_from_cli(cli_action) { + Ok(actions) => { + zellij_client::cli_client::start_cli_client(Box::new(os_input), session_name, actions); + std::process::exit(0); + }, + Err(e) => { + eprintln!("{}", e); + log::error!("Error sending action: {}", e); + std::process::exit(2); + }, + } } fn attach_with_session_index(config_options: Options, index: usize, create: bool) -> ClientInfo { @@ -249,10 +315,17 @@ fn attach_with_session_name( } pub(crate) fn start_client(opts: CliArgs) { - let (config, layout, config_options) = match Setup::from_options(&opts) { + // look for old YAML config/layout/theme files and convert them to KDL + convert_old_yaml_files(&opts); + let (config, layout, config_options) = match Setup::from_cli_args(&opts) { Ok(results) => results, Err(e) => { - eprintln!("{}", e); + if let ConfigError::KdlError(error) = e { + let report: Report = error.into(); + eprintln!("{:?}", report); + } else { + eprintln!("{}", e); + } process::exit(1); }, }; @@ -285,7 +358,7 @@ pub(crate) fn start_client(opts: CliArgs) { let attach_layout = match client { ClientInfo::Attach(_, _) => None, - ClientInfo::New(_) => layout, + ClientInfo::New(_) => Some(layout), }; if create { @@ -314,23 +387,21 @@ pub(crate) fn start_client(opts: CliArgs) { config, config_options, ClientInfo::New(session_name), - layout, + Some(layout), ); } else { - if let Some(layout_some) = layout.clone() { - if let Some(session_name) = layout_some.session.name { - if layout_some.session.attach.unwrap() { + if let Some(session_name) = config_options.session_name.as_ref() { + match config_options.attach_to_session { + Some(true) => { let client = attach_with_session_name( - Some(session_name), + Some(session_name.clone()), config_options.clone(), true, ); - let attach_layout = match client { ClientInfo::Attach(_, _) => None, - ClientInfo::New(_) => layout, + ClientInfo::New(_) => Some(layout), }; - start_client_impl( Box::new(os_input), opts, @@ -339,20 +410,23 @@ pub(crate) fn start_client(opts: CliArgs) { client, attach_layout, ); - } else { + }, + _ => { start_client_plan(session_name.clone()); start_client_impl( Box::new(os_input), opts, config, - config_options, - ClientInfo::New(session_name), - layout, + config_options.clone(), + ClientInfo::New(session_name.clone()), + Some(layout), ); - } - - process::exit(0); + }, } + // after we detach, this happens and so we need to exit before the rest of the + // function happens + // TODO: offload this to a different function + process::exit(0); } let session_name = names::Generator::default().next().unwrap(); @@ -363,7 +437,7 @@ pub(crate) fn start_client(opts: CliArgs) { config, config_options, ClientInfo::New(session_name), - layout, + Some(layout), ); } } diff --git a/src/main.rs b/src/main.rs index ca05dbf10..d2363e7bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ mod tests; use zellij_utils::{ clap::Parser, - cli::{CliArgs, Command, Sessions}, + cli::{CliAction, CliArgs, Command, Sessions}, logging::*, }; @@ -14,10 +14,53 @@ fn main() { configure_logger(); let opts = CliArgs::parse(); - #[cfg(feature = "unstable")] { - if let Some(Command::Sessions(Sessions::Action { .. })) = opts.command { - commands::send_action_to_session(opts); + if let Some(Command::Sessions(Sessions::Action(cli_action))) = opts.command { + commands::send_action_to_session(cli_action, opts.session); + std::process::exit(0); + } + if let Some(Command::Sessions(Sessions::Command { + command, + direction, + cwd, + floating, + })) = opts.command + { + let command_cli_action = CliAction::NewPane { + command, + direction, + cwd, + floating, + }; + commands::send_action_to_session(command_cli_action, opts.session); + std::process::exit(0); + } + if let Some(Command::Sessions(Sessions::Edit { + file, + direction, + line_number, + floating, + })) = opts.command + { + let command_cli_action = CliAction::Edit { + file, + direction, + line_number, + floating, + }; + commands::send_action_to_session(command_cli_action, opts.session); + std::process::exit(0); + } + if let Some(Command::Sessions(Sessions::ConvertConfig { old_config_file })) = opts.command { + commands::convert_old_config_file(old_config_file); + std::process::exit(0); + } + if let Some(Command::Sessions(Sessions::ConvertLayout { old_layout_file })) = opts.command { + commands::convert_old_layout_file(old_layout_file); + std::process::exit(0); + } + if let Some(Command::Sessions(Sessions::ConvertTheme { old_theme_file })) = opts.command { + commands::convert_old_theme_file(old_theme_file); std::process::exit(0); } } diff --git a/src/tests/e2e/cases.rs b/src/tests/e2e/cases.rs index 7457ed544..63e2d6778 100644 --- a/src/tests/e2e/cases.rs +++ b/src/tests/e2e/cases.rs @@ -458,9 +458,8 @@ pub fn close_tab() { name: "Wait for tab to close", instruction: |mut remote_terminal: RemoteTerminal| -> bool { let mut step_is_complete = false; - if remote_terminal.cursor_position_is(3, 2) + if remote_terminal.snapshot_contains("Tab #1") && !remote_terminal.snapshot_contains("Tab #2") - && remote_terminal.tip_appears() { // cursor is in the first tab again |