consolidate shell integration behind config setting (#5302)

* consolidate shell integration behind config setting

* write output differently
This commit is contained in:
Darren Schroeder 2022-04-23 19:53:12 -05:00 committed by GitHub
parent e2b510b65e
commit 8eab311565
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 9 deletions

View File

@ -7,6 +7,9 @@ use {
std::borrow::Cow, std::borrow::Cow,
}; };
const PROMPT_MARKER_BEFORE_PS1: &str = "\x1b]133;A\x1b\\"; // OSC 133;A ST
const PROMPT_MARKER_BEFORE_PS2: &str = "\x1b]133;A;k=s\x1b\\"; // OSC 133;A;k=s ST
/// Nushell prompt definition /// Nushell prompt definition
#[derive(Clone)] #[derive(Clone)]
pub struct NushellPrompt { pub struct NushellPrompt {
@ -95,7 +98,7 @@ impl Prompt for NushellPrompt {
// Just before starting to draw the PS1 prompt send the escape code (see // Just before starting to draw the PS1 prompt send the escape code (see
// https://sw.kovidgoyal.net/kitty/shell-integration/#notes-for-shell-developers) // https://sw.kovidgoyal.net/kitty/shell-integration/#notes-for-shell-developers)
let mut prompt = if self.shell_integration { let mut prompt = if self.shell_integration {
String::from("\x1b]133;A\x1b\\") String::from(PROMPT_MARKER_BEFORE_PS1)
} else { } else {
String::new() String::new()
}; };
@ -155,7 +158,7 @@ impl Prompt for NushellPrompt {
// Just before starting to draw the PS1 prompt send the escape code (see // Just before starting to draw the PS1 prompt send the escape code (see
// https://sw.kovidgoyal.net/kitty/shell-integration/#notes-for-shell-developers) // https://sw.kovidgoyal.net/kitty/shell-integration/#notes-for-shell-developers)
let mut prompt = if self.shell_integration { let mut prompt = if self.shell_integration {
String::from("\x1b]133;A;k=s\x1b\\") String::from(PROMPT_MARKER_BEFORE_PS2)
} else { } else {
String::new() String::new()
}; };

View File

@ -147,7 +147,7 @@ pub(crate) fn update_prompt<'prompt>(
(prompt_vi_insert_string, prompt_vi_normal_string), (prompt_vi_insert_string, prompt_vi_normal_string),
); );
if config.use_ansi_coloring { if config.shell_integration {
nu_prompt.enable_shell_integration(); nu_prompt.enable_shell_integration();
} }

View File

@ -18,9 +18,13 @@ use nu_protocol::{
ShellError, Span, Value, ShellError, Span, Value,
}; };
use reedline::{DefaultHinter, Emacs, Vi}; use reedline::{DefaultHinter, Emacs, Vi};
use std::io::{self, Write};
use std::path::PathBuf; use std::path::PathBuf;
use std::{sync::atomic::Ordering, time::Instant}; use std::{sync::atomic::Ordering, time::Instant};
const PROMPT_MARKER_BEFORE_CMD: &str = "\x1b]133;C\x1b\\"; // OSC 133;C ST
const RESET_APPLICATION_MODE: &str = "\x1b[?1l";
pub fn evaluate_repl( pub fn evaluate_repl(
engine_state: &mut EngineState, engine_state: &mut EngineState,
stack: &mut Stack, stack: &mut Stack,
@ -209,12 +213,7 @@ pub fn evaluate_repl(
} }
let input = line_editor.read_line(prompt); let input = line_editor.read_line(prompt);
let use_shell_integration = config.shell_integration;
if config.use_ansi_coloring {
// Just before running a command/program, send the escape code (see
// https://sw.kovidgoyal.net/kitty/shell-integration/#notes-for-shell-developers)
print!("\x1b]133;C\x1b\\");
}
match input { match input {
Ok(Signal::Success(s)) => { Ok(Signal::Success(s)) => {
@ -305,6 +304,22 @@ pub fn evaluate_repl(
let _ = std::env::set_current_dir(path); let _ = std::env::set_current_dir(path);
engine_state.env_vars.insert("PWD".into(), cwd); engine_state.env_vars.insert("PWD".into(), cwd);
} }
if use_shell_integration {
// Just before running a command/program, send the escape code (see
// https://sw.kovidgoyal.net/kitty/shell-integration/#notes-for-shell-developers)
let mut ansi_escapes = String::from(PROMPT_MARKER_BEFORE_CMD);
ansi_escapes.push_str(RESET_APPLICATION_MODE);
if let Some(cwd) = stack.get_env_var(engine_state, "PWD") {
let path = cwd.as_string()?;
ansi_escapes.push_str(&format!("\x1b]2;{}\x07", path));
}
// print!("{}", ansi_escapes);
match io::stdout().write_all(ansi_escapes.as_bytes()) {
Ok(it) => it,
Err(err) => print!("error: {}", err),
};
}
} }
Ok(Signal::CtrlC) => { Ok(Signal::CtrlC) => {
// `Reedline` clears the line content. New prompt is shown // `Reedline` clears the line content. New prompt is shown

View File

@ -45,6 +45,7 @@ pub struct Config {
pub keybindings: Vec<ParsedKeybinding>, pub keybindings: Vec<ParsedKeybinding>,
pub menus: Vec<ParsedMenu>, pub menus: Vec<ParsedMenu>,
pub rm_always_trash: bool, pub rm_always_trash: bool,
pub shell_integration: bool,
} }
impl Default for Config { impl Default for Config {
@ -69,6 +70,7 @@ impl Default for Config {
keybindings: Vec::new(), keybindings: Vec::new(),
menus: Vec::new(), menus: Vec::new(),
rm_always_trash: false, rm_always_trash: false,
shell_integration: false,
} }
} }
} }
@ -236,6 +238,14 @@ impl Value {
eprintln!("{:?}", e); eprintln!("{:?}", e);
} }
}, },
"shell_integration" => {
if let Ok(b) = value.as_bool() {
config.shell_integration = b;
} else {
eprintln!("$config.shell_integration is not a bool")
}
}
x => { x => {
eprintln!("$config.{} is an unknown config setting", x) eprintln!("$config.{} is an unknown config setting", x)
} }

View File

@ -194,6 +194,7 @@ let-env config = {
edit_mode: emacs # emacs, vi edit_mode: emacs # emacs, vi
max_history_size: 10000 # Session has to be reloaded for this to take effect max_history_size: 10000 # Session has to be reloaded for this to take effect
sync_history_on_enter: true # Enable to share the history between multiple sessions, else you have to close the session to persist history to file sync_history_on_enter: true # Enable to share the history between multiple sessions, else you have to close the session to persist history to file
shell_integration: true # enables terminal markers and a workaround to arrow keys stop working issue
menus: [ menus: [
# Configuration for default nushell menus # Configuration for default nushell menus
# Note the lack of souce parameter # Note the lack of souce parameter