diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3f9705035..92e2a1522 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -133,6 +133,8 @@ Improved terminal support ^^^^^^^^^^^^^^^^^^^^^^^^^ - Fish now reports the working directory (via OSC 7) unconditionally instead of only for some terminals (:issue:`9955`). - Fish now sets the terminal window title (via OSC 0) unconditionally instead of only for some terminals (:issue:`10037`). +- Fish now marks the prompt and command-output regions (via OSC 133) to enable terminal shell integration (:issue:`10352`). + Shell integration shortcuts can scroll to the next/previous prompt or show the last command output in a pager. - Focus reporting is enabled unconditionally, not just inside tmux. To use it, define functions that handle events ``fish_focus_in`` and ``fish_focus_out``. - Focus reporting is no longer disabled on the first prompt. diff --git a/share/functions/__fish_config_interactive.fish b/share/functions/__fish_config_interactive.fish index 9138b255a..d2a7adbfe 100644 --- a/share/functions/__fish_config_interactive.fish +++ b/share/functions/__fish_config_interactive.fish @@ -200,7 +200,6 @@ end" >$__fish_config_dir/config.fish if set -q VTE_VERSION # Same for these terminals or string match -q -- 'alacritty*' $TERM - or string match -q -- '*kitty' $TERM or test "$TERM_PROGRAM" = WezTerm set -g fish_handle_reflow 0 else if set -q KONSOLE_VERSION diff --git a/src/output.rs b/src/output.rs index 35554b35c..e3a01a6bc 100644 --- a/src/output.rs +++ b/src/output.rs @@ -427,8 +427,12 @@ impl Outputter { /// Emit a terminfo string, like tputs. /// affcnt (number of lines affected) is assumed to be 1, i.e. not applicable. pub fn tputs(&mut self, str: &CStr) { + self.tputs_bytes(str.to_bytes()); + } + + pub fn tputs_bytes(&mut self, str: &[u8]) { self.begin_buffering(); - let _ = self.write(str.to_bytes()); + let _ = self.write(str); self.end_buffering(); } diff --git a/src/reader.rs b/src/reader.rs index 00ab9b427..965ce880d 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -23,6 +23,7 @@ use std::cell::UnsafeCell; use std::cmp; use std::io::BufReader; +use std::io::Write; use std::num::NonZeroUsize; use std::ops::Range; use std::os::fd::RawFd; @@ -625,6 +626,7 @@ fn read_i(parser: &Parser) -> i32 { data.update_buff_pos(EditableLineTag::Commandline, Some(0)); data.command_line.clear(); data.command_line_changed(EditableLineTag::Commandline); + data.screen.write_bytes(b"\x1b]133;C\x07"); event::fire_generic(parser, L!("fish_preexec").to_owned(), vec![command.clone()]); let eval_res = reader_run_command(parser, &command); signal_clear_cancel(); @@ -636,6 +638,11 @@ fn read_i(parser: &Parser) -> i32 { data.exit_loop_requested |= parser.libdata().pods.exit_current_script; parser.libdata_mut().pods.exit_current_script = false; + let _ = write!( + Outputter::stdoutput().borrow_mut(), + "\x1b]133;D;{}\x07", + parser.get_last_status() + ); event::fire_generic(parser, L!("fish_postexec").to_owned(), vec![command]); // Allow any pending history items to be returned in the history array. data.history.resolve_pending(); diff --git a/src/screen.rs b/src/screen.rs index 4458fae8c..3f57d5ba3 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -740,6 +740,10 @@ fn write_mbs_if_some(&mut self, s: &Option>) -> bool { self.outp.borrow_mut().tputs_if_some(s) } + pub(crate) fn write_bytes(&mut self, s: &[u8]) { + self.outp.borrow_mut().tputs_bytes(s); + } + /// Convert a wide string to a multibyte string and append it to the buffer. fn write_str(&mut self, s: &wstr) { self.outp.borrow_mut().write_wstr(s); @@ -832,6 +836,7 @@ fn update(&mut self, left_prompt: &wstr, right_prompt: &wstr, vars: &dyn Environ // Output the left prompt if it has changed. if left_prompt != zelf.actual_left_prompt { zelf.r#move(0, 0); + zelf.write_bytes(b"\x1b]133;A\x07"); let mut start = 0; for line_break in left_prompt_layout.line_breaks { zelf.write_str(&left_prompt[start..line_break]);