refactor: support highlighting more languages (#28)

pull/30/head
sigoden 1 year ago committed by GitHub
parent 11dc4d104b
commit d73be65b07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

70
Cargo.lock generated

@ -8,21 +8,13 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
[[package]]
name = "aichat"
version = "0.4.0"
dependencies = [
"anyhow",
"atty",
"bincode",
"bytes",
"chrono",
"clap",
@ -97,21 +89,6 @@ dependencies = [
"serde",
]
[[package]]
name = "bit-set"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bitflags"
version = "1.3.2"
@ -506,16 +483,6 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "fancy-regex"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6b8560a05112eb52f04b00e5d3790c0dd75d9d980eb8a122fb23b92a623ccf"
dependencies = [
"bit-set",
"regex",
]
[[package]]
name = "fd-lock"
version = "3.0.10"
@ -1114,6 +1081,28 @@ version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "onig"
version = "6.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f"
dependencies = [
"bitflags",
"libc",
"once_cell",
"onig_sys",
]
[[package]]
name = "onig_sys"
version = "69.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7"
dependencies = [
"cc",
"pkg-config",
]
[[package]]
name = "os_str_bytes"
version = "6.4.1"
@ -1255,17 +1244,6 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "regex"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.28"
@ -1611,11 +1589,11 @@ checksum = "c6c454c27d9d7d9a84c7803aaa3c50cd088d2906fe3c6e42da3209aa623576a8"
dependencies = [
"bincode",
"bitflags",
"fancy-regex",
"flate2",
"fnv",
"lazy_static",
"once_cell",
"onig",
"regex-syntax",
"serde",
"serde_derive",

@ -31,11 +31,12 @@ copypasta = "0.8.2"
chrono = "0.4.23"
atty = "0.2.14"
unicode-width = "0.1.10"
bincode = "1.3.3"
[dependencies.syntect]
version = "5.0.0"
default-features = false
features = ["parsing", "regex-fancy", "default-syntaxes"]
features = ["parsing", "regex-onig"]
[profile.release]
lto = true

Binary file not shown.

@ -3,7 +3,10 @@ use syntect::parsing::SyntaxSet;
use syntect::util::as_24_bit_terminal_escaped;
use syntect::{easy::HighlightLines, parsing::SyntaxReference};
const THEME: &[u8] = include_bytes!("theme.yaml");
/// Comms from https://github.com/jonschlinkert/sublime-monokai-extended/tree/0ca4e75291515c4d47e2d455e598e03e0dc53745
const THEME: &[u8] = include_bytes!("../../assets/theme.yaml");
/// Comes from https://github.com/sharkdp/bat/raw/5e77ca37e89c873e4490b42ff556370dc5c6ba4f/assets/syntaxes.bin
const SYNTAXES: &[u8] = include_bytes!("../../assets/syntaxes.bin");
pub struct MarkdownRender {
syntax_set: SyntaxSet,
@ -16,7 +19,8 @@ pub struct MarkdownRender {
impl MarkdownRender {
pub fn new() -> Self {
let syntax_set = SyntaxSet::load_defaults_newlines();
let syntax_set: SyntaxSet =
bincode::deserialize_from(SYNTAXES).expect("invalid syntaxes.bin");
let theme: Theme = serde_yaml::from_slice(THEME).unwrap();
let md_syntax = syntax_set.find_syntax_by_extension("md").unwrap().clone();
let txt_syntax = syntax_set.find_syntax_by_extension("txt").unwrap().clone();
@ -96,12 +100,9 @@ impl MarkdownRender {
}
fn find_syntax(&self, lang: &str) -> Option<&SyntaxReference> {
self.syntax_set.find_syntax_by_extension(lang).or_else(|| {
LANGEGUATE_NAME_EXTS
.iter()
.find(|(name, _)| *name == lang.to_lowercase())
.and_then(|(_, ext)| self.syntax_set.find_syntax_by_extension(ext))
})
self.syntax_set
.find_syntax_by_token(lang)
.or_else(|| self.syntax_set.find_syntax_by_extension(lang))
}
}
@ -113,30 +114,6 @@ enum LineType {
CodeEnd,
}
const LANGEGUATE_NAME_EXTS: [(&str, &str); 21] = [
("asp", "asa"),
("actionscript", "as"),
("c#", "cs"),
("clojure", "clj"),
("erlang", "erl"),
("haskell", "hs"),
("javascript", "js"),
("bibtex", "bib"),
("latex", "tex"),
("tex", "sty"),
("ocaml", "ml"),
("ocamllex", "mll"),
("ocamlyacc", "mly"),
("objective-c++", "mm"),
("objective-c", "m"),
("pascal", "pas"),
("perl", "pl"),
("python", "py"),
("restructuredtext", "rst"),
("ruby", "rb"),
("rust", "rs"),
];
fn detect_code_block(line: &str) -> Option<String> {
if !line.starts_with("```") {
return None;
@ -148,3 +125,9 @@ fn detect_code_block(line: &str) -> Option<String> {
.collect();
Some(lang)
}
#[test]
fn feature() {
let syntax_set: SyntaxSet = bincode::deserialize_from(SYNTAXES).expect("invalid syntaxes.bin");
assert!(syntax_set.find_syntax_by_extension("md").is_some());
}

@ -36,7 +36,7 @@ pub fn render_stream_inner(
writer: &mut Stdout,
) -> Result<()> {
let mut last_tick = Instant::now();
let tick_rate = Duration::from_millis(200);
let tick_rate = Duration::from_millis(100);
let mut buffer = String::new();
let mut markdown_render = MarkdownRender::new();
let terminal_columns = terminal::size()?.0;
@ -55,12 +55,15 @@ pub fn render_stream_inner(
let mut lines: Vec<&str> = text.split('\n').collect();
buffer = lines.pop().unwrap_or_default().to_string();
let output = markdown_render.render(&lines.join("\n"));
queue!(
writer,
style::Print(output),
style::Print("\n"),
style::Print(&buffer),
)?;
for line in output.split('\n') {
queue!(
writer,
style::Print(line),
style::Print("\n"),
cursor::MoveLeft(terminal_columns),
)?;
}
queue!(writer, style::Print(&buffer),)?;
} else {
buffer = format!("{buffer}{text}");
let output = markdown_render.render_line_stateless(&buffer);
@ -107,7 +110,9 @@ pub fn render_stream_inner(
fn recover_cursor(writer: &mut Stdout, terminal_columns: u16, buffer: &str) -> Result<()> {
let buffer_rows = (buffer.width() as u16 + terminal_columns - 1) / terminal_columns;
let (_, row) = cursor::position()?;
if row + 1 >= buffer_rows {
if buffer_rows == 0 {
queue!(writer, cursor::MoveTo(0, row))?;
} else if row + 1 >= buffer_rows {
queue!(writer, cursor::MoveTo(0, row + 1 - buffer_rows))?;
} else {
queue!(

Loading…
Cancel
Save