summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsigoden <sigoden@gmail.com>2023-03-07 15:37:03 +0800
committerGitHub <noreply@github.com>2023-03-07 15:37:03 +0800
commitd73be65b07c22f69539b5819f0684090c32d3b60 (patch)
tree0f8c7b11c6a046d8af253d754b8c5a98d316174d
parent11dc4d104b21b75d63e10e42ea4ee767c7bd5fdf (diff)
downloadaichat-d73be65b07c22f69539b5819f0684090c32d3b60.tar.gz
refactor: support highlighting more languages (#28)
-rw-r--r--Cargo.lock70
-rw-r--r--Cargo.toml3
-rw-r--r--assets/syntaxes.binbin0 -> 898115 bytes
-rw-r--r--assets/theme.yaml (renamed from src/render/theme.yaml)0
-rw-r--r--src/render/markdown.rs47
-rw-r--r--src/render/mod.rs21
6 files changed, 54 insertions, 87 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b5422ca..eedf019 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -9,20 +9,12 @@ 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",
@@ -98,21 +90,6 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -507,16 +484,6 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1115,6 +1082,28 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1256,17 +1245,6 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1611,11 +1589,11 @@ checksum = "c6c454c27d9d7d9a84c7803aaa3c50cd088d2906fe3c6e42da3209aa623576a8"
dependencies = [
"bincode",
"bitflags",
- "fancy-regex",
"flate2",
"fnv",
"lazy_static",
"once_cell",
+ "onig",
"regex-syntax",
"serde",
"serde_derive",
diff --git a/Cargo.toml b/Cargo.toml
index 216e8cb..731bbfa 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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
diff --git a/assets/syntaxes.bin b/assets/syntaxes.bin
new file mode 100644
index 0000000..df582f5
--- /dev/null
+++ b/assets/syntaxes.bin
Binary files differ
diff --git a/src/render/theme.yaml b/assets/theme.yaml
index 9475b9b..9475b9b 100644
--- a/src/render/theme.yaml
+++ b/assets/theme.yaml
diff --git a/src/render/markdown.rs b/src/render/markdown.rs
index fc0bc3e..5316653 100644
--- a/src/render/markdown.rs
+++ b/src/render/markdown.rs
@@ -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());
+}
diff --git a/src/render/mod.rs b/src/render/mod.rs
index b6e28f7..e0f42e7 100644
--- a/src/render/mod.rs
+++ b/src/render/mod.rs
@@ -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!(