Add mark-prompt feature flag

So far, terminals that fail to parse OSC sequences are the only reason
for wanting to turn off OSC 133.  Let's allow to work around it by
adding a feature flag (which is implied to be temporary).

To use it, run this once, and restart fish:

    set -Ua fish_features no-mark-prompt

Tested with

    fish -i | string escape | grep 133 &&
    ! fish_features=no-mark-prompt fish -i | string escape | grep 133

See #11749
Also #11609
This commit is contained in:
Johannes Altmanninger
2025-08-27 09:13:27 +02:00
parent 9c0086b7af
commit 6900b89c82
5 changed files with 39 additions and 15 deletions

View File

@@ -32,6 +32,8 @@ This release of fish fixes a number of issues identified in fish 4.0.2:
- The routines to save history and universal variables have seen some robustness improvements.
- Vi mode: The cursor position after pasting via :kbd:`p` has been corrected.
- Vi mode: Trying to replace the last character via :kbd:`r` no longer replaces the last-but-one character (:issue:`11484`),
- To work around terminals that fail to parse OSC sequences, a temporary feature flag has been added.
It allows you to disable prompt marking (OSC 133) by running (once) ``set -Ua fish_features no-mark-prompt" and restarting fish (:issue:`11749`).
fish 4.0.2 (released April 20, 2025)
====================================

View File

@@ -30,6 +30,9 @@ pub enum FeatureFlag {
/// Whether keyboard protocols (kitty's CSI x u, xterm's modifyOtherKeys) are used
keyboard_protocols,
/// Whether to write OSC 133 prompt markers
mark_prompt,
}
struct Features {
@@ -118,6 +121,14 @@ pub struct FeatureMetadata {
default_value: true,
read_only: false,
},
FeatureMetadata {
flag: FeatureFlag::mark_prompt,
name: L!("mark-prompt"),
groups: L!("4.0"),
description: L!("Write OSC 133 prompt markers to the terminal"),
default_value: true,
read_only: false,
},
];
thread_local!(
@@ -180,6 +191,7 @@ const fn new() -> Self {
AtomicBool::new(METADATA[4].default_value),
AtomicBool::new(METADATA[5].default_value),
AtomicBool::new(METADATA[6].default_value),
AtomicBool::new(METADATA[7].default_value),
],
}
}

View File

@@ -66,6 +66,7 @@
use crate::flog::{FLOG, FLOGF};
#[allow(unused_imports)]
use crate::future::IsSomeAnd;
use crate::future_feature_flags::{feature_test, FeatureFlag};
use crate::global_safety::RelaxedAtomicBool;
use crate::highlight::{
autosuggest_validate_from_history, highlight_shell, HighlightRole, HighlightSpec,
@@ -664,13 +665,15 @@ fn read_i(parser: &Parser) -> i32 {
data.command_line.clear();
data.update_buff_pos(EditableLineTag::Commandline, None);
data.command_line_changed(EditableLineTag::Commandline);
// OSC 133 "Command start"
write!(
BufferedOuputter::new(&mut Outputter::stdoutput().borrow_mut()),
"\x1b]133;C;cmdline_url={}\x07",
escape_string(&command, EscapeStringStyle::Url),
)
.unwrap();
if feature_test(FeatureFlag::mark_prompt) {
// OSC 133 "Command start"
write!(
BufferedOuputter::new(&mut Outputter::stdoutput().borrow_mut()),
"\x1b]133;C;cmdline_url={}\x07",
escape_string(&command, EscapeStringStyle::Url),
)
.unwrap();
}
event::fire_generic(parser, L!("fish_preexec").to_owned(), vec![command.clone()]);
let eval_res = reader_run_command(parser, &command);
signal_clear_cancel();
@@ -683,12 +686,14 @@ fn read_i(parser: &Parser) -> i32 {
parser.libdata_mut().exit_current_script = false;
// OSC 133 "Command finished"
write!(
BufferedOuputter::new(&mut Outputter::stdoutput().borrow_mut()),
"\x1b]133;D;{}\x07",
parser.get_last_status()
)
.unwrap();
if feature_test(FeatureFlag::mark_prompt) {
write!(
BufferedOuputter::new(&mut Outputter::stdoutput().borrow_mut()),
"\x1b]133;D;{}\x07",
parser.get_last_status()
)
.unwrap();
}
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();

View File

@@ -7,6 +7,7 @@
//! The current implementation is less smart than ncurses allows and can not for example move blocks
//! of text around to handle text insertion.
use crate::future_feature_flags::{feature_test, FeatureFlag};
use crate::pager::{PageRendering, Pager, PAGER_MIN_HEIGHT};
use std::cell::RefCell;
use std::collections::LinkedList;
@@ -931,8 +932,11 @@ fn update(
} else if left_prompt != zelf.actual_left_prompt || (zelf.scrolled && is_final_rendering) {
zelf.r#move(0, 0);
let mut start = 0;
let osc_133_prompt_start =
|zelf: &mut Screen| zelf.write_bytes(b"\x1b]133;A;special_key=1\x07");
let osc_133_prompt_start = |zelf: &mut Screen| {
if feature_test(FeatureFlag::mark_prompt) {
zelf.write_bytes(b"\x1b]133;A;special_key=1\x07");
}
};
if left_prompt_layout.line_breaks.is_empty() {
osc_133_prompt_start(&mut zelf);
}

View File

@@ -63,6 +63,7 @@ status features
#CHECK: remove-percent-self off 4.0 %self is no longer expanded (use $fish_pid)
#CHECK: test-require-arg off 4.0 builtin test requires an argument
#CHECK: keyboard-protocols on 4.0 Use keyboard protocols (kitty, xterm's modifyotherkeys
#CHECK: mark-prompt on 4.0 Write OSC 133 prompt markers to the terminal
status test-feature stderr-nocaret
echo $status
#CHECK: 0