From 149cafc6d66086c5f42c3f2f82c442d438e5b2c4 Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Mon, 27 Feb 2023 16:34:31 +0100 Subject: fix(cli): edit cwd (#2201) * fix(cli): properly set cwd for edit panes * fix(layouts): properly set cwd for edit panes * style(fmt): rustfmt --- zellij-server/src/os_input_output.rs | 9 ++++-- zellij-server/src/plugins/wasm_bridge.rs | 2 +- zellij-server/src/pty.rs | 6 ++-- zellij-server/src/route.rs | 4 +-- ...nd_cli_edit_action_with_default_parameters.snap | 4 +-- ...sts__send_cli_edit_action_with_line_number.snap | 4 +-- ..._send_cli_edit_action_with_split_direction.snap | 4 +-- zellij-utils/src/cli.rs | 2 +- zellij-utils/src/input/actions.rs | 11 +++++-- zellij-utils/src/input/command.rs | 3 +- zellij-utils/src/input/layout.rs | 35 +++++++++++++++++----- ..._with_bare_propagated_to_its_consumer_edit.snap | 5 +++- ...th_command_propagated_to_its_consumer_edit.snap | 5 +++- zellij-utils/src/kdl/kdl_layout_parser.rs | 7 +++-- 14 files changed, 71 insertions(+), 30 deletions(-) diff --git a/zellij-server/src/os_input_output.rs b/zellij-server/src/os_input_output.rs index 6e11f5ed6..a3e1fa10e 100644 --- a/zellij-server/src/os_input_output.rs +++ b/zellij-server/src/os_input_output.rs @@ -277,7 +277,12 @@ fn spawn_terminal( // secondary fd let mut failover_cmd_args = None; let cmd = match terminal_action { - TerminalAction::OpenFile(file_to_open, line_number) => { + TerminalAction::OpenFile(mut file_to_open, line_number, cwd) => { + if file_to_open.is_relative() { + if let Some(cwd) = cwd.as_ref() { + file_to_open = cwd.join(file_to_open); + } + } let mut command = default_editor.unwrap_or_else(|| { PathBuf::from( env::var("EDITOR") @@ -318,7 +323,7 @@ fn spawn_terminal( RunCommand { command, args, - cwd: None, + cwd, hold_on_close: false, hold_on_start: false, } diff --git a/zellij-server/src/plugins/wasm_bridge.rs b/zellij-server/src/plugins/wasm_bridge.rs index 77d979ac1..62e8cedb9 100644 --- a/zellij-server/src/plugins/wasm_bridge.rs +++ b/zellij-server/src/plugins/wasm_bridge.rs @@ -691,7 +691,7 @@ fn host_open_file(plugin_env: &PluginEnv) { plugin_env .senders .send_to_pty(PtyInstruction::SpawnTerminal( - Some(TerminalAction::OpenFile(path, None)), + Some(TerminalAction::OpenFile(path, None, None)), None, None, ClientOrTabIndex::TabIndex(plugin_env.tab_index), diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs index 4c4f0a910..d40a166c9 100644 --- a/zellij-server/src/pty.rs +++ b/zellij-server/src/pty.rs @@ -166,7 +166,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box) -> Result<()> { || format!("failed to open in-place editor for client {}", client_id); match pty.spawn_terminal( - Some(TerminalAction::OpenFile(temp_file, line_number)), + Some(TerminalAction::OpenFile(temp_file, line_number, None)), ClientOrTabIndex::ClientId(client_id), ) { Ok((pid, _starts_held)) => { @@ -822,7 +822,7 @@ impl Pty { }, } }, - Some(Run::EditFile(path_to_file, line_number)) => { + Some(Run::EditFile(path_to_file, line_number, cwd)) => { let starts_held = false; // we do not hold edit panes (for now?) match self .bus @@ -831,7 +831,7 @@ impl Pty { .context("no OS I/O interface found") .with_context(err_context)? .spawn_terminal( - TerminalAction::OpenFile(path_to_file, line_number), + TerminalAction::OpenFile(path_to_file, line_number, cwd), quit_cb, self.default_editor.clone(), ) diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs index 36799b5ad..53ccf964d 100644 --- a/zellij-server/src/route.rs +++ b/zellij-server/src/route.rs @@ -284,9 +284,9 @@ pub(crate) fn route_action( .send_to_pty(pty_instr) .with_context(err_context)?; }, - Action::EditFile(path_to_file, line_number, split_direction, should_float) => { + Action::EditFile(path_to_file, line_number, cwd, split_direction, should_float) => { let title = format!("Editing: {}", path_to_file.display()); - let open_file = TerminalAction::OpenFile(path_to_file, line_number); + let open_file = TerminalAction::OpenFile(path_to_file, line_number, cwd); let pty_instr = match (split_direction, should_float) { (Some(Direction::Left), false) => { PtyInstruction::SpawnTerminalVertically(Some(open_file), Some(title), client_id) diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_default_parameters.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_default_parameters.snap index 649328fe4..ccd71c6a3 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_default_parameters.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_default_parameters.snap @@ -1,6 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1944 +assertion_line: 2102 expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())" --- -[SpawnTerminal(Some(OpenFile("/file/to/edit", None)), Some(false), Some("Editing: /file/to/edit"), ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] +[SpawnTerminal(Some(OpenFile("/file/to/edit", None, Some("."))), Some(false), Some("Editing: /file/to/edit"), ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_line_number.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_line_number.snap index 92e668f41..485a2312a 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_line_number.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_line_number.snap @@ -1,6 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1989 +assertion_line: 2140 expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())" --- -[SpawnTerminal(Some(OpenFile("/file/to/edit", Some(100))), Some(false), Some("Editing: /file/to/edit"), ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] +[SpawnTerminal(Some(OpenFile("/file/to/edit", Some(100), Some("."))), Some(false), Some("Editing: /file/to/edit"), ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_split_direction.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_split_direction.snap index 3280a24e4..7b3459d5f 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_split_direction.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_edit_action_with_split_direction.snap @@ -1,6 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 2018 +assertion_line: 2178 expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())" --- -[SpawnTerminalHorizontally(Some(OpenFile("/file/to/edit", None)), Some("Editing: /file/to/edit"), 10), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] +[SpawnTerminalHorizontally(Some(OpenFile("/file/to/edit", None, Some("."))), Some("Editing: /file/to/edit"), 10), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] diff --git a/zellij-utils/src/cli.rs b/zellij-utils/src/cli.rs index 40d451d19..2733f1c74 100644 --- a/zellij-utils/src/cli.rs +++ b/zellij-utils/src/cli.rs @@ -353,7 +353,7 @@ pub enum CliAction { layout: Option, /// Default folder to look for layouts - #[clap(short, long, value_parser, requires("layout"))] + #[clap(long, value_parser, requires("layout"))] layout_dir: Option, /// Name of the new tab diff --git a/zellij-utils/src/input/actions.rs b/zellij-utils/src/input/actions.rs index 467f6a58a..a47e79f47 100644 --- a/zellij-utils/src/input/actions.rs +++ b/zellij-utils/src/input/actions.rs @@ -152,7 +152,13 @@ pub enum Action { /// If no direction is specified, will try to use the biggest available space. NewPane(Option, Option), // String is an optional pane name /// Open the file in a new pane using the default editor - EditFile(PathBuf, Option, Option, bool), // usize is an optional line number, bool is floating true/false + EditFile( + PathBuf, + Option, + Option, + Option, + bool, + ), // usize is an optional line number, Option is an optional cwd, bool is floating true/false /// Open a new floating pane NewFloatingPane(Option, Option), // String is an optional pane name /// Open a new tiled (embedded, non-floating) pane @@ -317,13 +323,14 @@ impl Action { .map(|cwd| current_dir.join(cwd)) .or_else(|| Some(current_dir)); if file.is_relative() { - if let Some(cwd) = cwd { + if let Some(cwd) = cwd.as_ref() { file = cwd.join(file); } } Ok(vec![Action::EditFile( file, line_number, + cwd, direction, floating, )]) diff --git a/zellij-utils/src/input/command.rs b/zellij-utils/src/input/command.rs index 3b6f25025..3d2a87ab3 100644 --- a/zellij-utils/src/input/command.rs +++ b/zellij-utils/src/input/command.rs @@ -5,7 +5,8 @@ use std::path::PathBuf; #[derive(Debug, Clone)] pub enum TerminalAction { - OpenFile(PathBuf, Option), // path to file and optional line_number + OpenFile(PathBuf, Option, Option), // path to file (should be absolute), optional line_number and an + // optional cwd RunCommand(RunCommand), } diff --git a/zellij-utils/src/input/layout.rs b/zellij-utils/src/input/layout.rs index a0d61b241..d6f5a2f7d 100644 --- a/zellij-utils/src/input/layout.rs +++ b/zellij-utils/src/input/layout.rs @@ -73,7 +73,7 @@ pub enum Run { Plugin(RunPlugin), #[serde(rename = "command")] Command(RunCommand), - EditFile(PathBuf, Option), // TODO: merge this with TerminalAction::OpenFile + EditFile(PathBuf, Option, Option), // TODO: merge this with TerminalAction::OpenFile Cwd(PathBuf), } @@ -108,13 +108,26 @@ impl Run { }, ( Some(Run::Command(base_run_command)), - Some(Run::EditFile(file_to_edit, line_number)), + Some(Run::EditFile(file_to_edit, line_number, edit_cwd)), ) => match &base_run_command.cwd { - Some(cwd) => Some(Run::EditFile(cwd.join(&file_to_edit), *line_number)), - None => Some(Run::EditFile(file_to_edit.clone(), *line_number)), + Some(cwd) => Some(Run::EditFile( + cwd.join(&file_to_edit), + *line_number, + Some(cwd.join(edit_cwd.clone().unwrap_or_default())), + )), + None => Some(Run::EditFile( + file_to_edit.clone(), + *line_number, + edit_cwd.clone(), + )), }, - (Some(Run::Cwd(cwd)), Some(Run::EditFile(file_to_edit, line_number))) => { - Some(Run::EditFile(cwd.join(&file_to_edit), *line_number)) + (Some(Run::Cwd(cwd)), Some(Run::EditFile(file_to_edit, line_number, edit_cwd))) => { + let cwd = edit_cwd.clone().unwrap_or(cwd.clone()); + Some(Run::EditFile( + cwd.join(&file_to_edit), + *line_number, + Some(cwd), + )) }, (Some(_base), Some(other)) => Some(other.clone()), (Some(base), _) => Some(base.clone()), @@ -132,7 +145,15 @@ impl Run { run_command.cwd = Some(cwd.clone()); }, }, - Run::EditFile(path_to_file, _line_number) => { + Run::EditFile(path_to_file, _line_number, edit_cwd) => { + match edit_cwd.as_mut() { + Some(edit_cwd) => { + *edit_cwd = cwd.join(&edit_cwd); + }, + None => { + let _ = edit_cwd.insert(cwd.clone()); + }, + }; *path_to_file = cwd.join(&path_to_file); }, Run::Cwd(path) => { diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_bare_propagated_to_its_consumer_edit.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_bare_propagated_to_its_consumer_edit.snap index 34d0fb321..68661a9c5 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_bare_propagated_to_its_consumer_edit.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_bare_propagated_to_its_consumer_edit.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1558 +assertion_line: 1614 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -21,6 +21,9 @@ Layout { EditFile( "/tmp/foo/bar", None, + Some( + "/tmp/foo", + ), ), ), borderless: false, diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_command_propagated_to_its_consumer_edit.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_command_propagated_to_its_consumer_edit.snap index 298be4e00..47469139b 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_command_propagated_to_its_consumer_edit.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_command_propagated_to_its_consumer_edit.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1574 +assertion_line: 1630 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -21,6 +21,9 @@ Layout { EditFile( "/tmp/foo/bar", None, + Some( + "/tmp/foo/", + ), ), ), borderless: false, diff --git a/zellij-utils/src/kdl/kdl_layout_parser.rs b/zellij-utils/src/kdl/kdl_layout_parser.rs index 5d89fab1b..cf6afaf70 100644 --- a/zellij-utils/src/kdl/kdl_layout_parser.rs +++ b/zellij-utils/src/kdl/kdl_layout_parser.rs @@ -374,8 +374,10 @@ impl<'a> KdlLayoutParser<'a> { hold_on_close, hold_on_start, }))), - (None, Some(edit), Some(cwd)) => Ok(Some(Run::EditFile(cwd.join(edit), None))), - (None, Some(edit), None) => Ok(Some(Run::EditFile(edit, None))), + (None, Some(edit), Some(cwd)) => { + Ok(Some(Run::EditFile(cwd.join(edit), None, Some(cwd)))) + }, + (None, Some(edit), None) => Ok(Some(Run::EditFile(edit, None, None))), (Some(_command), Some(_edit), _) => Err(ConfigError::new_layout_kdl_error( "cannot have both a command and an edit instruction for the same pane".into(), pane_node.span().offset(), @@ -962,7 +964,6 @@ impl<'a> KdlLayoutParser<'a> { .unwrap_or(false); let split_size = self.parse_split_size(kdl_node)?; let children_split_direction = self.parse_split_direction(kdl_node)?; - let is_part_of_stack = false; let (external_children_index, pane_parts) = match kdl_children_nodes!(kdl_node) { Some(children) => { self.parse_child_pane_nodes_for_pane(&children, children_are_stacked)? -- cgit v1.2.3