mirror of
https://github.com/wez/wezterm.git
synced 2024-11-23 23:21:08 +03:00
term: remove TerminalHost from api
This simplifies a bunch of things
This commit is contained in:
parent
d361b8a7c5
commit
cb3606d130
@ -12,7 +12,7 @@ use std::ops::Range;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use term::color::ColorPalette;
|
||||
use term::{Clipboard, KeyCode, KeyModifiers, Line, MouseEvent, StableRowIndex, TerminalHost};
|
||||
use term::{Clipboard, KeyCode, KeyModifiers, Line, MouseEvent, StableRowIndex};
|
||||
use termwiz::cell::{Cell, CellAttributes};
|
||||
use termwiz::color::AnsiColor;
|
||||
use url::Url;
|
||||
@ -179,12 +179,12 @@ impl Tab for SearchOverlay {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mouse_event(&self, event: MouseEvent, host: &mut dyn TerminalHost) -> anyhow::Result<()> {
|
||||
self.delegate.mouse_event(event, host)
|
||||
fn mouse_event(&self, event: MouseEvent) -> anyhow::Result<()> {
|
||||
self.delegate.mouse_event(event)
|
||||
}
|
||||
|
||||
fn advance_bytes(&self, buf: &[u8], host: &mut dyn TerminalHost) {
|
||||
self.delegate.advance_bytes(buf, host)
|
||||
fn advance_bytes(&self, buf: &[u8]) {
|
||||
self.delegate.advance_bytes(buf)
|
||||
}
|
||||
fn is_dead(&self) -> bool {
|
||||
self.delegate.is_dead()
|
||||
|
@ -178,16 +178,6 @@ pub struct TermWindow {
|
||||
shape_cache: RefCell<LruCache<ShapeCacheKey, anyhow::Result<Vec<GlyphInfo>>>>,
|
||||
}
|
||||
|
||||
struct Host<'a> {
|
||||
writer: &'a mut dyn std::io::Write,
|
||||
}
|
||||
|
||||
impl<'a> term::TerminalHost for Host<'a> {
|
||||
fn writer(&mut self) -> &mut dyn std::io::Write {
|
||||
self.writer
|
||||
}
|
||||
}
|
||||
|
||||
fn mouse_press_to_tmb(press: &MousePress) -> TMB {
|
||||
match press {
|
||||
MousePress::Left => TMB::Left,
|
||||
@ -3017,13 +3007,7 @@ impl TermWindow {
|
||||
modifiers: window_mods_to_termwiz_mods(event.modifiers),
|
||||
};
|
||||
|
||||
tab.mouse_event(
|
||||
mouse_event,
|
||||
&mut Host {
|
||||
writer: &mut *tab.writer(),
|
||||
},
|
||||
)
|
||||
.ok();
|
||||
tab.mouse_event(mouse_event).ok();
|
||||
|
||||
match event.kind {
|
||||
WMEK::Move => {}
|
||||
|
@ -7,7 +7,7 @@ use portable_pty::{Child, MasterPty, PtySize};
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::sync::Arc;
|
||||
use term::color::ColorPalette;
|
||||
use term::{Clipboard, KeyCode, KeyModifiers, MouseEvent, StableRowIndex, Terminal, TerminalHost};
|
||||
use term::{Clipboard, KeyCode, KeyModifiers, MouseEvent, StableRowIndex, Terminal};
|
||||
use url::Url;
|
||||
|
||||
pub struct LocalTab {
|
||||
@ -41,18 +41,16 @@ impl Tab for LocalTab {
|
||||
self.terminal.borrow_mut().set_clipboard(clipboard);
|
||||
}
|
||||
|
||||
fn advance_bytes(&self, buf: &[u8], host: &mut dyn TerminalHost) {
|
||||
self.terminal.borrow_mut().advance_bytes(buf, host)
|
||||
fn advance_bytes(&self, buf: &[u8]) {
|
||||
self.terminal.borrow_mut().advance_bytes(buf)
|
||||
}
|
||||
|
||||
fn mouse_event(&self, event: MouseEvent, host: &mut dyn TerminalHost) -> Result<(), Error> {
|
||||
self.terminal.borrow_mut().mouse_event(event, host)
|
||||
fn mouse_event(&self, event: MouseEvent) -> Result<(), Error> {
|
||||
self.terminal.borrow_mut().mouse_event(event)
|
||||
}
|
||||
|
||||
fn key_down(&self, key: KeyCode, mods: KeyModifiers) -> Result<(), Error> {
|
||||
self.terminal
|
||||
.borrow_mut()
|
||||
.key_down(key, mods, &mut *self.pty.borrow_mut())
|
||||
self.terminal.borrow_mut().key_down(key, mods)
|
||||
}
|
||||
|
||||
fn resize(&self, size: PtySize) -> Result<(), Error> {
|
||||
@ -75,9 +73,7 @@ impl Tab for LocalTab {
|
||||
}
|
||||
|
||||
fn send_paste(&self, text: &str) -> Result<(), Error> {
|
||||
self.terminal
|
||||
.borrow_mut()
|
||||
.send_paste(text, &mut *self.pty.borrow_mut())
|
||||
self.terminal.borrow_mut().send_paste(text)
|
||||
}
|
||||
|
||||
fn get_title(&self) -> String {
|
||||
|
@ -124,6 +124,8 @@ impl Domain for LocalDomain {
|
||||
let child = pair.slave.spawn_command(cmd)?;
|
||||
info!("spawned: {:?}", child);
|
||||
|
||||
let writer = pair.master.try_clone_writer()?;
|
||||
|
||||
let terminal = term::Terminal::new(
|
||||
size.rows as usize,
|
||||
size.cols as usize,
|
||||
@ -132,6 +134,7 @@ impl Domain for LocalDomain {
|
||||
std::sync::Arc::new(crate::config::TermConfig {}),
|
||||
"WezTerm",
|
||||
crate::wezterm_version(),
|
||||
Box::new(writer),
|
||||
);
|
||||
|
||||
let mux = Mux::get().unwrap();
|
||||
|
@ -13,7 +13,6 @@ use std::rc::Rc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use term::TerminalHost;
|
||||
use thiserror::*;
|
||||
|
||||
pub mod domain;
|
||||
@ -68,12 +67,7 @@ fn read_from_tab_pty(tab_id: TabId, mut reader: Box<dyn std::io::Read>) {
|
||||
promise::spawn::spawn_into_main_thread_with_low_priority(async move {
|
||||
let mux = Mux::get().unwrap();
|
||||
if let Some(tab) = mux.get_tab(tab_id) {
|
||||
tab.advance_bytes(
|
||||
&data,
|
||||
&mut Host {
|
||||
writer: &mut *tab.writer(),
|
||||
},
|
||||
);
|
||||
tab.advance_bytes(&data);
|
||||
mux.notify(MuxNotification::TabOutput(tab_id));
|
||||
}
|
||||
});
|
||||
@ -93,20 +87,6 @@ fn read_from_tab_pty(tab_id: TabId, mut reader: Box<dyn std::io::Read>) {
|
||||
});
|
||||
}
|
||||
|
||||
/// This is just a stub impl of TerminalHost; it really only exists
|
||||
/// in order to parse data sent by the peer (so, just to parse output).
|
||||
/// As such it only really has Host::writer get called.
|
||||
/// The GUI driven flows provide their own impl of TerminalHost.
|
||||
struct Host<'a> {
|
||||
writer: &'a mut dyn std::io::Write,
|
||||
}
|
||||
|
||||
impl<'a> TerminalHost for Host<'a> {
|
||||
fn writer(&mut self) -> &mut dyn std::io::Write {
|
||||
&mut self.writer
|
||||
}
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static MUX: RefCell<Option<Rc<Mux>>> = RefCell::new(None);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
|
||||
use std::cell::RefMut;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use term::color::ColorPalette;
|
||||
use term::{Clipboard, KeyCode, KeyModifiers, MouseEvent, StableRowIndex, TerminalHost};
|
||||
use term::{Clipboard, KeyCode, KeyModifiers, MouseEvent, StableRowIndex};
|
||||
use url::Url;
|
||||
|
||||
static TAB_ID: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::AtomicUsize::new(0);
|
||||
@ -92,8 +92,8 @@ pub trait Tab: Downcast {
|
||||
fn writer(&self) -> RefMut<dyn std::io::Write>;
|
||||
fn resize(&self, size: PtySize) -> anyhow::Result<()>;
|
||||
fn key_down(&self, key: KeyCode, mods: KeyModifiers) -> anyhow::Result<()>;
|
||||
fn mouse_event(&self, event: MouseEvent, host: &mut dyn TerminalHost) -> anyhow::Result<()>;
|
||||
fn advance_bytes(&self, buf: &[u8], host: &mut dyn TerminalHost);
|
||||
fn mouse_event(&self, event: MouseEvent) -> anyhow::Result<()>;
|
||||
fn advance_bytes(&self, buf: &[u8]);
|
||||
fn is_dead(&self) -> bool;
|
||||
fn palette(&self) -> ColorPalette;
|
||||
fn domain_id(&self) -> DomainId;
|
||||
|
@ -134,16 +134,6 @@ fn maybe_push_tab_changes(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct BufferedTerminalHost<'a> {
|
||||
write: std::cell::RefMut<'a, dyn std::io::Write>,
|
||||
}
|
||||
|
||||
impl<'a> term::TerminalHost for BufferedTerminalHost<'a> {
|
||||
fn writer(&mut self) -> &mut dyn std::io::Write {
|
||||
&mut *self.write
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SessionHandler {
|
||||
to_write_tx: PollableSender<DecodedPdu>,
|
||||
per_tab: HashMap<TabId, Arc<Mutex<PerTab>>>,
|
||||
@ -331,10 +321,7 @@ impl SessionHandler {
|
||||
let tab = mux
|
||||
.get_tab(tab_id)
|
||||
.ok_or_else(|| anyhow!("no such tab {}", tab_id))?;
|
||||
let mut host = BufferedTerminalHost {
|
||||
write: tab.writer(),
|
||||
};
|
||||
tab.mouse_event(event, &mut host)?;
|
||||
tab.mouse_event(event)?;
|
||||
maybe_push_tab_changes(&tab, sender, per_tab)?;
|
||||
Ok(Pdu::UnitResponse(UnitResponse {}))
|
||||
},
|
||||
|
@ -16,7 +16,7 @@ use std::cell::RefMut;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use term::color::ColorPalette;
|
||||
use term::{Clipboard, KeyCode, KeyModifiers, MouseEvent, TerminalHost};
|
||||
use term::{Clipboard, KeyCode, KeyModifiers, MouseEvent};
|
||||
use termwiz::input::KeyEvent;
|
||||
use url::Url;
|
||||
|
||||
@ -231,7 +231,7 @@ impl Tab for ClientTab {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mouse_event(&self, event: MouseEvent, _host: &mut dyn TerminalHost) -> anyhow::Result<()> {
|
||||
fn mouse_event(&self, event: MouseEvent) -> anyhow::Result<()> {
|
||||
self.mouse.borrow_mut().append(event);
|
||||
if MouseState::next(Rc::clone(&self.mouse)) {
|
||||
self.renderable
|
||||
@ -243,7 +243,7 @@ impl Tab for ClientTab {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn advance_bytes(&self, _buf: &[u8], _host: &mut dyn TerminalHost) {
|
||||
fn advance_bytes(&self, _buf: &[u8]) {
|
||||
panic!("ClientTab::advance_bytes not impl");
|
||||
}
|
||||
|
||||
|
@ -255,6 +255,8 @@ impl Domain for RemoteSshDomain {
|
||||
let child = pair.slave.spawn_command(cmd)?;
|
||||
log::info!("spawned: {:?}", child);
|
||||
|
||||
let writer = pair.master.try_clone_writer()?;
|
||||
|
||||
let terminal = term::Terminal::new(
|
||||
size.rows as usize,
|
||||
size.cols as usize,
|
||||
@ -263,6 +265,7 @@ impl Domain for RemoteSshDomain {
|
||||
std::sync::Arc::new(crate::config::TermConfig {}),
|
||||
"WezTerm",
|
||||
crate::wezterm_version(),
|
||||
Box::new(writer),
|
||||
);
|
||||
|
||||
let mux = Mux::get().unwrap();
|
||||
|
@ -26,7 +26,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use term::color::ColorPalette;
|
||||
use term::{KeyCode, KeyModifiers, Line, MouseEvent, StableRowIndex, TerminalHost};
|
||||
use term::{KeyCode, KeyModifiers, Line, MouseEvent, StableRowIndex};
|
||||
use termwiz::input::{InputEvent, KeyEvent, MouseEvent as TermWizMouseEvent};
|
||||
use termwiz::lineedit::*;
|
||||
use termwiz::surface::{Change, SequenceNo, Surface};
|
||||
@ -299,7 +299,7 @@ impl Tab for TermWizTerminalTab {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mouse_event(&self, event: MouseEvent, _host: &mut dyn TerminalHost) -> anyhow::Result<()> {
|
||||
fn mouse_event(&self, event: MouseEvent) -> anyhow::Result<()> {
|
||||
use term::input::MouseButton;
|
||||
use termwiz::input::MouseButtons as Buttons;
|
||||
|
||||
@ -327,7 +327,7 @@ impl Tab for TermWizTerminalTab {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn advance_bytes(&self, _buf: &[u8], _host: &mut dyn TerminalHost) {
|
||||
fn advance_bytes(&self, _buf: &[u8]) {
|
||||
panic!("advance_bytes is undefined for TermWizTerminalTab");
|
||||
}
|
||||
|
||||
|
@ -17,14 +17,6 @@ impl Clipboard for Box<dyn Clipboard> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the host of the terminal.
|
||||
/// Provides a means for sending data to the connected pty
|
||||
pub trait TerminalHost {
|
||||
/// Returns an object that can be used to send data to the
|
||||
/// slave end of the associated pty.
|
||||
fn writer(&mut self) -> &mut dyn std::io::Write;
|
||||
}
|
||||
|
||||
pub struct Terminal {
|
||||
/// The terminal model/state
|
||||
state: TerminalState,
|
||||
@ -55,6 +47,8 @@ impl Terminal {
|
||||
config: Arc<dyn TerminalConfiguration>,
|
||||
term_program: &str,
|
||||
term_version: &str,
|
||||
// writing to the writer sends data to input of the pty
|
||||
writer: Box<dyn std::io::Write>,
|
||||
) -> Terminal {
|
||||
Terminal {
|
||||
state: TerminalState::new(
|
||||
@ -65,16 +59,17 @@ impl Terminal {
|
||||
config,
|
||||
term_program,
|
||||
term_version,
|
||||
writer,
|
||||
),
|
||||
parser: Parser::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Feed the terminal parser a slice of bytes of input.
|
||||
pub fn advance_bytes<B: AsRef<[u8]>>(&mut self, bytes: B, host: &mut dyn TerminalHost) {
|
||||
pub fn advance_bytes<B: AsRef<[u8]>>(&mut self, bytes: B) {
|
||||
let bytes = bytes.as_ref();
|
||||
|
||||
let mut performer = Performer::new(&mut self.state, host);
|
||||
let mut performer = Performer::new(&mut self.state);
|
||||
|
||||
self.parser.parse(bytes, |action| performer.perform(action));
|
||||
}
|
||||
|
@ -232,6 +232,8 @@ pub struct TerminalState {
|
||||
|
||||
term_program: String,
|
||||
term_version: String,
|
||||
|
||||
writer: Box<dyn std::io::Write>,
|
||||
}
|
||||
|
||||
fn encode_modifiers(mods: KeyModifiers) -> u8 {
|
||||
@ -284,6 +286,7 @@ impl TerminalState {
|
||||
config: Arc<dyn TerminalConfiguration>,
|
||||
term_program: &str,
|
||||
term_version: &str,
|
||||
writer: Box<dyn std::io::Write>,
|
||||
) -> TerminalState {
|
||||
let screen = ScreenOrAlt::new(physical_rows, physical_cols, &config);
|
||||
|
||||
@ -316,6 +319,7 @@ impl TerminalState {
|
||||
current_dir: None,
|
||||
term_program: term_program.to_string(),
|
||||
term_version: term_version.to_string(),
|
||||
writer,
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,11 +374,7 @@ impl TerminalState {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mouse_wheel(
|
||||
&mut self,
|
||||
event: MouseEvent,
|
||||
writer: &mut dyn std::io::Write,
|
||||
) -> Result<(), Error> {
|
||||
fn mouse_wheel(&mut self, event: MouseEvent) -> Result<(), Error> {
|
||||
let (report_button, key) = match event.button {
|
||||
MouseButton::WheelUp(_) => (64, KeyCode::UpArrow),
|
||||
MouseButton::WheelDown(_) => (65, KeyCode::DownArrow),
|
||||
@ -382,21 +382,17 @@ impl TerminalState {
|
||||
};
|
||||
|
||||
if self.sgr_mouse {
|
||||
writer.write_all(
|
||||
self.writer.write_all(
|
||||
format!("\x1b[<{};{};{}M", report_button, event.x + 1, event.y + 1).as_bytes(),
|
||||
)?;
|
||||
} else if self.screen.is_alt_screen_active() {
|
||||
// Send cursor keys instead (equivalent to xterm's alternateScroll mode)
|
||||
self.key_down(key, KeyModifiers::default(), writer)?;
|
||||
self.key_down(key, KeyModifiers::default())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mouse_button_press(
|
||||
&mut self,
|
||||
event: MouseEvent,
|
||||
host: &mut dyn TerminalHost,
|
||||
) -> Result<(), Error> {
|
||||
fn mouse_button_press(&mut self, event: MouseEvent) -> Result<(), Error> {
|
||||
self.current_mouse_button = event.button;
|
||||
if let Some(button) = match event.button {
|
||||
MouseButton::Left => Some(0),
|
||||
@ -405,7 +401,7 @@ impl TerminalState {
|
||||
_ => None,
|
||||
} {
|
||||
if self.sgr_mouse {
|
||||
host.writer().write_all(
|
||||
self.writer.write_all(
|
||||
format!("\x1b[<{};{};{}M", button, event.x + 1, event.y + 1).as_bytes(),
|
||||
)?;
|
||||
}
|
||||
@ -414,26 +410,18 @@ impl TerminalState {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mouse_button_release(
|
||||
&mut self,
|
||||
event: MouseEvent,
|
||||
writer: &mut dyn std::io::Write,
|
||||
) -> Result<(), Error> {
|
||||
fn mouse_button_release(&mut self, event: MouseEvent) -> Result<(), Error> {
|
||||
if self.current_mouse_button != MouseButton::None {
|
||||
self.current_mouse_button = MouseButton::None;
|
||||
if self.sgr_mouse {
|
||||
write!(writer, "\x1b[<3;{};{}m", event.x + 1, event.y + 1)?;
|
||||
write!(self.writer, "\x1b[<3;{};{}m", event.x + 1, event.y + 1)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mouse_move(
|
||||
&mut self,
|
||||
event: MouseEvent,
|
||||
writer: &mut dyn std::io::Write,
|
||||
) -> Result<(), Error> {
|
||||
fn mouse_move(&mut self, event: MouseEvent) -> Result<(), Error> {
|
||||
if let Some(button) = match (self.current_mouse_button, self.button_event_mouse) {
|
||||
(MouseButton::Left, true) => Some(32),
|
||||
(MouseButton::Middle, true) => Some(33),
|
||||
@ -441,17 +429,19 @@ impl TerminalState {
|
||||
(..) => None,
|
||||
} {
|
||||
if self.sgr_mouse {
|
||||
write!(writer, "\x1b[<{};{};{}M", button, event.x + 1, event.y + 1)?;
|
||||
write!(
|
||||
self.writer,
|
||||
"\x1b[<{};{};{}M",
|
||||
button,
|
||||
event.x + 1,
|
||||
event.y + 1
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn mouse_event(
|
||||
&mut self,
|
||||
mut event: MouseEvent,
|
||||
host: &mut dyn TerminalHost,
|
||||
) -> Result<(), Error> {
|
||||
pub fn mouse_event(&mut self, mut event: MouseEvent) -> Result<(), Error> {
|
||||
// Clamp the mouse coordinates to the size of the model.
|
||||
// This situation can trigger for example when the
|
||||
// window is resized and leaves a partial row at the bottom of the
|
||||
@ -471,19 +461,19 @@ impl TerminalState {
|
||||
kind: MouseEventKind::Press,
|
||||
button: MouseButton::WheelDown(_),
|
||||
..
|
||||
} => self.mouse_wheel(event, host.writer()),
|
||||
} => self.mouse_wheel(event),
|
||||
MouseEvent {
|
||||
kind: MouseEventKind::Press,
|
||||
..
|
||||
} => self.mouse_button_press(event, host),
|
||||
} => self.mouse_button_press(event),
|
||||
MouseEvent {
|
||||
kind: MouseEventKind::Release,
|
||||
..
|
||||
} => self.mouse_button_release(event, host.writer()),
|
||||
} => self.mouse_button_release(event),
|
||||
MouseEvent {
|
||||
kind: MouseEventKind::Move,
|
||||
..
|
||||
} => self.mouse_move(event, host.writer()),
|
||||
} => self.mouse_move(event),
|
||||
}
|
||||
}
|
||||
|
||||
@ -502,12 +492,12 @@ impl TerminalState {
|
||||
/// Send text to the terminal that is the result of pasting.
|
||||
/// If bracketed paste mode is enabled, the paste is enclosed
|
||||
/// in the bracketing, otherwise it is fed to the pty as-is.
|
||||
pub fn send_paste(&mut self, text: &str, writer: &mut dyn std::io::Write) -> Result<(), Error> {
|
||||
pub fn send_paste(&mut self, text: &str) -> Result<(), Error> {
|
||||
if self.bracketed_paste {
|
||||
let buf = format!("\x1b[200~{}\x1b[201~", text);
|
||||
writer.write_all(buf.as_bytes())?;
|
||||
self.writer.write_all(buf.as_bytes())?;
|
||||
} else {
|
||||
writer.write_all(text.as_bytes())?;
|
||||
self.writer.write_all(text.as_bytes())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -517,12 +507,7 @@ impl TerminalState {
|
||||
/// keycode into a sequence of bytes to send to the slave end
|
||||
/// of the pty via the `Write`-able object provided by the caller.
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
pub fn key_down(
|
||||
&mut self,
|
||||
key: KeyCode,
|
||||
mods: KeyModifiers,
|
||||
writer: &mut dyn std::io::Write,
|
||||
) -> Result<(), Error> {
|
||||
pub fn key_down(&mut self, key: KeyCode, mods: KeyModifiers) -> Result<(), Error> {
|
||||
use crate::KeyCode::*;
|
||||
|
||||
let key = key.normalize_shift_to_upper_case(mods);
|
||||
@ -744,7 +729,7 @@ impl TerminalState {
|
||||
};
|
||||
|
||||
// debug!("sending {:?}, {:?}", to_send, key);
|
||||
writer.write_all(to_send.as_bytes())?;
|
||||
self.writer.write_all(to_send.as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1040,7 +1025,7 @@ impl TerminalState {
|
||||
*/
|
||||
}
|
||||
|
||||
fn perform_device(&mut self, dev: Device, host: &mut dyn TerminalHost) {
|
||||
fn perform_device(&mut self, dev: Device) {
|
||||
match dev {
|
||||
Device::DeviceAttributes(a) => error!("unhandled: {:?}", a),
|
||||
Device::SoftReset => {
|
||||
@ -1048,20 +1033,20 @@ impl TerminalState {
|
||||
// TODO: see https://vt100.net/docs/vt510-rm/DECSTR.html
|
||||
}
|
||||
Device::RequestPrimaryDeviceAttributes => {
|
||||
host.writer().write(DEVICE_IDENT).ok();
|
||||
self.writer.write(DEVICE_IDENT).ok();
|
||||
}
|
||||
Device::RequestSecondaryDeviceAttributes => {
|
||||
host.writer().write(b"\x1b[>0;0;0c").ok();
|
||||
self.writer.write(b"\x1b[>0;0;0c").ok();
|
||||
}
|
||||
Device::RequestTerminalNameAndVersion => {
|
||||
host.writer().write(DCS).ok();
|
||||
host.writer()
|
||||
self.writer.write(DCS).ok();
|
||||
self.writer
|
||||
.write(format!(">|{} {}", self.term_program, self.term_version).as_bytes())
|
||||
.ok();
|
||||
host.writer().write(ST).ok();
|
||||
self.writer.write(ST).ok();
|
||||
}
|
||||
Device::StatusReport => {
|
||||
host.writer().write(b"\x1b[0n").ok();
|
||||
self.writer.write(b"\x1b[0n").ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1280,7 +1265,7 @@ impl TerminalState {
|
||||
checksum
|
||||
}
|
||||
|
||||
fn perform_csi_window(&mut self, window: Window, host: &mut dyn TerminalHost) {
|
||||
fn perform_csi_window(&mut self, window: Window) {
|
||||
match window {
|
||||
Window::ReportTextAreaSizeCells => {
|
||||
let screen = self.screen();
|
||||
@ -1288,7 +1273,7 @@ impl TerminalState {
|
||||
let width = Some(screen.physical_cols as i64);
|
||||
|
||||
let response = Window::ResizeWindowCells { width, height };
|
||||
write!(host.writer(), "{}", CSI::Window(response)).ok();
|
||||
write!(self.writer, "{}", CSI::Window(response)).ok();
|
||||
}
|
||||
Window::ChecksumRectangularArea {
|
||||
request_id,
|
||||
@ -1304,7 +1289,7 @@ impl TerminalState {
|
||||
right.as_zero_based(),
|
||||
bottom.as_zero_based(),
|
||||
);
|
||||
write!(host.writer(), "\x1bP{}!~{:04x}\x1b\\", request_id, checksum).ok();
|
||||
write!(self.writer, "\x1bP{}!~{:04x}\x1b\\", request_id, checksum).ok();
|
||||
}
|
||||
Window::ResizeWindowCells { .. } => {
|
||||
// We don't allow the application to change the window size; that's
|
||||
@ -1432,7 +1417,7 @@ impl TerminalState {
|
||||
}
|
||||
}
|
||||
|
||||
fn perform_csi_cursor(&mut self, cursor: Cursor, host: &mut dyn TerminalHost) {
|
||||
fn perform_csi_cursor(&mut self, cursor: Cursor) {
|
||||
match cursor {
|
||||
Cursor::SetTopAndBottomMargins { top, bottom } => {
|
||||
let rows = self.screen().physical_rows;
|
||||
@ -1511,7 +1496,7 @@ impl TerminalState {
|
||||
let line = OneBased::from_zero_based(self.cursor.y as u32);
|
||||
let col = OneBased::from_zero_based(self.cursor.x as u32);
|
||||
let report = CSI::Cursor(Cursor::ActivePositionReport { line, col });
|
||||
write!(host.writer(), "{}", report).ok();
|
||||
write!(self.writer, "{}", report).ok();
|
||||
}
|
||||
Cursor::SaveCursor => self.save_cursor(),
|
||||
Cursor::RestoreCursor => self.restore_cursor(),
|
||||
@ -1606,7 +1591,6 @@ impl TerminalState {
|
||||
/// the terminal state and the embedding/host terminal interface
|
||||
pub(crate) struct Performer<'a> {
|
||||
pub state: &'a mut TerminalState,
|
||||
pub host: &'a mut dyn TerminalHost,
|
||||
print: Option<String>,
|
||||
}
|
||||
|
||||
@ -1631,12 +1615,8 @@ impl<'a> Drop for Performer<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Performer<'a> {
|
||||
pub fn new(state: &'a mut TerminalState, host: &'a mut dyn TerminalHost) -> Self {
|
||||
Self {
|
||||
state,
|
||||
host,
|
||||
print: None,
|
||||
}
|
||||
pub fn new(state: &'a mut TerminalState) -> Self {
|
||||
Self { state, print: None }
|
||||
}
|
||||
|
||||
fn flush_print(&mut self) {
|
||||
@ -1750,12 +1730,12 @@ impl<'a> Performer<'a> {
|
||||
self.flush_print();
|
||||
match csi {
|
||||
CSI::Sgr(sgr) => self.state.perform_csi_sgr(sgr),
|
||||
CSI::Cursor(cursor) => self.state.perform_csi_cursor(cursor, self.host),
|
||||
CSI::Cursor(cursor) => self.state.perform_csi_cursor(cursor),
|
||||
CSI::Edit(edit) => self.state.perform_csi_edit(edit),
|
||||
CSI::Mode(mode) => self.state.perform_csi_mode(mode),
|
||||
CSI::Device(dev) => self.state.perform_device(*dev, self.host),
|
||||
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, self.host),
|
||||
CSI::Window(window) => self.state.perform_csi_window(window),
|
||||
CSI::Unspecified(unspec) => {
|
||||
error!("unknown unspecified CSI: {:?}", format!("{}", unspec))
|
||||
}
|
||||
@ -1864,7 +1844,7 @@ impl<'a> Performer<'a> {
|
||||
self.palette().colors.0[pair.palette_index as usize],
|
||||
),
|
||||
}]);
|
||||
write!(self.host.writer(), "{}", response).ok();
|
||||
write!(self.writer, "{}", response).ok();
|
||||
}
|
||||
ColorOrQuery::Color(c) => {
|
||||
self.palette_mut().colors.0[pair.palette_index as usize] = c;
|
||||
@ -1909,7 +1889,7 @@ impl<'a> Performer<'a> {
|
||||
which_color,
|
||||
vec![ColorOrQuery::Color(self.palette().$name)],
|
||||
);
|
||||
write!(self.host.writer(), "{}", response).ok();
|
||||
write!(self.writer, "{}", response).ok();
|
||||
}
|
||||
ColorOrQuery::Color(c) => self.palette_mut().$name = c,
|
||||
}
|
||||
|
@ -15,23 +15,6 @@ use termwiz::escape::csi::{Edit, EraseInDisplay, EraseInLine};
|
||||
use termwiz::escape::{OneBased, OperatingSystemCommand, CSI};
|
||||
use termwiz::surface::CursorShape;
|
||||
|
||||
struct TestHost {}
|
||||
|
||||
impl TestHost {
|
||||
fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::io::Write for TestHost {
|
||||
fn write(&mut self, _buf: &[u8]) -> Result<usize, std::io::Error> {
|
||||
panic!("no writer support in TestHost");
|
||||
}
|
||||
fn flush(&mut self) -> Result<(), std::io::Error> {
|
||||
panic!("no writer support in TestHost");
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct LocalClip {
|
||||
clip: RefCell<Option<String>>,
|
||||
@ -60,15 +43,8 @@ impl Clipboard for LocalClip {
|
||||
}
|
||||
}
|
||||
|
||||
impl TerminalHost for TestHost {
|
||||
fn writer(&mut self) -> &mut dyn std::io::Write {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
struct TestTerm {
|
||||
term: Terminal,
|
||||
host: TestHost,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -95,14 +71,12 @@ impl TestTerm {
|
||||
Arc::new(TestTermConfig { scrollback }),
|
||||
"WezTerm",
|
||||
"O_o",
|
||||
Box::new(Vec::new()),
|
||||
);
|
||||
let clip: Arc<dyn Clipboard> = Arc::new(LocalClip::new());
|
||||
term.set_clipboard(&clip);
|
||||
|
||||
let mut term = Self {
|
||||
term,
|
||||
host: TestHost::new(),
|
||||
};
|
||||
let mut term = Self { term };
|
||||
|
||||
term.set_auto_wrap(true);
|
||||
|
||||
@ -110,7 +84,7 @@ impl TestTerm {
|
||||
}
|
||||
|
||||
fn print<B: AsRef<[u8]>>(&mut self, bytes: B) {
|
||||
self.term.advance_bytes(bytes, &mut self.host);
|
||||
self.term.advance_bytes(bytes);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
Loading…
Reference in New Issue
Block a user