1
1
mirror of https://github.com/wez/wezterm.git synced 2024-09-21 03:39:16 +03:00

parse tmux control mode events

when in tmux mode, bypass vtparse
This commit is contained in:
g4c 2021-08-23 19:59:46 +08:00 committed by Wez Furlong
parent 6a167252b6
commit f36d4c6734
3 changed files with 42 additions and 7 deletions

View File

@ -32,6 +32,7 @@ serde = {version="1.0", features = ["rc", "derive"], optional=true}
sha2 = "0.9"
terminfo = "0.7"
thiserror = "1.0"
tmux-cc = {version = "0.1", path = "../tmux-cc"}
unicode-segmentation = "1.8"
ucd-trie = "0.1"
vtparse = { version="0.6", path="../vtparse" }

View File

@ -8,6 +8,7 @@
//! only; it does not provide terminal emulation facilities itself.
use num_derive::*;
use std::fmt::{Display, Error as FmtError, Formatter, Write as FmtWrite};
use tmux_cc::Event;
pub mod apc;
pub mod csi;
@ -178,6 +179,8 @@ pub enum DeviceControlMode {
Data(u8),
/// A self contained (Enter, Data*, Exit) sequence
ShortDeviceControl(Box<ShortDeviceControl>),
/// Tmux parsed events
TmuxEvents(Box<Vec<Event>>),
}
impl Display for DeviceControlMode {
@ -201,6 +204,7 @@ impl Display for DeviceControlMode {
Self::Exit => Ok(()),
Self::Data(c) => f.write_char(*c as char),
Self::ShortDeviceControl(s) => s.fmt(f),
Self::TmuxEvents(_) => write!(f, "tmux event"),
}
}
}
@ -212,6 +216,7 @@ impl std::fmt::Debug for DeviceControlMode {
Self::Exit => write!(fmt, "Exit"),
Self::Data(b) => write!(fmt, "Data({:?} 0x{:x})", *b as char, *b),
Self::ShortDeviceControl(s) => write!(fmt, "ShortDeviceControl({:?})", s),
Self::TmuxEvents(_) => write!(fmt, "tmux event"),
}
}
}

View File

@ -7,7 +7,9 @@ use crate::escape::{
use log::error;
use num_traits::FromPrimitive;
use regex::bytes::Regex;
use std::cell::RefCell;
use std::borrow::{Borrow, BorrowMut};
use std::cell::{Ref, RefCell};
use tmux_cc;
use vtparse::{CsiParam, VTActor, VTParser};
struct SixelBuilder {
@ -53,6 +55,7 @@ struct ParseState {
sixel: Option<SixelBuilder>,
dcs: Option<ShortDeviceControl>,
get_tcap: Option<GetTcapBuilder>,
tmux_state: Option<RefCell<tmux_cc::Parser>>,
}
/// The `Parser` struct holds the state machine that is used to decode
@ -81,11 +84,23 @@ impl Parser {
}
pub fn parse<F: FnMut(Action)>(&mut self, bytes: &[u8], mut callback: F) {
let mut perform = Performer {
callback: &mut callback,
state: &mut self.state.borrow_mut(),
};
self.state_machine.parse(bytes, &mut perform);
let tmux_state: bool = self.state.borrow().tmux_state.is_some();
if tmux_state {
let parser_state = self.state.borrow();
let tmux_state = parser_state.tmux_state.as_ref().unwrap();
let mut tmux_parser = tmux_state.borrow_mut();
let tmux_events = tmux_parser.advance_bytes(bytes);
log::info!("parsed tmux events: {:?}", &tmux_events);
callback(Action::DeviceControl(DeviceControlMode::TmuxEvents(
Box::new(tmux_events),
)));
} else {
let mut perform = Performer {
callback: &mut callback,
state: &mut self.state.borrow_mut(),
};
self.state_machine.parse(bytes, &mut perform);
}
}
/// A specialized version of the parser that halts after recognizing the
@ -215,6 +230,10 @@ impl<'a, F: FnMut(Action)> VTActor for Performer<'a, F> {
data: vec![],
});
} else {
if byte == b'p' && params == [1000] {
// into tmux_cc mode
self.state.borrow_mut().tmux_state = Some(RefCell::new(tmux_cc::Parser::new()));
}
(self.callback)(Action::DeviceControl(DeviceControlMode::Enter(Box::new(
EnterDeviceControlMode {
byte,
@ -234,7 +253,17 @@ impl<'a, F: FnMut(Action)> VTActor for Performer<'a, F> {
} else if let Some(tcap) = self.state.get_tcap.as_mut() {
tcap.push(data);
} else {
(self.callback)(Action::DeviceControl(DeviceControlMode::Data(data)));
if let Some(tmux_state) = &self.state.tmux_state {
let mut tmux_parser = tmux_state.borrow_mut();
if let Some(tmux_event) = tmux_parser.advance_byte(data) {
log::info!("parsed tmux event:{:?}", &tmux_event);
(self.callback)(Action::DeviceControl(DeviceControlMode::TmuxEvents(
Box::new(vec![tmux_event]),
)));
}
} else {
(self.callback)(Action::DeviceControl(DeviceControlMode::Data(data)));
}
}
}