1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-11 03:27:05 +03:00

Start adding hyperlink support code

This commit is contained in:
Wez Furlong 2018-02-10 15:12:21 -08:00
parent 76fe17b20b
commit 1500063c96
3 changed files with 77 additions and 2 deletions

View File

@ -6,6 +6,7 @@ version = "0.1.0"
[dependencies]
bitflags = "1.0.1"
failure = "0.1.1"
maplit = "1.0.1"
palette = "0.2.1"
serde = "1.0.27"
serde_derive = "1.0.27"
@ -14,5 +15,4 @@ unicode-width = "0.1.4"
vte = "0.3.2"
[features]
# When enabled, print the results of parsing the input stream to stdout
debug-escape-sequences = []

61
term/src/hyperlink.rs Normal file
View File

@ -0,0 +1,61 @@
//! Handling hyperlinks.
//! This gist describes an escape sequence for explicitly managing hyperlinks:
//! https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5fedaA
//! We use that as the foundation of our hyperlink support, and the game
//! plan is to then implicitly enable the hyperlink attribute for a cell
//! as we recognize linkable input text during print() processing.
use std::collections::HashMap;
/// The spec says that the escape sequence is of the form:
/// OSC 8 ; params ; URI BEL|ST
/// params is an optional list of key=value assignments,
/// separated by the : character. Example: id=xyz123:foo=bar:baz=quux.
/// This function parses such a string and returns the mapping
/// of key to value. Malformed input causes subsequent key/value pairs
/// to be skipped, returning the data successfully parsed out so far.
pub fn parse_link_params(params: &str) -> HashMap<&str, &str> {
let mut map = HashMap::new();
for kv in params.split(":") {
let mut iter = kv.splitn(2, "=");
let key = iter.next();
let value = iter.next();
match (key, value) {
(Some(key), Some(value)) => map.insert(key, value),
_ => break,
};
}
map
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn parse_link() {
assert_eq!(parse_link_params(""), hashmap!{});
assert_eq!(parse_link_params("foo"), hashmap!{});
assert_eq!(
parse_link_params("foo=bar=baz"),
hashmap!{"foo" => "bar=baz"}
);
assert_eq!(parse_link_params("foo=bar"), hashmap!{"foo" => "bar"});
assert_eq!(
parse_link_params("id=1234:foo=bar"),
hashmap!{
"id" => "1234",
"foo" => "bar"
}
);
assert_eq!(
parse_link_params("id=1234:foo=bar:"),
hashmap!{
"id" => "1234",
"foo" => "bar"
}
);
}
}

View File

@ -13,14 +13,19 @@ extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate vte;
#[macro_use]
extern crate maplit;
use failure::Error;
use std::ops::{Deref, DerefMut, Range};
use std::str;
use std::time::{Duration, Instant};
#[macro_use]
mod debug;
pub mod hyperlink;
/// Represents the index into screen.lines. Index 0 is the top of
/// the scrollback (if any). The index of the top of the visible screen
/// depends on the terminal dimensions and the scrollback size.
@ -1808,7 +1813,6 @@ impl vte::Perform for TerminalState {
fn osc_dispatch(&mut self, osc: &[&[u8]]) {
match osc {
&[b"0", title] => {
use std::str;
if let Ok(title) = str::from_utf8(title) {
self.answerback.push(
AnswerBack::TitleChanged(title.to_string()),
@ -1817,6 +1821,16 @@ impl vte::Perform for TerminalState {
println!("OSC: failed to decode utf for {:?}", title);
}
}
&[b"8", params, url] => {
if let Ok(params) = str::from_utf8(params) {
println!("set URL params={}", params);
}
if let Ok(url) = str::from_utf8(url) {
println!("set URL attribute={}", url);
} else {
println!("OSC: failed to decode utf for {:?}", url);
}
}
_ => {
println!("OSC unhandled: {:?}", osc);
}