1
1
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:
Wez Furlong 2020-05-30 07:44:53 -07:00
parent d361b8a7c5
commit cb3606d130
13 changed files with 86 additions and 184 deletions

View File

@ -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()

View File

@ -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 => {}

View File

@ -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 {

View File

@ -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();

View File

@ -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);
}

View File

@ -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;

View File

@ -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 {}))
},

View File

@ -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");
}

View File

@ -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();

View File

@ -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");
}

View File

@ -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));
}

View File

@ -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,
}

View File

@ -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)]