Try to reduce write(3) calls for OSC 133 prompt markers

Something like

	write!(f, "foo{}bar", ...)

seems to call f.write_str() thrice.

Splitting a single OSC 133 command into three calls to write(3) might result in
odd situations if one of them fails. Let's try to do it in one in most cases.

Add a new buffered output type that can be used with write!(). This is
somewhat redundant given that we have scoped_buffer().  While at it, remove
the confused error handling.  This doesn't fail unless we are OOM (and this
new type makes that more obvious).

(cherry picked from commit e5e932e970)
This commit is contained in:
Johannes Altmanninger
2025-03-03 10:37:49 +01:00
parent 7ee6d91ba0
commit d30a2c5240
2 changed files with 33 additions and 3 deletions

View File

@@ -456,6 +456,35 @@ pub fn stdoutput() -> &'static RefCell<Outputter> {
}
}
pub struct BufferedOuputter<'a>(&'a mut Outputter);
impl<'a> BufferedOuputter<'a> {
pub fn new(outputter: &'a mut Outputter) -> Self {
outputter.begin_buffering();
Self(outputter)
}
}
impl<'a> Drop for BufferedOuputter<'a> {
fn drop(&mut self) {
self.0.end_buffering();
}
}
impl<'a> Write for BufferedOuputter<'a> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.0
.write(buf)
.expect("Writing to in-memory buffer should never fail");
Ok(buf.len())
}
fn flush(&mut self) -> Result<()> {
self.0.flush().unwrap();
Ok(())
}
}
/// Given a list of RgbColor, pick the "best" one, as determined by the color support. Returns
/// RgbColor::NONE if empty.
pub fn best_color(candidates: &[RgbColor], support: ColorSupport) -> RgbColor {

View File

@@ -672,11 +672,12 @@ fn read_i(parser: &Parser) -> i32 {
parser.libdata_mut().exit_current_script = false;
// OSC 133 "Command finished"
let _ = write!(
Outputter::stdoutput().borrow_mut(),
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();