netget/scripting/
highlight.rs1use std::sync::OnceLock;
4use syntect::easy::HighlightLines;
5use syntect::highlighting::ThemeSet;
6use syntect::parsing::SyntaxSet;
7use syntect::util::{as_24_bit_terminal_escaped, LinesWithEndings};
8
9static SYNTAXES: OnceLock<SyntaxSet> = OnceLock::new();
10static THEMES: OnceLock<ThemeSet> = OnceLock::new();
11
12pub fn highlight_code(code: &str, language: &str) -> String {
17 let ps = SYNTAXES.get_or_init(SyntaxSet::load_defaults_newlines);
19 let ts = THEMES.get_or_init(ThemeSet::load_defaults);
20
21 let theme = &ts.themes["base16-ocean.dark"];
23
24 let syntax = ps
26 .find_syntax_by_token(language)
27 .unwrap_or_else(|| ps.find_syntax_plain_text());
28
29 let mut h = HighlightLines::new(syntax, theme);
31 let mut highlighted = String::new();
32
33 for line in LinesWithEndings::from(code) {
34 if let Ok(ranges) = h.highlight_line(line, ps) {
35 let escaped = as_24_bit_terminal_escaped(&ranges[..], false);
36 highlighted.push_str(&escaped);
37 } else {
38 highlighted.push_str(line);
40 }
41 }
42
43 highlighted.push_str("\x1b[0m");
45
46 highlighted
47}
48
49pub fn format_script_for_log(code: &str, language: &str) -> String {
53 let highlighted = highlight_code(code, language);
54
55 format!(
56 "\n┌─────────────────────────────────────────────┐\n\
57 │ LLM-Generated {} Script \n\
58 └─────────────────────────────────────────────┘\n\
59 {}\n\
60 ─────────────────────────────────────────────────",
61 language.to_uppercase(),
62 highlighted
63 )
64}