1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-23 15:04:36 +03:00

implement coarse tab data rpc PoC

This required switching away from Rc to Arc so that the data in the
client can transit between threads.

This isn't useful yet.
This commit is contained in:
Wez Furlong 2019-03-14 08:25:26 -07:00
parent 7cdd1876d1
commit fe7502fc0b
16 changed files with 87 additions and 36 deletions

View File

@ -3,7 +3,7 @@ use crate::mux::tab::Tab;
use clipboard::{ClipboardContext, ClipboardProvider};
use failure::Error;
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
use std::sync::Arc;
use term::{KeyCode, KeyModifiers};
use termwiz::hyperlink::Hyperlink;
@ -188,7 +188,7 @@ impl<'a, H: HostHelper> term::TerminalHost for TabHost<'a, H> {
&mut self.writer
}
fn click_link(&mut self, link: &Rc<Hyperlink>) {
fn click_link(&mut self, link: &Arc<Hyperlink>) {
match open::that(link.uri()) {
Ok(_) => {}
Err(err) => eprintln!("failed to open {}: {:?}", link.uri(), err),

View File

@ -153,9 +153,17 @@ fn main() -> Result<(), Error> {
}
SubCommand::Cli(_) => {
use crate::server::client::Client;
use crate::server::codec::*;
let mut client = Client::new(&config)?;
eprintln!("ping: {:?}", client.ping()?);
eprintln!("tabs: {:?}", client.list_tabs()?);
let tabs = client.list_tabs()?;
for (tab_id, title) in tabs.tabs.iter() {
eprintln!("tab {}: {}", tab_id, title);
let data = client.get_coarse_tab_renderable_data(GetCoarseTabRenderableData {
tab_id: *tab_id,
})?;
eprintln!("coarse: {:?}", data);
}
Ok(())
}
}

View File

@ -74,7 +74,7 @@ impl<'a> TerminalHost for Host<'a> {
&mut self.writer
}
fn click_link(&mut self, link: &Rc<Hyperlink>) {
fn click_link(&mut self, link: &Arc<Hyperlink>) {
match open::that(link.uri()) {
Ok(_) => {}
Err(err) => eprintln!("failed to open {}: {:?}", link.uri(), err),

View File

@ -1,5 +1,5 @@
use std::ops::Range;
use std::rc::Rc;
use std::sync::Arc;
use term::{CursorPosition, Line, Terminal, TerminalState};
use termwiz::hyperlink::Hyperlink;
@ -26,7 +26,7 @@ pub trait Renderable {
fn clean_dirty_lines(&mut self);
/// Returns the currently highlighted hyperlink
fn current_highlight(&self) -> Option<Rc<Hyperlink>>;
fn current_highlight(&self) -> Option<Arc<Hyperlink>>;
/// Returns physical, non-scrollback (rows, cols) for the
/// terminal screen
@ -50,7 +50,7 @@ impl Renderable for Terminal {
TerminalState::make_all_lines_dirty(self)
}
fn current_highlight(&self) -> Option<Rc<Hyperlink>> {
fn current_highlight(&self) -> Option<Arc<Hyperlink>> {
TerminalState::current_highlight(self)
}

View File

@ -64,4 +64,9 @@ impl Client {
rpc!(ping, Ping = (), Pong);
rpc!(list_tabs, ListTabs = (), ListTabsResponse);
rpc!(
get_coarse_tab_renderable_data,
GetCoarseTabRenderableData,
GetCoarseTabRenderableDataResponse
);
}

View File

@ -15,7 +15,7 @@ use bincode;
use failure::Error;
use serde_derive::*;
use std::collections::HashMap;
use std::rc::Rc;
use std::sync::Arc;
use term::{CursorPosition, Line};
use termwiz::hyperlink::Hyperlink;
use varu64;
@ -137,6 +137,8 @@ pdu! {
Pong: 2,
ListTabs: 3,
ListTabsResponse: 4,
GetCoarseTabRenderableData: 5,
GetCoarseTabRenderableDataResponse: 6,
}
#[derive(Deserialize, Serialize, PartialEq, Debug)]
@ -174,7 +176,7 @@ pub struct GetCoarseTabRenderableDataResponse {
pub cursor_position: CursorPosition,
pub physical_rows: usize,
pub physical_cols: usize,
pub current_highlight: Option<Rc<Hyperlink>>,
pub current_highlight: Option<Arc<Hyperlink>>,
pub dirty_lines: Vec<DirtyLine>,
}

View File

@ -71,8 +71,43 @@ impl ClientSession {
.wait()?;
Pdu::ListTabsResponse(result).encode(&mut self.stream, decoded.serial)?;
}
Pdu::GetCoarseTabRenderableData(GetCoarseTabRenderableData { tab_id }) => {
let result = Future::with_executor(self.executor.clone_executor(), move || {
let mux = Mux::get().unwrap();
let tab = mux
.get_tab(tab_id)
.ok_or_else(|| format_err!("no such tab {}", tab_id))?;
let renderable = tab.renderer();
let dirty_lines = renderable
.get_dirty_lines()
.iter()
.map(|(line_idx, line, sel)| DirtyLine {
line_idx: *line_idx,
line: (*line).clone(),
selection_col_from: sel.start,
selection_col_to: sel.end,
})
.collect();
Pdu::Pong { .. } | Pdu::ListTabsResponse { .. } | Pdu::Invalid { .. } => {}
let (physical_rows, physical_cols) = renderable.physical_dimensions();
Ok(GetCoarseTabRenderableDataResponse {
dirty_lines,
current_highlight: renderable.current_highlight(),
cursor_position: renderable.get_cursor_position(),
physical_rows,
physical_cols,
})
})
.wait()?;
Pdu::GetCoarseTabRenderableDataResponse(result)
.encode(&mut self.stream, decoded.serial)?;
}
Pdu::Pong { .. }
| Pdu::ListTabsResponse { .. }
| Pdu::GetCoarseTabRenderableDataResponse { .. }
| Pdu::Invalid { .. } => {}
}
}
}

View File

@ -7,7 +7,6 @@ use serde_derive::*;
use failure::Error;
use std::ops::{Deref, DerefMut, Range};
use std::rc::Rc;
use std::str;
#[macro_use]

View File

@ -1,4 +1,5 @@
use super::*;
use std::sync::Arc;
use termwiz::escape::parser::Parser;
use termwiz::hyperlink::Rule as HyperlinkRule;
@ -20,7 +21,7 @@ pub trait TerminalHost {
fn set_title(&mut self, title: &str);
/// Called when a URL is clicked
fn click_link(&mut self, link: &Rc<Hyperlink>);
fn click_link(&mut self, link: &Arc<Hyperlink>);
/// Switch to a specific tab
fn activate_tab(&mut self, _tab: usize) {}

View File

@ -5,6 +5,7 @@ use super::*;
use image::{self, GenericImage};
use ordered_float::NotNaN;
use std::fmt::Write;
use std::sync::Arc;
use termwiz::escape::csi::{
Cursor, DecPrivateMode, DecPrivateModeCode, Device, Edit, EraseInDisplay, EraseInLine, Mode,
Sgr,
@ -154,7 +155,7 @@ pub struct TerminalState {
/// Which hyperlink is considered to be highlighted, because the
/// mouse_position is over a cell with a Hyperlink attribute.
current_highlight: Option<Rc<Hyperlink>>,
current_highlight: Option<Arc<Hyperlink>>,
/// Keeps track of double and triple clicks
last_mouse_click: Option<LastMouseClick>,
@ -342,7 +343,7 @@ impl TerminalState {
&mut self,
x: usize,
y: ScrollbackOrVisibleRowIndex,
) -> Option<Rc<Hyperlink>> {
) -> Option<Arc<Hyperlink>> {
let rules = &self.hyperlink_rules;
let idx = self.screen.scrollback_or_visible_row(y);
@ -1003,7 +1004,7 @@ impl TerminalState {
}
/// Returns the currently highlighted hyperlink
pub fn current_highlight(&self) -> Option<Rc<Hyperlink>> {
pub fn current_highlight(&self) -> Option<Arc<Hyperlink>> {
self.current_highlight.as_ref().cloned()
}
@ -1139,7 +1140,7 @@ impl TerminalState {
fn set_hyperlink(&mut self, link: Option<Hyperlink>) {
self.pen.hyperlink = match link {
Some(hyperlink) => Some(Rc::new(hyperlink)),
Some(hyperlink) => Some(Arc::new(hyperlink)),
None => None,
}
}
@ -1228,7 +1229,7 @@ impl TerminalState {
};
*/
let image_data = Rc::new(ImageData::with_raw_data(image.data));
let image_data = Arc::new(ImageData::with_raw_data(image.data));
let mut ypos = NotNaN::new(0.0).unwrap();
let cursor_x = self.cursor.x;

View File

@ -6,7 +6,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use smallvec::SmallVec;
use std;
use std::mem;
use std::rc::Rc;
use std::sync::Arc;
use unicode_width::UnicodeWidthStr;
/// Holds the attributes for a cell.
@ -22,7 +22,7 @@ pub struct CellAttributes {
/// The background color
pub background: ColorAttribute,
/// The hyperlink content, if any
pub hyperlink: Option<Rc<Hyperlink>>,
pub hyperlink: Option<Arc<Hyperlink>>,
/// The image data, if any
pub image: Option<Box<ImageCell>>,
}
@ -159,7 +159,7 @@ impl CellAttributes {
self
}
pub fn set_hyperlink(&mut self, link: Option<Rc<Hyperlink>>) -> &mut Self {
pub fn set_hyperlink(&mut self, link: Option<Arc<Hyperlink>>) -> &mut Self {
self.hyperlink = link;
self
}
@ -309,7 +309,7 @@ pub enum AttributeChange {
Invisible(bool),
Foreground(ColorAttribute),
Background(ColorAttribute),
Hyperlink(Option<Rc<Hyperlink>>),
Hyperlink(Option<Arc<Hyperlink>>),
}
#[cfg(test)]

View File

@ -11,7 +11,7 @@ use serde_derive::*;
use std::collections::HashMap;
use std::fmt::{Display, Error as FmtError, Formatter};
use std::ops::Range;
use std::rc::Rc;
use std::sync::Arc;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Hyperlink {
@ -157,7 +157,7 @@ pub struct RuleMatch {
pub range: Range<usize>,
/// Holds the created Hyperlink object that should be associated
/// the cells that correspond to the span.
pub link: Rc<Hyperlink>,
pub link: Arc<Hyperlink>,
}
/// An internal intermediate match result
@ -220,7 +220,7 @@ impl Rule {
.into_iter()
.map(|m| {
let url = m.expand();
let link = Rc::new(Hyperlink::new_implicit(url));
let link = Arc::new(Hyperlink::new_implicit(url));
RuleMatch {
link,
range: m.range(),
@ -245,7 +245,7 @@ mod test {
Rule::match_hyperlinks(" http://example.com", &rules),
vec![RuleMatch {
range: 2..20,
link: Rc::new(Hyperlink::new_implicit("http://example.com")),
link: Arc::new(Hyperlink::new_implicit("http://example.com")),
}]
);
@ -255,11 +255,11 @@ mod test {
// Longest match first
RuleMatch {
range: 18..34,
link: Rc::new(Hyperlink::new_implicit("mailto:woot@example.com")),
link: Arc::new(Hyperlink::new_implicit("mailto:woot@example.com")),
},
RuleMatch {
range: 2..17,
link: Rc::new(Hyperlink::new_implicit("mailto:foo@example.com")),
link: Arc::new(Hyperlink::new_implicit("mailto:foo@example.com")),
},
]
);

View File

@ -14,7 +14,7 @@
use ordered_float::NotNaN;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_derive::*;
use std::rc::Rc;
use std::sync::Arc;
fn deserialize_notnan<'de, D>(deserializer: D) -> Result<NotNaN<f32>, D::Error>
where
@ -71,14 +71,14 @@ pub struct ImageCell {
/// Texture coordinates for the bottom right of this cell.
bottom_right: TextureCoordinate,
/// References the underlying image data
data: Rc<ImageData>,
data: Arc<ImageData>,
}
impl ImageCell {
pub fn new(
top_left: TextureCoordinate,
bottom_right: TextureCoordinate,
data: Rc<ImageData>,
data: Arc<ImageData>,
) -> Self {
Self {
top_left,

View File

@ -2,7 +2,7 @@ use crate::cell::{AttributeChange, CellAttributes};
use crate::color::ColorAttribute;
pub use crate::image::{ImageData, TextureCoordinate};
use crate::surface::{CursorShape, Position};
use std::rc::Rc;
use std::sync::Arc;
/// `Change` describes an update operation to be applied to a `Surface`.
/// Changes to the active attributes (color, style), moving the cursor
@ -103,5 +103,5 @@ pub struct Image {
/// Texture coordinates for the bottom right of this image block.
pub bottom_right: TextureCoordinate,
/// the image data
pub image: Rc<ImageData>,
pub image: Arc<ImageData>,
}

View File

@ -4,7 +4,7 @@ use crate::hyperlink::Rule;
use crate::range::in_range;
use crate::surface::Change;
use std::ops::Range;
use std::rc::Rc;
use std::sync::Arc;
use unicode_segmentation::UnicodeSegmentation;
bitflags! {
@ -155,7 +155,7 @@ impl Line {
let attrs = self.cells[cell_idx]
.attrs()
.clone()
.set_hyperlink(Some(Rc::clone(&m.link)))
.set_hyperlink(Some(Arc::clone(&m.link)))
.clone();
let cell = Cell::new_grapheme(self.cells[cell_idx].str(), attrs);
self.cells[cell_idx] = cell;

View File

@ -770,7 +770,7 @@ mod test {
use crate::cell::Intensity;
use crate::color::AnsiColor;
use crate::image::ImageData;
use std::rc::Rc;
use std::sync::Arc;
// The \x20's look a little awkward, but we can't use a plain
// space in the first chararcter of a multi-line continuation;
@ -1432,7 +1432,7 @@ mod test {
#[test]
fn images() {
// a dummy image blob with nonsense content
let data = Rc::new(ImageData::with_raw_data(vec![]));
let data = Arc::new(ImageData::with_raw_data(vec![]));
let mut s = Surface::new(2, 2);
s.add_change(Change::Image(Image {
top_left: TextureCoordinate::new_f32(0.0, 0.0),