shell_integration: Report current working directory as OSC 7 (#6481)

This is a de-facto standard supported by many terminals, originally
added to macOS Terminal.app, now also supported by VTE (GNOME),
Konsole (KDE), WezTerm, and more.
This commit is contained in:
unrelentingtech 2022-09-13 15:36:53 +03:00 committed by GitHub
parent 8564c5371f
commit df6a7b6f5c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 1 deletions

1
Cargo.lock generated
View file

@ -2649,6 +2649,7 @@ dependencies = [
"nu-protocol", "nu-protocol",
"nu-test-support", "nu-test-support",
"nu-utils", "nu-utils",
"percent-encoding",
"reedline", "reedline",
"rstest", "rstest",
"strip-ansi-escapes", "strip-ansi-escapes",

View file

@ -31,6 +31,7 @@ is_executable = "1.0.1"
lazy_static = "1.4.0" lazy_static = "1.4.0"
log = "0.4" log = "0.4"
miette = { version = "5.1.0", features = ["fancy"] } miette = { version = "5.1.0", features = ["fancy"] }
percent-encoding = "2"
strip-ansi-escapes = "0.1.1" strip-ansi-escapes = "0.1.1"
sysinfo = "0.25.2" sysinfo = "0.25.2"
thiserror = "1.0.31" thiserror = "1.0.31"

View file

@ -332,6 +332,7 @@ pub fn evaluate_repl(
match input { match input {
Ok(Signal::Success(s)) => { Ok(Signal::Success(s)) => {
let hostname = sys.host_name();
let history_supports_meta = let history_supports_meta =
matches!(config.history_file_format, HistoryFileFormat::Sqlite); matches!(config.history_file_format, HistoryFileFormat::Sqlite);
if history_supports_meta && !s.is_empty() && line_editor.has_last_command_context() if history_supports_meta && !s.is_empty() && line_editor.has_last_command_context()
@ -339,7 +340,7 @@ pub fn evaluate_repl(
line_editor line_editor
.update_last_command_context(&|mut c| { .update_last_command_context(&|mut c| {
c.start_timestamp = Some(chrono::Utc::now()); c.start_timestamp = Some(chrono::Utc::now());
c.hostname = sys.host_name(); c.hostname = hostname.clone();
c.cwd = Some(StateWorkingSet::new(engine_state).get_cwd()); c.cwd = Some(StateWorkingSet::new(engine_state).get_cwd());
c c
@ -479,6 +480,21 @@ pub fn evaluate_repl(
run_ansi_sequence(&get_command_finished_marker(stack, engine_state))?; run_ansi_sequence(&get_command_finished_marker(stack, engine_state))?;
if let Some(cwd) = stack.get_env_var(engine_state, "PWD") { if let Some(cwd) = stack.get_env_var(engine_state, "PWD") {
let path = cwd.as_string()?; let path = cwd.as_string()?;
// Communicate the path as OSC 7 (often used for spawning new tabs in the same dir)
run_ansi_sequence(&format!(
"\x1b]7;file://{}{}{}\x1b\\",
percent_encoding::utf8_percent_encode(
&hostname.unwrap_or_else(|| "localhost".to_string()),
percent_encoding::CONTROLS
),
if path.starts_with('/') { "" } else { "/" },
percent_encoding::utf8_percent_encode(
&path,
percent_encoding::CONTROLS
)
))?;
// Try to abbreviate string for windows title // Try to abbreviate string for windows title
let maybe_abbrev_path = if let Some(p) = nu_path::home_dir() { let maybe_abbrev_path = if let Some(p) = nu_path::home_dir() {
path.replace(&p.as_path().display().to_string(), "~") path.replace(&p.as_path().display().to_string(), "~")