Skip to content

Commit d73be65

Browse files
authored
refactor: support highlighting more languages (#28)
1 parent 11dc4d1 commit d73be65

File tree

6 files changed

+54
-87
lines changed

6 files changed

+54
-87
lines changed

Cargo.lock

Lines changed: 24 additions & 46 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ copypasta = "0.8.2"
3131
chrono = "0.4.23"
3232
atty = "0.2.14"
3333
unicode-width = "0.1.10"
34+
bincode = "1.3.3"
3435

3536
[dependencies.syntect]
3637
version = "5.0.0"
3738
default-features = false
38-
features = ["parsing", "regex-fancy", "default-syntaxes"]
39+
features = ["parsing", "regex-onig"]
3940

4041
[profile.release]
4142
lto = true

assets/syntaxes.bin

877 KB
Binary file not shown.
File renamed without changes.

src/render/markdown.rs

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ use syntect::parsing::SyntaxSet;
33
use syntect::util::as_24_bit_terminal_escaped;
44
use syntect::{easy::HighlightLines, parsing::SyntaxReference};
55

6-
const THEME: &[u8] = include_bytes!("theme.yaml");
6+
/// Comms from https://github.com/jonschlinkert/sublime-monokai-extended/tree/0ca4e75291515c4d47e2d455e598e03e0dc53745
7+
const THEME: &[u8] = include_bytes!("../../assets/theme.yaml");
8+
/// Comes from https://github.com/sharkdp/bat/raw/5e77ca37e89c873e4490b42ff556370dc5c6ba4f/assets/syntaxes.bin
9+
const SYNTAXES: &[u8] = include_bytes!("../../assets/syntaxes.bin");
710

811
pub struct MarkdownRender {
912
syntax_set: SyntaxSet,
@@ -16,7 +19,8 @@ pub struct MarkdownRender {
1619

1720
impl MarkdownRender {
1821
pub fn new() -> Self {
19-
let syntax_set = SyntaxSet::load_defaults_newlines();
22+
let syntax_set: SyntaxSet =
23+
bincode::deserialize_from(SYNTAXES).expect("invalid syntaxes.bin");
2024
let theme: Theme = serde_yaml::from_slice(THEME).unwrap();
2125
let md_syntax = syntax_set.find_syntax_by_extension("md").unwrap().clone();
2226
let txt_syntax = syntax_set.find_syntax_by_extension("txt").unwrap().clone();
@@ -96,12 +100,9 @@ impl MarkdownRender {
96100
}
97101

98102
fn find_syntax(&self, lang: &str) -> Option<&SyntaxReference> {
99-
self.syntax_set.find_syntax_by_extension(lang).or_else(|| {
100-
LANGEGUATE_NAME_EXTS
101-
.iter()
102-
.find(|(name, _)| *name == lang.to_lowercase())
103-
.and_then(|(_, ext)| self.syntax_set.find_syntax_by_extension(ext))
104-
})
103+
self.syntax_set
104+
.find_syntax_by_token(lang)
105+
.or_else(|| self.syntax_set.find_syntax_by_extension(lang))
105106
}
106107
}
107108

@@ -113,30 +114,6 @@ enum LineType {
113114
CodeEnd,
114115
}
115116

116-
const LANGEGUATE_NAME_EXTS: [(&str, &str); 21] = [
117-
("asp", "asa"),
118-
("actionscript", "as"),
119-
("c#", "cs"),
120-
("clojure", "clj"),
121-
("erlang", "erl"),
122-
("haskell", "hs"),
123-
("javascript", "js"),
124-
("bibtex", "bib"),
125-
("latex", "tex"),
126-
("tex", "sty"),
127-
("ocaml", "ml"),
128-
("ocamllex", "mll"),
129-
("ocamlyacc", "mly"),
130-
("objective-c++", "mm"),
131-
("objective-c", "m"),
132-
("pascal", "pas"),
133-
("perl", "pl"),
134-
("python", "py"),
135-
("restructuredtext", "rst"),
136-
("ruby", "rb"),
137-
("rust", "rs"),
138-
];
139-
140117
fn detect_code_block(line: &str) -> Option<String> {
141118
if !line.starts_with("```") {
142119
return None;
@@ -148,3 +125,9 @@ fn detect_code_block(line: &str) -> Option<String> {
148125
.collect();
149126
Some(lang)
150127
}
128+
129+
#[test]
130+
fn feature() {
131+
let syntax_set: SyntaxSet = bincode::deserialize_from(SYNTAXES).expect("invalid syntaxes.bin");
132+
assert!(syntax_set.find_syntax_by_extension("md").is_some());
133+
}

src/render/mod.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub fn render_stream_inner(
3636
writer: &mut Stdout,
3737
) -> Result<()> {
3838
let mut last_tick = Instant::now();
39-
let tick_rate = Duration::from_millis(200);
39+
let tick_rate = Duration::from_millis(100);
4040
let mut buffer = String::new();
4141
let mut markdown_render = MarkdownRender::new();
4242
let terminal_columns = terminal::size()?.0;
@@ -55,12 +55,15 @@ pub fn render_stream_inner(
5555
let mut lines: Vec<&str> = text.split('\n').collect();
5656
buffer = lines.pop().unwrap_or_default().to_string();
5757
let output = markdown_render.render(&lines.join("\n"));
58-
queue!(
59-
writer,
60-
style::Print(output),
61-
style::Print("\n"),
62-
style::Print(&buffer),
63-
)?;
58+
for line in output.split('\n') {
59+
queue!(
60+
writer,
61+
style::Print(line),
62+
style::Print("\n"),
63+
cursor::MoveLeft(terminal_columns),
64+
)?;
65+
}
66+
queue!(writer, style::Print(&buffer),)?;
6467
} else {
6568
buffer = format!("{buffer}{text}");
6669
let output = markdown_render.render_line_stateless(&buffer);
@@ -107,7 +110,9 @@ pub fn render_stream_inner(
107110
fn recover_cursor(writer: &mut Stdout, terminal_columns: u16, buffer: &str) -> Result<()> {
108111
let buffer_rows = (buffer.width() as u16 + terminal_columns - 1) / terminal_columns;
109112
let (_, row) = cursor::position()?;
110-
if row + 1 >= buffer_rows {
113+
if buffer_rows == 0 {
114+
queue!(writer, cursor::MoveTo(0, row))?;
115+
} else if row + 1 >= buffer_rows {
111116
queue!(writer, cursor::MoveTo(0, row + 1 - buffer_rows))?;
112117
} else {
113118
queue!(

0 commit comments

Comments
 (0)