diff --git a/src/commands.rs b/src/commands.rs index 6d429cdb4b..d8f37a7a0a 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -18,7 +18,11 @@ use zellij_server::{os_input_output::get_server_os_input, start_server as start_ use zellij_utils::{ cli::{CliArgs, Command, SessionCommand, Sessions}, envs, - input::{actions::Action, config::ConfigError, options::Options}, + input::{ + actions::Action, + config::{Config, ConfigError}, + options::Options, + }, nix, setup::Setup, }; @@ -115,6 +119,7 @@ fn find_indexed_session( pub(crate) fn send_action_to_session( cli_action: zellij_utils::cli::CliAction, requested_session_name: Option, + config: Option, ) { match get_active_session() { ActiveSession::None => { @@ -132,13 +137,13 @@ pub(crate) fn send_action_to_session( std::process::exit(1); } } - attach_with_cli_client(cli_action, &session_name); + attach_with_cli_client(cli_action, &session_name, config); }, ActiveSession::Many => { 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); + attach_with_cli_client(cli_action, &session_name, config); } else { eprintln!( "Session '{}' not found. The following sessions are active:", @@ -148,7 +153,7 @@ pub(crate) fn send_action_to_session( std::process::exit(1); } } else if let Ok(session_name) = envs::get_session_name() { - attach_with_cli_client(cli_action, &session_name); + attach_with_cli_client(cli_action, &session_name, config); } else { eprintln!("Please specify the session name to send actions to. The following sessions are active:"); print_sessions(existing_sessions); @@ -226,10 +231,14 @@ pub(crate) fn convert_old_theme_file(old_theme_file: PathBuf) { } } -fn attach_with_cli_client(cli_action: zellij_utils::cli::CliAction, session_name: &str) { +fn attach_with_cli_client( + cli_action: zellij_utils::cli::CliAction, + session_name: &str, + config: Option, +) { let os_input = get_os_input(zellij_client::os_input_output::get_cli_client_os_input); let get_current_dir = || std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")); - match Action::actions_from_cli(cli_action, Box::new(get_current_dir)) { + match Action::actions_from_cli(cli_action, Box::new(get_current_dir), config) { Ok(actions) => { zellij_client::cli_client::start_cli_client(Box::new(os_input), session_name, actions); std::process::exit(0); diff --git a/src/main.rs b/src/main.rs index 77c3256d9b..54ca71cb4c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ mod tests; use zellij_utils::{ clap::Parser, cli::{CliAction, CliArgs, Command, Sessions}, + input::config::Config, logging::*, }; @@ -14,8 +15,9 @@ fn main() { let opts = CliArgs::parse(); { + let config = Config::try_from(&opts).ok(); if let Some(Command::Sessions(Sessions::Action(cli_action))) = opts.command { - commands::send_action_to_session(cli_action, opts.session); + commands::send_action_to_session(cli_action, opts.session, config); std::process::exit(0); } if let Some(Command::Sessions(Sessions::Run { @@ -37,7 +39,7 @@ fn main() { close_on_exit, start_suspended, }; - commands::send_action_to_session(command_cli_action, opts.session); + commands::send_action_to_session(command_cli_action, opts.session, config); std::process::exit(0); } if let Some(Command::Sessions(Sessions::Edit { @@ -62,7 +64,7 @@ fn main() { floating, cwd, }; - commands::send_action_to_session(command_cli_action, opts.session); + commands::send_action_to_session(command_cli_action, opts.session, config); std::process::exit(0); } if let Some(Command::Sessions(Sessions::ConvertConfig { old_config_file })) = opts.command { diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs index d40a166c9a..83255e61c5 100644 --- a/zellij-server/src/pty.rs +++ b/zellij-server/src/pty.rs @@ -455,18 +455,46 @@ impl Pty { default_editor, } } - pub fn get_default_terminal(&self, cwd: Option) -> TerminalAction { - let shell = PathBuf::from(env::var("SHELL").unwrap_or_else(|_| { - log::warn!("Cannot read SHELL env, falling back to use /bin/sh"); - "/bin/sh".to_string() - })); - TerminalAction::RunCommand(RunCommand { - args: vec![], - command: shell, - cwd, // note: this might also be filled by the calling function, eg. spawn_terminal - hold_on_close: false, - hold_on_start: false, - }) + pub fn get_default_terminal( + &self, + cwd: Option, + default_shell: Option, + ) -> TerminalAction { + match default_shell { + Some(mut default_shell) => { + if let Some(cwd) = cwd { + match default_shell { + TerminalAction::RunCommand(ref mut command) => { + command.cwd = Some(cwd); + }, + TerminalAction::OpenFile(ref file, line_number, ref mut edit_cwd) => { + match edit_cwd.as_mut() { + Some(edit_cwd) => { + *edit_cwd = cwd.join(&edit_cwd); + }, + None => { + let _ = edit_cwd.insert(cwd.clone()); + }, + }; + }, + } + } + default_shell + }, + None => { + let shell = PathBuf::from(env::var("SHELL").unwrap_or_else(|_| { + log::warn!("Cannot read SHELL env, falling back to use /bin/sh"); + "/bin/sh".to_string() + })); + TerminalAction::RunCommand(RunCommand { + args: vec![], + command: shell, + cwd, // note: this might also be filled by the calling function, eg. spawn_terminal + hold_on_close: false, + hold_on_start: false, + }) + }, + } } fn fill_cwd(&self, terminal_action: &mut TerminalAction, client_id: ClientId) { if let TerminalAction::RunCommand(run_command) = terminal_action { @@ -499,12 +527,12 @@ impl Pty { let terminal_action = match client_or_tab_index { ClientOrTabIndex::ClientId(client_id) => { let mut terminal_action = - terminal_action.unwrap_or_else(|| self.get_default_terminal(None)); + terminal_action.unwrap_or_else(|| self.get_default_terminal(None, None)); self.fill_cwd(&mut terminal_action, client_id); terminal_action }, ClientOrTabIndex::TabIndex(_) => { - terminal_action.unwrap_or_else(|| self.get_default_terminal(None)) + terminal_action.unwrap_or_else(|| self.get_default_terminal(None, None)) }, }; let (hold_on_start, hold_on_close) = match &terminal_action { @@ -589,7 +617,8 @@ impl Pty { ) -> Result<()> { let err_context = || format!("failed to spawn terminals for layout for client {client_id}"); - let mut default_shell = default_shell.unwrap_or_else(|| self.get_default_terminal(None)); + let mut default_shell = + default_shell.unwrap_or_else(|| self.get_default_terminal(None, None)); self.fill_cwd(&mut default_shell, client_id); let extracted_run_instructions = layout.extract_run_instructions(); let extracted_floating_run_instructions = @@ -800,7 +829,7 @@ impl Pty { }, Some(Run::Cwd(cwd)) => { let starts_held = false; // we do not hold Cwd panes - let shell = self.get_default_terminal(Some(cwd)); + let shell = self.get_default_terminal(Some(cwd), Some(default_shell.clone())); match self .bus .os_input diff --git a/zellij-server/src/unit/screen_tests.rs b/zellij-server/src/unit/screen_tests.rs index bf01fded5f..5c21273b0c 100644 --- a/zellij-server/src/unit/screen_tests.rs +++ b/zellij-server/src/unit/screen_tests.rs @@ -103,7 +103,7 @@ fn send_cli_action_to_server( let os_input = Box::new(mock_screen.os_input.clone()); let to_server = mock_screen.to_server.clone(); let get_current_dir = || PathBuf::from("."); - let actions = Action::actions_from_cli(cli_action, Box::new(get_current_dir)).unwrap(); + let actions = Action::actions_from_cli(cli_action, Box::new(get_current_dir), None).unwrap(); for action in actions { route_action( action, diff --git a/zellij-utils/src/input/actions.rs b/zellij-utils/src/input/actions.rs index a47e79f47f..7b7f78c433 100644 --- a/zellij-utils/src/input/actions.rs +++ b/zellij-utils/src/input/actions.rs @@ -7,7 +7,7 @@ use super::layout::{ use crate::cli::CliAction; use crate::data::InputMode; use crate::data::{Direction, Resize}; -use crate::input::config::{ConfigError, KdlError}; +use crate::input::config::{Config, ConfigError, KdlError}; use crate::input::options::OnForceClose; use crate::setup::{find_default_config_dir, get_layout_dir}; use miette::{NamedSource, Report}; @@ -237,6 +237,7 @@ impl Action { pub fn actions_from_cli( cli_action: CliAction, get_current_dir: Box PathBuf>, + config: Option, ) -> Result, String> { match cli_action { CliAction::Write { bytes } => Ok(vec![Action::Write(bytes)]), @@ -367,8 +368,9 @@ impl Action { .map(|cwd| current_dir.join(cwd)) .or_else(|| Some(current_dir)); if let Some(layout_path) = layout { - let layout_dir = - layout_dir.or_else(|| get_layout_dir(find_default_config_dir())); + let layout_dir = layout_dir + .or_else(|| config.and_then(|c| c.options.layout_dir)) + .or_else(|| get_layout_dir(find_default_config_dir())); let (path_to_raw_layout, raw_layout, swap_layouts) = Layout::stringified_from_path_or_default(Some(&layout_path), layout_dir) .map_err(|e| format!("Failed to load layout: {}", e))?;