Skip to main content

ratatui_code_editor/
utils.rs

1pub fn get_lang(filename: &str) -> String {
2
3    let extension = std::path::Path::new(filename)
4        .extension()
5        .and_then(|ext| ext.to_str())
6        .unwrap_or("");
7
8    match extension {
9        "rs" => "rust",
10        "js" | "jsx"  => "javascript",
11        "ts" | "tsx"=> "typescript",
12        "py" => "python",
13        "go" => "go",
14        "java" => "java",
15        "cpp"  => "cpp",
16        "c" => "c",
17        "cs" => "c_sharp",
18        "html" => "html",
19        "css" => "css",
20        "json" => "json",
21        "toml" => "toml",
22        "yaml" | "yml" => "yaml",
23        "sh" | "bash" => "shell",
24        "md" => "markdown",
25        _ => "unknown",
26    }
27    .to_string()
28}
29
30pub fn indent(lang: &str) -> String {
31    match lang {
32        "rust" |"python" | "php" | "toml" | "c"  | "cpp" |
33        "zig" | "kotlin" | "erlang" | "html" | "sql" => {
34            "    ".to_string()
35        },
36        "go" | "c_sharp" => {
37            "\t".to_string()
38        },
39
40        _ => "  ".to_string(),
41    }
42}
43
44pub fn comment(lang: &str) -> &'static str {
45    match lang {
46        "python" | "shell" => "#",
47        "lua" => "--",
48        _ => "//",
49    }
50}
51
52pub fn count_indent_units(
53    line: ropey::RopeSlice<'_>, 
54    indent_unit: &str, 
55    max_col: Option<usize>
56) -> usize {
57    if indent_unit.is_empty() { return 0; }
58
59    let mut chars = line.chars();
60    let mut count = 0;
61    let mut col = 0;
62    let indent_chars: Vec<char> = indent_unit.chars().collect();
63
64    'outer: loop {
65        for &ch in &indent_chars {
66            match chars.next() {
67                Some(c) if c == ch => col += 1,
68                _ => break 'outer,
69            }
70        }
71        count += 1;
72        if let Some(max) = max_col {
73            if col >= max { break; }
74        }
75    }
76
77    count
78}
79
80pub fn rgb(hex: &str) -> (u8, u8, u8) {
81    let hex = hex.trim_start_matches('#');
82    let r = u8::from_str_radix(&hex[0..2], 16).unwrap_or(0);
83    let g = u8::from_str_radix(&hex[2..4], 16).unwrap_or(0);
84    let b = u8::from_str_radix(&hex[4..6], 16).unwrap_or(0);
85    (r, g, b)
86}
87
88/// Calculate end position by walking through the text
89/// Returns (end_row, end_col) starting from (start_row, start_col)
90pub fn calculate_end_position(
91    start_row: usize, start_col: usize, text: &str
92) -> (usize, usize) {
93    let mut end_row = start_row;
94    let mut end_col = start_col;
95    
96    for ch in text.chars() {
97        if ch == '\n' {
98            end_row += 1;
99            end_col = 0;
100        } else {
101            end_col += 1;
102        }
103    }
104    
105    (end_row, end_col)
106}