forked from extern/nushell
adjust where prompt markers go (#5491)
* adjust where prompt markers go * marks are working, yipee!
This commit is contained in:
parent
1d64863585
commit
94a9380e8b
@ -7,9 +7,6 @@ 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 {
|
||||||
@ -19,7 +16,6 @@ pub struct NushellPrompt {
|
|||||||
default_vi_insert_prompt_indicator: Option<String>,
|
default_vi_insert_prompt_indicator: Option<String>,
|
||||||
default_vi_normal_prompt_indicator: Option<String>,
|
default_vi_normal_prompt_indicator: Option<String>,
|
||||||
default_multiline_indicator: Option<String>,
|
default_multiline_indicator: Option<String>,
|
||||||
shell_integration: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for NushellPrompt {
|
impl Default for NushellPrompt {
|
||||||
@ -37,7 +33,6 @@ impl NushellPrompt {
|
|||||||
default_vi_insert_prompt_indicator: None,
|
default_vi_insert_prompt_indicator: None,
|
||||||
default_vi_normal_prompt_indicator: None,
|
default_vi_normal_prompt_indicator: None,
|
||||||
default_multiline_indicator: None,
|
default_multiline_indicator: None,
|
||||||
shell_integration: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,34 +82,20 @@ impl NushellPrompt {
|
|||||||
fn default_wrapped_custom_string(&self, str: String) -> String {
|
fn default_wrapped_custom_string(&self, str: String) -> String {
|
||||||
format!("({})", str)
|
format!("({})", str)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn enable_shell_integration(&mut self) {
|
|
||||||
self.shell_integration = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Prompt for NushellPrompt {
|
impl Prompt for NushellPrompt {
|
||||||
fn render_prompt_left(&self) -> Cow<str> {
|
fn render_prompt_left(&self) -> Cow<str> {
|
||||||
// Just before starting to draw the PS1 prompt send the escape code (see
|
if let Some(prompt_string) = &self.left_prompt_string {
|
||||||
// https://sw.kovidgoyal.net/kitty/shell-integration/#notes-for-shell-developers)
|
prompt_string.replace('\n', "\r\n").into()
|
||||||
let mut prompt = if self.shell_integration {
|
|
||||||
String::from(PROMPT_MARKER_BEFORE_PS1)
|
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
let default = DefaultPrompt::new();
|
||||||
};
|
default
|
||||||
|
.render_prompt_left()
|
||||||
prompt.push_str(&match &self.left_prompt_string {
|
.to_string()
|
||||||
Some(prompt_string) => prompt_string.replace('\n', "\r\n"),
|
.replace('\n', "\r\n")
|
||||||
None => {
|
.into()
|
||||||
let default = DefaultPrompt::new();
|
}
|
||||||
default
|
|
||||||
.render_prompt_left()
|
|
||||||
.to_string()
|
|
||||||
.replace('\n', "\r\n")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
prompt.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_prompt_right(&self) -> Cow<str> {
|
fn render_prompt_right(&self) -> Cow<str> {
|
||||||
@ -155,21 +136,10 @@ impl Prompt for NushellPrompt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render_prompt_multiline_indicator(&self) -> Cow<str> {
|
fn render_prompt_multiline_indicator(&self) -> Cow<str> {
|
||||||
// Just before starting to draw the PS1 prompt send the escape code (see
|
match &self.default_multiline_indicator {
|
||||||
// https://sw.kovidgoyal.net/kitty/shell-integration/#notes-for-shell-developers)
|
Some(indicator) => indicator.as_str().into(),
|
||||||
let mut prompt = if self.shell_integration {
|
None => "::: ".into(),
|
||||||
String::from(PROMPT_MARKER_BEFORE_PS2)
|
}
|
||||||
} else {
|
|
||||||
String::new()
|
|
||||||
};
|
|
||||||
|
|
||||||
prompt.push_str(
|
|
||||||
self.default_multiline_indicator
|
|
||||||
.as_ref()
|
|
||||||
.unwrap_or(&String::from("::: ")),
|
|
||||||
);
|
|
||||||
|
|
||||||
prompt.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_prompt_history_search_indicator(
|
fn render_prompt_history_search_indicator(
|
||||||
|
@ -147,10 +147,6 @@ pub(crate) fn update_prompt<'prompt>(
|
|||||||
(prompt_vi_insert_string, prompt_vi_normal_string),
|
(prompt_vi_insert_string, prompt_vi_normal_string),
|
||||||
);
|
);
|
||||||
|
|
||||||
if config.shell_integration {
|
|
||||||
nu_prompt.enable_shell_integration();
|
|
||||||
}
|
|
||||||
|
|
||||||
let ret_val = nu_prompt as &dyn Prompt;
|
let ret_val = nu_prompt as &dyn Prompt;
|
||||||
if is_perf_true {
|
if is_perf_true {
|
||||||
info!("update_prompt {}:{}:{}", file!(), line!(), column!());
|
info!("update_prompt {}:{}:{}", file!(), line!(), column!());
|
||||||
|
@ -19,7 +19,8 @@ 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 PRE_EXECUTE_MARKER: &str = "\x1b]133;A\x1b\\";
|
||||||
|
const PRE_PROMPT_MARKER: &str = "\x1b]133;C\x1b\\";
|
||||||
const RESET_APPLICATION_MODE: &str = "\x1b[?1l";
|
const RESET_APPLICATION_MODE: &str = "\x1b[?1l";
|
||||||
|
|
||||||
pub fn evaluate_repl(
|
pub fn evaluate_repl(
|
||||||
@ -206,6 +207,10 @@ pub fn evaluate_repl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.shell_integration {
|
||||||
|
run_ansi_sequence(PRE_EXECUTE_MARKER)?;
|
||||||
|
}
|
||||||
|
|
||||||
let prompt =
|
let prompt =
|
||||||
prompt_update::update_prompt(config, engine_state, stack, &mut nu_prompt, is_perf_true);
|
prompt_update::update_prompt(config, engine_state, stack, &mut nu_prompt, is_perf_true);
|
||||||
|
|
||||||
@ -221,7 +226,6 @@ 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;
|
|
||||||
|
|
||||||
match input {
|
match input {
|
||||||
Ok(Signal::Success(s)) => {
|
Ok(Signal::Success(s)) => {
|
||||||
@ -234,6 +238,27 @@ pub fn evaluate_repl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.shell_integration {
|
||||||
|
run_ansi_sequence(RESET_APPLICATION_MODE)?;
|
||||||
|
run_ansi_sequence(PRE_PROMPT_MARKER)?;
|
||||||
|
if let Some(cwd) = stack.get_env_var(engine_state, "PWD") {
|
||||||
|
let path = cwd.as_string()?;
|
||||||
|
// Try to abbreviate string for windows title
|
||||||
|
let maybe_abbrev_path = if let Some(p) = nu_path::home_dir() {
|
||||||
|
path.replace(&p.as_path().display().to_string(), "~")
|
||||||
|
} else {
|
||||||
|
path
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set window title too
|
||||||
|
// https://tldp.org/HOWTO/Xterm-Title-3.html
|
||||||
|
// ESC]0;stringBEL -- Set icon name and window title to string
|
||||||
|
// ESC]1;stringBEL -- Set icon name to string
|
||||||
|
// ESC]2;stringBEL -- Set window title to string
|
||||||
|
run_ansi_sequence(&format!("\x1b]2;{}\x07", maybe_abbrev_path))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
let tokens = lex(s.as_bytes(), 0, &[], &[], false);
|
let tokens = lex(s.as_bytes(), 0, &[], &[], false);
|
||||||
// Check if this is a single call to a directory, if so auto-cd
|
// Check if this is a single call to a directory, if so auto-cd
|
||||||
@ -321,42 +346,6 @@ pub fn evaluate_repl(
|
|||||||
let _ = std::env::set_current_dir(path);
|
let _ = std::env::set_current_dir(path);
|
||||||
engine_state.add_env_var("PWD".into(), cwd);
|
engine_state.add_env_var("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(RESET_APPLICATION_MODE);
|
|
||||||
ansi_escapes.push_str(PROMPT_MARKER_BEFORE_CMD);
|
|
||||||
if let Some(cwd) = stack.get_env_var(engine_state, "PWD") {
|
|
||||||
let path = cwd.as_string()?;
|
|
||||||
// Try to abbreviate string for windows title
|
|
||||||
let maybe_abbrev_path = if let Some(p) = nu_path::home_dir() {
|
|
||||||
path.replace(&p.as_path().display().to_string(), "~")
|
|
||||||
} else {
|
|
||||||
path
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set window title too
|
|
||||||
// https://tldp.org/HOWTO/Xterm-Title-3.html
|
|
||||||
// ESC]0;stringBEL -- Set icon name and window title to string
|
|
||||||
// ESC]1;stringBEL -- Set icon name to string
|
|
||||||
// ESC]2;stringBEL -- Set window title to string
|
|
||||||
ansi_escapes.push_str(&format!("\x1b]2;{}\x07", maybe_abbrev_path));
|
|
||||||
}
|
|
||||||
match io::stdout().write_all(ansi_escapes.as_bytes()) {
|
|
||||||
Ok(it) => it,
|
|
||||||
Err(err) => println!("error: {}", err),
|
|
||||||
};
|
|
||||||
let _ = io::stdout().flush().map_err(|e| {
|
|
||||||
ShellError::GenericError(
|
|
||||||
"Error flushing stdio".into(),
|
|
||||||
e.to_string(),
|
|
||||||
Some(Span { start: 0, end: 0 }),
|
|
||||||
None,
|
|
||||||
Vec::new(),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(Signal::CtrlC) => {
|
Ok(Signal::CtrlC) => {
|
||||||
// `Reedline` clears the line content. New prompt is shown
|
// `Reedline` clears the line content. New prompt is shown
|
||||||
@ -378,6 +367,30 @@ pub fn evaluate_repl(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run_ansi_sequence(seq: &str) -> Result<(), ShellError> {
|
||||||
|
match io::stdout().write_all(seq.as_bytes()) {
|
||||||
|
Ok(it) => it,
|
||||||
|
Err(err) => {
|
||||||
|
return Err(ShellError::GenericError(
|
||||||
|
"Error writing ansi sequence".into(),
|
||||||
|
err.to_string(),
|
||||||
|
Some(Span { start: 0, end: 0 }),
|
||||||
|
None,
|
||||||
|
Vec::new(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
io::stdout().flush().map_err(|e| {
|
||||||
|
ShellError::GenericError(
|
||||||
|
"Error flushing stdio".into(),
|
||||||
|
e.to_string(),
|
||||||
|
Some(Span { start: 0, end: 0 }),
|
||||||
|
None,
|
||||||
|
Vec::new(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run_hook(
|
pub fn run_hook(
|
||||||
engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
stack: &mut Stack,
|
stack: &mut Stack,
|
||||||
|
Loading…
Reference in New Issue
Block a user