diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs index 5322e6a68e..bb642ecbb8 100644 --- a/zellij-server/src/lib.rs +++ b/zellij-server/src/lib.rs @@ -29,7 +29,12 @@ use zellij_utils::{ channels::{self, ChannelWithContext, SenderWithContext}, cli::CliArgs, errors::{ContextType, ErrorInstruction, ServerContext}, - input::{get_mode_info, layout::Layout, options::Options}, + input::{ + command::{RunCommand, TerminalAction}, + get_mode_info, + layout::Layout, + options::Options, + }, ipc::{ClientAttributes, ClientToServerMsg, ExitReason, ServerToClientMsg}, setup::get_default_data_dir, }; @@ -84,6 +89,7 @@ pub(crate) struct SessionMetaData { pub senders: ThreadSenders, pub capabilities: PluginCapabilities, pub palette: Palette, + pub default_shell: Option, screen_thread: Option>, pty_thread: Option>, wasm_thread: Option>, @@ -219,13 +225,21 @@ pub fn start_server(os_input: Box, socket_path: PathBuf) { ); *session_data.write().unwrap() = Some(session); *session_state.write().unwrap() = SessionState::Attached; + + let default_shell = session_data + .read() + .unwrap() + .as_ref() + .map(|session| session.default_shell.clone()) + .flatten(); + session_data .read() .unwrap() .as_ref() .unwrap() .senders - .send_to_pty(PtyInstruction::NewTab) + .send_to_pty(PtyInstruction::NewTab(default_shell.clone())) .unwrap(); } ServerInstruction::AttachClient(attrs, _, options) => { @@ -324,6 +338,13 @@ fn init_session( arrow_fonts: config_options.simplified_ui, }; + let default_shell = config_options.default_shell.clone().map(|command| { + TerminalAction::RunCommand(RunCommand { + command, + ..Default::default() + }) + }); + let pty_thread = thread::Builder::new() .name("pty".to_string()) .spawn({ @@ -393,6 +414,7 @@ fn init_session( should_silently_fail: false, }, capabilities, + default_shell, palette: client_attributes.palette, screen_thread: Some(screen_thread), pty_thread: Some(pty_thread), diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs index 8c1818bd8b..0dba3611bc 100644 --- a/zellij-server/src/pty.rs +++ b/zellij-server/src/pty.rs @@ -28,7 +28,7 @@ pub(crate) enum PtyInstruction { SpawnTerminal(Option), SpawnTerminalVertically(Option), SpawnTerminalHorizontally(Option), - NewTab, + NewTab(Option), ClosePane(PaneId), CloseTab(Vec), Exit, @@ -42,7 +42,7 @@ impl From<&PtyInstruction> for PtyContext { PtyInstruction::SpawnTerminalHorizontally(_) => PtyContext::SpawnTerminalHorizontally, PtyInstruction::ClosePane(_) => PtyContext::ClosePane, PtyInstruction::CloseTab(_) => PtyContext::CloseTab, - PtyInstruction::NewTab => PtyContext::NewTab, + PtyInstruction::NewTab(_) => PtyContext::NewTab, PtyInstruction::Exit => PtyContext::Exit, } } @@ -81,11 +81,11 @@ pub(crate) fn pty_thread_main(mut pty: Pty, maybe_layout: Option) { .send_to_screen(ScreenInstruction::HorizontalSplit(PaneId::Terminal(pid))) .unwrap(); } - PtyInstruction::NewTab => { + PtyInstruction::NewTab(terminal_action) => { if let Some(layout) = maybe_layout.clone() { - pty.spawn_terminals_for_layout(layout); + pty.spawn_terminals_for_layout(layout, terminal_action); } else { - let pid = pty.spawn_terminal(None); + let pid = pty.spawn_terminal(terminal_action); pty.bus .senders .send_to_screen(ScreenInstruction::NewTab(pid)) @@ -234,12 +234,20 @@ impl Pty { self.id_to_child_pid.insert(pid_primary, pid_secondary); pid_primary } - pub fn spawn_terminals_for_layout(&mut self, layout: Layout) { + pub fn spawn_terminals_for_layout( + &mut self, + layout: Layout, + terminal_action: Option, + ) { let total_panes = layout.total_terminal_panes(); let mut new_pane_pids = vec![]; for _ in 0..total_panes { - let (pid_primary, pid_secondary): (RawFd, Pid) = - self.bus.os_input.as_mut().unwrap().spawn_terminal(None); + let (pid_primary, pid_secondary): (RawFd, Pid) = self + .bus + .os_input + .as_mut() + .unwrap() + .spawn_terminal(terminal_action.clone()); self.id_to_child_pid.insert(pid_primary, pid_secondary); new_pane_pids.push(pid_primary); } diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs index 285f333cb6..9c0ac18fb8 100644 --- a/zellij-server/src/route.rs +++ b/zellij-server/src/route.rs @@ -133,13 +133,14 @@ fn route_action( .unwrap(); } Action::NewPane(direction) => { + let shell = session.default_shell.clone(); let pty_instr = match direction { - Some(Direction::Left) => PtyInstruction::SpawnTerminalVertically(None), - Some(Direction::Right) => PtyInstruction::SpawnTerminalVertically(None), - Some(Direction::Up) => PtyInstruction::SpawnTerminalHorizontally(None), - Some(Direction::Down) => PtyInstruction::SpawnTerminalHorizontally(None), + Some(Direction::Left) => PtyInstruction::SpawnTerminalVertically(shell), + Some(Direction::Right) => PtyInstruction::SpawnTerminalVertically(shell), + Some(Direction::Up) => PtyInstruction::SpawnTerminalHorizontally(shell), + Some(Direction::Down) => PtyInstruction::SpawnTerminalHorizontally(shell), // No direction specified - try to put it in the biggest available spot - None => PtyInstruction::SpawnTerminal(None), + None => PtyInstruction::SpawnTerminal(shell), }; session.senders.send_to_pty(pty_instr).unwrap(); } @@ -150,7 +151,11 @@ fn route_action( .unwrap(); } Action::NewTab => { - session.senders.send_to_pty(PtyInstruction::NewTab).unwrap(); + let shell = session.default_shell.clone(); + session + .senders + .send_to_pty(PtyInstruction::NewTab(shell)) + .unwrap(); } Action::GoToNextTab => { session diff --git a/zellij-utils/src/input/options.rs b/zellij-utils/src/input/options.rs index 4ebb5b86db..1057197886 100644 --- a/zellij-utils/src/input/options.rs +++ b/zellij-utils/src/input/options.rs @@ -20,6 +20,9 @@ pub struct Options { /// Set the default mode #[structopt(long)] pub default_mode: Option, + /// Set the default shell + #[structopt(long, parse(from_os_str))] + pub default_shell: Option, /// Set the layout_dir, defaults to /// subdirectory of config dir #[structopt(long, parse(from_os_str))] @@ -50,6 +53,11 @@ impl Options { other => other, }; + let default_shell = match other.default_shell { + None => self.default_shell.clone(), + other => other, + }; + let layout_dir = match other.layout_dir { None => self.layout_dir.clone(), other => other, @@ -64,6 +72,7 @@ impl Options { simplified_ui, theme, default_mode, + default_shell, layout_dir, } }