mirror of
https://github.com/wez/wezterm.git
synced 2024-11-23 15:04:36 +03:00
implement answerback for osc 4, 10-18
These codes are used to change the color palette, but if the `?` string is used in place of a color spec, then we must respond with the current color value string for that palette entry, so lets implement that!
This commit is contained in:
parent
bf719caaf3
commit
99919dc807
@ -12,7 +12,7 @@ use termwiz::escape::csi::{
|
||||
Cursor, DecPrivateMode, DecPrivateModeCode, Device, Edit, EraseInDisplay, EraseInLine, Mode,
|
||||
Sgr, TerminalMode, TerminalModeCode, Window,
|
||||
};
|
||||
use termwiz::escape::osc::{ITermFileData, ITermProprietary};
|
||||
use termwiz::escape::osc::{ChangeColorPair, ColorOrQuery, ITermFileData, ITermProprietary};
|
||||
use termwiz::escape::{Action, ControlCode, Esc, EscCode, OneBased, OperatingSystemCommand, CSI};
|
||||
use termwiz::hyperlink::Rule as HyperlinkRule;
|
||||
use termwiz::image::{ImageCell, ImageData, TextureCoordinate};
|
||||
@ -2108,35 +2108,56 @@ impl<'a> Performer<'a> {
|
||||
eprintln!("Application sends SystemNotification: {}", message);
|
||||
}
|
||||
OperatingSystemCommand::ChangeColorNumber(specs) => {
|
||||
eprintln!("ChangeColorNumber: {:?}", specs);
|
||||
for pair in specs {
|
||||
eprintln!(
|
||||
"ChangeColorNumber {} to {}",
|
||||
pair.palette_index,
|
||||
pair.color.to_rgb_string()
|
||||
);
|
||||
self.palette.colors.0[pair.palette_index as usize] = pair.color;
|
||||
match pair.color {
|
||||
ColorOrQuery::Query => {
|
||||
let response =
|
||||
OperatingSystemCommand::ChangeColorNumber(vec![ChangeColorPair {
|
||||
palette_index: pair.palette_index,
|
||||
color: ColorOrQuery::Color(
|
||||
self.palette.colors.0[pair.palette_index as usize],
|
||||
),
|
||||
}]);
|
||||
write!(self.host.writer(), "{}", response).ok();
|
||||
}
|
||||
ColorOrQuery::Color(c) => {
|
||||
self.palette.colors.0[pair.palette_index as usize] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.make_all_lines_dirty();
|
||||
}
|
||||
OperatingSystemCommand::ChangeDynamicColors(first_color, colors) => {
|
||||
eprintln!("ChangeDynamicColors: {:?} {:?}", first_color, colors);
|
||||
use termwiz::escape::osc::DynamicColorNumber;
|
||||
let mut idx: u8 = first_color as u8;
|
||||
for color in colors {
|
||||
let which_color: Option<DynamicColorNumber> = num::FromPrimitive::from_u8(idx);
|
||||
if let Some(which_color) = which_color {
|
||||
macro_rules! set_or_query {
|
||||
($name:ident) => {
|
||||
match color {
|
||||
ColorOrQuery::Query => {
|
||||
let response = OperatingSystemCommand::ChangeDynamicColors(
|
||||
which_color,
|
||||
vec![ColorOrQuery::Color(self.palette.$name)],
|
||||
);
|
||||
write!(self.host.writer(), "{}", response).ok();
|
||||
}
|
||||
ColorOrQuery::Color(c) => self.palette.$name = c,
|
||||
}
|
||||
};
|
||||
}
|
||||
match which_color {
|
||||
DynamicColorNumber::TextForegroundColor => {
|
||||
self.palette.foreground = color
|
||||
}
|
||||
DynamicColorNumber::TextBackgroundColor => {
|
||||
self.palette.background = color
|
||||
}
|
||||
DynamicColorNumber::TextCursorColor => self.palette.cursor_bg = color,
|
||||
DynamicColorNumber::TextForegroundColor => set_or_query!(foreground),
|
||||
DynamicColorNumber::TextBackgroundColor => set_or_query!(background),
|
||||
DynamicColorNumber::TextCursorColor => set_or_query!(cursor_bg),
|
||||
DynamicColorNumber::HighlightForegroundColor => {
|
||||
self.palette.selection_fg = color
|
||||
set_or_query!(selection_fg)
|
||||
}
|
||||
DynamicColorNumber::HighlightBackgroundColor => {
|
||||
self.palette.selection_bg = color
|
||||
set_or_query!(selection_bg)
|
||||
}
|
||||
DynamicColorNumber::MouseForegroundColor
|
||||
| DynamicColorNumber::MouseBackgroundColor
|
||||
|
@ -10,6 +10,21 @@ use std::collections::HashMap;
|
||||
use std::fmt::{Display, Error as FmtError, Formatter};
|
||||
use std::str;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ColorOrQuery {
|
||||
Color(RgbColor),
|
||||
Query,
|
||||
}
|
||||
|
||||
impl Display for ColorOrQuery {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||
match self {
|
||||
ColorOrQuery::Query => write!(f, "?"),
|
||||
ColorOrQuery::Color(c) => write!(f, "{}", c.to_rgb_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum OperatingSystemCommand {
|
||||
SetIconNameAndWindowTitle(String),
|
||||
@ -22,7 +37,7 @@ pub enum OperatingSystemCommand {
|
||||
SystemNotification(String),
|
||||
ITermProprietary(ITermProprietary),
|
||||
ChangeColorNumber(Vec<ChangeColorPair>),
|
||||
ChangeDynamicColors(DynamicColorNumber, Vec<RgbColor>),
|
||||
ChangeDynamicColors(DynamicColorNumber, Vec<ColorOrQuery>),
|
||||
|
||||
Unspecified(Vec<Vec<u8>>),
|
||||
}
|
||||
@ -45,7 +60,7 @@ pub enum DynamicColorNumber {
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ChangeColorPair {
|
||||
pub palette_index: u8,
|
||||
pub color: RgbColor,
|
||||
pub color: ColorOrQuery,
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
@ -157,8 +172,14 @@ impl OperatingSystemCommand {
|
||||
while let (Some(index), Some(spec)) = (iter.next(), iter.next()) {
|
||||
let index: u8 = str::from_utf8(index)?.parse()?;
|
||||
let spec = str::from_utf8(spec)?;
|
||||
let spec = RgbColor::from_named_or_rgb_string(spec)
|
||||
.ok_or_else(|| err_msg("invalid color spec"))?;
|
||||
let spec = if spec == "?" {
|
||||
ColorOrQuery::Query
|
||||
} else {
|
||||
ColorOrQuery::Color(
|
||||
RgbColor::from_named_or_rgb_string(spec)
|
||||
.ok_or_else(|| err_msg("invalid color spec"))?,
|
||||
)
|
||||
};
|
||||
|
||||
pairs.push(ChangeColorPair {
|
||||
palette_index: index,
|
||||
@ -174,11 +195,15 @@ impl OperatingSystemCommand {
|
||||
.ok_or_else(|| err_msg("osc code is not a valid DynamicColorNumber!?"))?;
|
||||
let mut colors = vec![];
|
||||
for spec in osc.iter().skip(1) {
|
||||
let spec = str::from_utf8(spec)?;
|
||||
colors.push(
|
||||
RgbColor::from_named_or_rgb_string(spec)
|
||||
.ok_or_else(|| err_msg("invalid color spec"))?,
|
||||
);
|
||||
if spec == b"?" {
|
||||
colors.push(ColorOrQuery::Query);
|
||||
} else {
|
||||
let spec = str::from_utf8(spec)?;
|
||||
colors.push(ColorOrQuery::Color(
|
||||
RgbColor::from_named_or_rgb_string(spec)
|
||||
.ok_or_else(|| err_msg("invalid color spec"))?,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(OperatingSystemCommand::ChangeDynamicColors(
|
||||
@ -301,13 +326,13 @@ impl Display for OperatingSystemCommand {
|
||||
ChangeColorNumber(specs) => {
|
||||
write!(f, "4;")?;
|
||||
for pair in specs {
|
||||
write!(f, "{};{}", pair.palette_index, pair.color.to_rgb_string())?
|
||||
write!(f, "{};{}", pair.palette_index, pair.color)?
|
||||
}
|
||||
}
|
||||
ChangeDynamicColors(first_color, colors) => {
|
||||
write!(f, "{}", *first_color as u8)?;
|
||||
for color in colors {
|
||||
write!(f, ";{}", color.to_rgb_string())?
|
||||
write!(f, ";{}", color)?
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user