diff options
-rw-r--r-- | src/cmd/watch.rs | 3 | ||||
-rw-r--r-- | src/protocol.rs | 4 | ||||
-rw-r--r-- | src/server.rs | 8 | ||||
-rw-r--r-- | src/term.rs | 31 |
4 files changed, 40 insertions, 6 deletions
diff --git a/src/cmd/watch.rs b/src/cmd/watch.rs index a46b00c..74324e0 100644 --- a/src/cmd/watch.rs +++ b/src/cmd/watch.rs @@ -74,13 +74,14 @@ fn list(address: &str) -> Result<()> { println!("available sessions:"); for session in sessions { println!( - "{}: {}, {}x{}, TERM={}, idle {}s", + "{}: {}, {}x{}, TERM={}, idle {}s: {}", session.id, session.username, session.size.0, session.size.1, session.term_type, session.idle_time, + session.title, ); } } diff --git a/src/protocol.rs b/src/protocol.rs index e831c48..d9098c7 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -46,6 +46,7 @@ pub struct Session { pub term_type: String, pub size: (u32, u32), pub idle_time: u32, + pub title: String, } pub struct FramedReader( @@ -288,6 +289,7 @@ impl From<&Message> for Packet { write_u32(val.size.0, data); write_u32(val.size.1, data); write_u32(val.idle_time, data); + write_str(&val.title, data); } fn write_sessions(val: &[Session], data: &mut Vec<u8>) { write_u32(u32_from_usize(val.len()), data); @@ -403,6 +405,7 @@ impl std::convert::TryFrom<Packet> for Message { let (cols, data) = read_u32(data)?; let (rows, data) = read_u32(data)?; let (idle_time, data) = read_u32(data)?; + let (title, data) = read_str(data)?; Ok(( Session { id, @@ -410,6 +413,7 @@ impl std::convert::TryFrom<Packet> for Message { term_type, size: (cols, rows), idle_time, + title, }, data, )) diff --git a/src/server.rs b/src/server.rs index 6ff8492..7e8cae8 100644 --- a/src/server.rs +++ b/src/server.rs @@ -188,6 +188,13 @@ impl Connection { .. } => (username, term_info), }; + let title = if let ConnectionState::Casting { saved_data, .. } = + &self.state + { + saved_data.title() + } else { + "" + }; // i don't really care if things break for a connection that has been // idle for 136 years @@ -200,6 +207,7 @@ impl Connection { idle_time: std::time::Instant::now() .duration_since(self.last_activity) .as_secs() as u32, + title: title.to_string(), }) } diff --git a/src/term.rs b/src/term.rs index 1acbd65..f851267 100644 --- a/src/term.rs +++ b/src/term.rs @@ -4,9 +4,14 @@ const RESET: &[&[u8]] = &[ b"\x1b[H\x1b[2J", b"\x1bc", ]; +const WINDOW_TITLE: &[(&[u8], &[u8])] = + &[(b"\x1b]0;", b"\x07"), (b"\x1b]2;", b"\x07")]; #[derive(Debug, Default)] -pub struct Buffer(Vec<u8>); +pub struct Buffer { + contents: Vec<u8>, + title: String, +} impl Buffer { pub fn new() -> Self { @@ -15,24 +20,40 @@ impl Buffer { pub fn append(&mut self, mut buf: &[u8]) -> bool { let mut cleared = false; + for window_title in WINDOW_TITLE { + if let Some(i) = twoway::find_bytes(buf, window_title.0) { + if let Some(j) = twoway::find_bytes(&buf[i..], window_title.1) + { + let start = i + window_title.0.len(); + let end = j + i; + if let Ok(title) = std::str::from_utf8(&buf[start..end]) { + self.title = title.to_string(); + } + } + } + } for reset in RESET { if let Some(i) = twoway::find_bytes(buf, reset) { cleared = true; - self.0.clear(); + self.contents.clear(); buf = &buf[i..]; } } - self.0.extend_from_slice(buf); + self.contents.extend_from_slice(buf); cleared } pub fn contents(&self) -> &[u8] { - &self.0 + &self.contents } pub fn len(&self) -> usize { - self.0.len() + self.contents.len() + } + + pub fn title(&self) -> &str { + &self.title } } |