1use ck_core::heatmap::{self, HeatmapBucket};
2use ratatui::style::Color;
3use std::path::{Path, PathBuf};
4use std::sync::OnceLock;
5use syntect::highlighting::ThemeSet;
6use syntect::parsing::SyntaxSet;
7
8pub fn syntax_set() -> &'static SyntaxSet {
9 static SYNTAX_SET: OnceLock<SyntaxSet> = OnceLock::new();
10 SYNTAX_SET.get_or_init(SyntaxSet::load_defaults_newlines)
11}
12
13pub fn theme_set() -> &'static ThemeSet {
14 static THEME_SET: OnceLock<ThemeSet> = OnceLock::new();
15 THEME_SET.get_or_init(ThemeSet::load_defaults)
16}
17
18pub use heatmap::{calculate_token_similarity, split_into_tokens};
19
20pub fn score_to_color(score: f32) -> Color {
21 match HeatmapBucket::from_score(score) {
22 HeatmapBucket::Step8 => Color::Rgb(0, 255, 100),
23 HeatmapBucket::Step7 => Color::Rgb(0, 200, 80),
24 HeatmapBucket::Step6 => Color::Rgb(0, 160, 70),
25 HeatmapBucket::Step5 => Color::Rgb(100, 140, 60),
26 _ => Color::Rgb(140, 140, 140),
27 }
28}
29
30pub fn apply_heatmap_color_to_token(token: &str, score: f32) -> Color {
31 if token.trim().is_empty() || token.chars().all(|c| !c.is_alphanumeric()) {
33 return Color::Reset;
34 }
35
36 let bucket = HeatmapBucket::from_score(score);
38
39 bucket
40 .rgb()
41 .map(|(r, g, b)| Color::Rgb(r, g, b))
42 .unwrap_or(Color::Reset)
43}
44
45pub fn find_repo_root(path: &Path) -> Option<PathBuf> {
46 let mut current = if path.is_file() {
47 path.parent().unwrap_or(path)
48 } else {
49 path
50 };
51
52 loop {
53 if current.join(".ck").exists() {
54 return Some(current.to_path_buf());
55 }
56 match current.parent() {
57 Some(parent) => current = parent,
58 None => return None,
59 }
60 }
61}