mirror of
https://github.com/wez/wezterm.git
synced 2024-11-22 13:16:39 +03:00
termwiz: recognize some bidi-related escape sequences
We don't do anything with these; this is just teaching the parser how to recognize these codes. refs: https://github.com/wez/wezterm/issues/784
This commit is contained in:
parent
2deba1ece4
commit
85a6b178cf
@ -412,6 +412,9 @@ impl<'a> Performer<'a> {
|
||||
CSI::Device(dev) => self.state.perform_device(*dev),
|
||||
CSI::Mouse(mouse) => error!("mouse report sent by app? {:?}", mouse),
|
||||
CSI::Window(window) => self.state.perform_csi_window(window),
|
||||
CSI::SelectCharacterPath(path, _) => {
|
||||
log::warn!("unhandled SelectCharacterPath {:?}", path);
|
||||
}
|
||||
CSI::Unspecified(unspec) => {
|
||||
log::warn!("unknown unspecified CSI: {:?}", format!("{}", unspec))
|
||||
}
|
||||
|
@ -27,12 +27,25 @@ pub enum CSI {
|
||||
|
||||
Window(Window),
|
||||
|
||||
/// ECMA-48 SCP
|
||||
SelectCharacterPath(CharacterPath, i64),
|
||||
|
||||
/// Unknown or unspecified; should be rare and is rather
|
||||
/// large, so it is boxed and kept outside of the enum
|
||||
/// body to help reduce space usage in the common cases.
|
||||
Unspecified(Box<Unspecified>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum CharacterPath {
|
||||
/// 0
|
||||
ImplementationDefault,
|
||||
/// 1
|
||||
LeftToRightOrTopToBottom,
|
||||
/// 2
|
||||
RightToLeftOrBottomToTop,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Unspecified {
|
||||
pub params: Vec<CsiParam>,
|
||||
@ -69,6 +82,18 @@ impl Display for CSI {
|
||||
CSI::Mouse(mouse) => mouse.fmt(f)?,
|
||||
CSI::Device(dev) => dev.fmt(f)?,
|
||||
CSI::Window(window) => window.fmt(f)?,
|
||||
CSI::SelectCharacterPath(path, n) => {
|
||||
let a = match path {
|
||||
CharacterPath::ImplementationDefault => 0,
|
||||
CharacterPath::LeftToRightOrTopToBottom => 1,
|
||||
CharacterPath::RightToLeftOrBottomToTop => 2,
|
||||
};
|
||||
match (a, n) {
|
||||
(0, 0) => write!(f, " k")?,
|
||||
(a, 0) => write!(f, "{} k", a)?,
|
||||
(a, n) => write!(f, "{};{} k", a, n)?,
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
@ -775,6 +800,8 @@ pub enum TerminalModeCode {
|
||||
KeyboardAction = 2,
|
||||
/// https://vt100.net/docs/vt510-rm/IRM.html
|
||||
Insert = 4,
|
||||
/// <https://terminal-wg.pages.freedesktop.org/bidi/recommendation/escape-sequences.html>
|
||||
BiDirectionalSupportMode = 8,
|
||||
/// https://vt100.net/docs/vt510-rm/SRM.html
|
||||
/// But in the MS terminal this is cursor blinking.
|
||||
SendReceive = 12,
|
||||
@ -1576,6 +1603,7 @@ macro_rules! parse {
|
||||
impl<'a> CSIParser<'a> {
|
||||
fn parse_next(&mut self, params: &'a [CsiParam]) -> Result<CSI, ()> {
|
||||
match (self.control, self.orig_params) {
|
||||
('k', [.., CsiParam::P(b' ')]) => self.select_character_path(params),
|
||||
('q', [.., CsiParam::P(b' ')]) => self.cursor_style(params),
|
||||
('y', [.., CsiParam::P(b'*')]) => self.checksum_area(params),
|
||||
|
||||
@ -1704,6 +1732,32 @@ impl<'a> CSIParser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn select_character_path(&mut self, params: &'a [CsiParam]) -> Result<CSI, ()> {
|
||||
fn path(n: i64) -> Result<CharacterPath, ()> {
|
||||
Ok(match n {
|
||||
0 => CharacterPath::ImplementationDefault,
|
||||
1 => CharacterPath::LeftToRightOrTopToBottom,
|
||||
2 => CharacterPath::RightToLeftOrBottomToTop,
|
||||
_ => return Err(()),
|
||||
})
|
||||
}
|
||||
|
||||
match params {
|
||||
[CsiParam::P(b' ')] => Ok(self.advance_by(
|
||||
1,
|
||||
params,
|
||||
CSI::SelectCharacterPath(CharacterPath::ImplementationDefault, 0),
|
||||
)),
|
||||
[CsiParam::Integer(a), CsiParam::P(b' ')] => {
|
||||
Ok(self.advance_by(2, params, CSI::SelectCharacterPath(path(*a)?, 0)))
|
||||
}
|
||||
[CsiParam::Integer(a), CsiParam::P(b';'), CsiParam::Integer(b), CsiParam::P(b' ')] => {
|
||||
Ok(self.advance_by(4, params, CSI::SelectCharacterPath(path(*a)?, *b)))
|
||||
}
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn cursor_style(&mut self, params: &'a [CsiParam]) -> Result<CSI, ()> {
|
||||
match params {
|
||||
[CsiParam::Integer(p), CsiParam::P(b' ')] => match FromPrimitive::from_i64(*p) {
|
||||
@ -2711,6 +2765,22 @@ mod test {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bidi_modes() {
|
||||
assert_eq!(
|
||||
parse('h', &[8], "\x1b[8h"),
|
||||
vec![CSI::Mode(Mode::SetMode(TerminalMode::Code(
|
||||
TerminalModeCode::BiDirectionalSupportMode
|
||||
)))]
|
||||
);
|
||||
assert_eq!(
|
||||
parse('l', &[8], "\x1b[8l"),
|
||||
vec![CSI::Mode(Mode::ResetMode(TerminalMode::Code(
|
||||
TerminalModeCode::BiDirectionalSupportMode
|
||||
)))]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mouse() {
|
||||
let res: Vec<_> = CSI::parse(
|
||||
|
@ -531,7 +531,7 @@ mod test {
|
||||
use crate::cell::{Intensity, Underline};
|
||||
use crate::color::ColorSpec;
|
||||
use crate::escape::csi::{
|
||||
DecPrivateMode, DecPrivateModeCode, Device, Mode, Sgr, Window, XtSmGraphics,
|
||||
CharacterPath, DecPrivateMode, DecPrivateModeCode, Device, Mode, Sgr, Window, XtSmGraphics,
|
||||
XtSmGraphicsItem, XtermKeyModifierResource,
|
||||
};
|
||||
use crate::escape::{EscCode, OneBased};
|
||||
@ -871,6 +871,24 @@ mod test {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bidi_modes() {
|
||||
assert_eq!(
|
||||
round_trip_parse("\x1b[1 k"),
|
||||
vec![Action::CSI(CSI::SelectCharacterPath(
|
||||
CharacterPath::LeftToRightOrTopToBottom,
|
||||
0
|
||||
))]
|
||||
);
|
||||
assert_eq!(
|
||||
round_trip_parse("\x1b[2;1 k"),
|
||||
vec![Action::CSI(CSI::SelectCharacterPath(
|
||||
CharacterPath::RightToLeftOrBottomToTop,
|
||||
1
|
||||
))]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn xterm_key() {
|
||||
assert_eq!(
|
||||
|
Loading…
Reference in New Issue
Block a user