diff --git a/crates/nu-cli/src/prompt_update.rs b/crates/nu-cli/src/prompt_update.rs index 0c24b8282a..5765755ac4 100644 --- a/crates/nu-cli/src/prompt_update.rs +++ b/crates/nu-cli/src/prompt_update.rs @@ -46,7 +46,10 @@ pub(crate) const VSCODE_POST_EXECUTION_MARKER_PREFIX: &str = "\x1b]633;D;"; #[allow(dead_code)] pub(crate) const VSCODE_POST_EXECUTION_MARKER_SUFFIX: &str = "\x1b\\"; #[allow(dead_code)] -pub(crate) const VSCODE_COMMANDLINE_MARKER: &str = "\x1b]633;E\x1b\\"; +//"\x1b]633;E;{}\x1b\\" +pub(crate) const VSCODE_COMMANDLINE_MARKER_PREFIX: &str = "\x1b]633;E;"; +#[allow(dead_code)] +pub(crate) const VSCODE_COMMANDLINE_MARKER_SUFFIX: &str = "\x1b\\"; #[allow(dead_code)] // "\x1b]633;P;Cwd={}\x1b\\" pub(crate) const VSCODE_CWD_PROPERTY_MARKER_PREFIX: &str = "\x1b]633;P;Cwd="; diff --git a/crates/nu-cli/src/repl.rs b/crates/nu-cli/src/repl.rs index 1cb6f005ef..0fd23b76d0 100644 --- a/crates/nu-cli/src/repl.rs +++ b/crates/nu-cli/src/repl.rs @@ -1,6 +1,7 @@ use crate::prompt_update::{ POST_EXECUTION_MARKER_PREFIX, POST_EXECUTION_MARKER_SUFFIX, PRE_EXECUTION_MARKER, - RESET_APPLICATION_MODE, VSCODE_CWD_PROPERTY_MARKER_PREFIX, VSCODE_CWD_PROPERTY_MARKER_SUFFIX, + RESET_APPLICATION_MODE, VSCODE_COMMANDLINE_MARKER_PREFIX, VSCODE_COMMANDLINE_MARKER_SUFFIX, + VSCODE_CWD_PROPERTY_MARKER_PREFIX, VSCODE_CWD_PROPERTY_MARKER_SUFFIX, VSCODE_POST_EXECUTION_MARKER_PREFIX, VSCODE_POST_EXECUTION_MARKER_SUFFIX, VSCODE_PRE_EXECUTION_MARKER, }; @@ -131,7 +132,26 @@ pub fn evaluate_repl( run_shell_integration_osc9_9(engine_state, &mut unique_stack, use_color); } if shell_integration_osc633 { - run_shell_integration_osc633(engine_state, &mut unique_stack, use_color); + // escape a few things because this says so + // https://code.visualstudio.com/docs/terminal/shell-integration#_vs-code-custom-sequences-osc-633-st + let cmd_text = line_editor.current_buffer_contents().to_string(); + + let replaced_cmd_text = cmd_text + .chars() + .map(|c| match c { + '\n' => '\x0a', + '\r' => '\x0d', + '\x1b' => '\x1b', + _ => c, + }) + .collect(); + + run_shell_integration_osc633( + engine_state, + &mut unique_stack, + use_color, + replaced_cmd_text, + ); } engine_state.set_startup_time(entire_start_time.elapsed().as_nanos() as i64); @@ -452,14 +472,19 @@ fn loop_iteration(ctx: LoopContext) -> (bool, Stack, Reedline) { let line_editor_input_time = std::time::Instant::now(); match input { - Ok(Signal::Success(s)) => { + Ok(Signal::Success(repl_cmd_line_text)) => { let history_supports_meta = matches!( engine_state.history_config().map(|h| h.file_format), Some(HistoryFileFormat::Sqlite) ); if history_supports_meta { - prepare_history_metadata(&s, hostname, engine_state, &mut line_editor); + prepare_history_metadata( + &repl_cmd_line_text, + hostname, + engine_state, + &mut line_editor, + ); } // For pre_exec_hook @@ -470,7 +495,7 @@ fn loop_iteration(ctx: LoopContext) -> (bool, Stack, Reedline) { if let Some(hook) = config.hooks.pre_execution.clone() { // Set the REPL buffer to the current command for the "pre_execution" hook let mut repl = engine_state.repl_state.lock().expect("repl state mutex"); - repl.buffer = s.to_string(); + repl.buffer = repl_cmd_line_text.to_string(); drop(repl); if let Err(err) = eval_hook( @@ -531,7 +556,7 @@ fn loop_iteration(ctx: LoopContext) -> (bool, Stack, Reedline) { // Actual command execution logic starts from here let cmd_execution_start_time = Instant::now(); - match parse_operation(s.clone(), engine_state, &stack) { + match parse_operation(repl_cmd_line_text.clone(), engine_state, &stack) { Ok(operation) => match operation { ReplOperation::AutoCd { cwd, target, span } => { do_auto_cd(target, cwd, &mut stack, engine_state, span); @@ -577,7 +602,7 @@ fn loop_iteration(ctx: LoopContext) -> (bool, Stack, Reedline) { if history_supports_meta { if let Err(e) = fill_in_result_related_history_metadata( - &s, + &repl_cmd_line_text, engine_state, cmd_duration, &mut stack, @@ -597,7 +622,12 @@ fn loop_iteration(ctx: LoopContext) -> (bool, Stack, Reedline) { run_shell_integration_osc9_9(engine_state, &mut stack, use_color); } if shell_integration_osc633 { - run_shell_integration_osc633(engine_state, &mut stack, use_color); + run_shell_integration_osc633( + engine_state, + &mut stack, + use_color, + repl_cmd_line_text, + ); } if shell_integration_reset_application_mode { run_shell_integration_reset_application_mode(); @@ -993,7 +1023,12 @@ fn run_shell_integration_osc9_9(engine_state: &EngineState, stack: &mut Stack, u } } -fn run_shell_integration_osc633(engine_state: &EngineState, stack: &mut Stack, use_color: bool) { +fn run_shell_integration_osc633( + engine_state: &EngineState, + stack: &mut Stack, + use_color: bool, + repl_cmd_line_text: String, +) { #[allow(deprecated)] if let Ok(path) = current_dir_str(engine_state, stack) { // Supported escape sequences of Microsoft's Visual Studio Code (vscode) @@ -1013,6 +1048,27 @@ fn run_shell_integration_osc633(engine_state: &EngineState, stack: &mut Stack, u start_time, use_color ); + + // escape a few things because this says so + // https://code.visualstudio.com/docs/terminal/shell-integration#_vs-code-custom-sequences-osc-633-st + + let replaced_cmd_text: String = repl_cmd_line_text + .chars() + .map(|c| match c { + '\n' => '\x0a', + '\r' => '\x0d', + '\x1b' => '\x1b', + _ => c, + }) + .collect(); + + //OSC 633 ; E ; [; - Mark the current working directory and communicate it to the terminal # and also helps with the run recent menu in vscode osc633: true