Skip to main content

xei_core/
completion.rs

1pub struct Completions {
2    pub suggestions: Vec<Suggestion>,
3    pub selected: usize,
4    pub active: bool,
5    pub prefix: String,
6}
7
8#[derive(Clone, Debug)]
9pub struct Suggestion {
10    pub label: String,
11    pub detail: String,
12    pub insert_text: String,
13}
14
15impl Default for Completions {
16    fn default() -> Self {
17        Self {
18            suggestions: Vec::new(),
19            selected: 0,
20            active: false,
21            prefix: String::new(),
22        }
23    }
24}
25
26impl Completions {
27    pub fn new() -> Self {
28        Self::default()
29    }
30
31    pub fn activate(&mut self, prefix: &str, ext: Option<&str>) {
32        self.prefix = prefix.to_string();
33        self.selected = 0;
34        self.suggestions = get_suggestions(prefix, ext);
35        self.active = !self.suggestions.is_empty();
36    }
37
38    pub fn deactivate(&mut self) {
39        self.active = false;
40        self.suggestions.clear();
41        self.selected = 0;
42        self.prefix.clear();
43    }
44
45    pub fn selected_suggestion(&self) -> Option<&Suggestion> {
46        self.suggestions.get(self.selected)
47    }
48
49    pub fn next(&mut self) {
50        if !self.suggestions.is_empty() {
51            self.selected = (self.selected + 1) % self.suggestions.len();
52        }
53    }
54
55    pub fn prev(&mut self) {
56        if !self.suggestions.is_empty() {
57            if self.selected == 0 {
58                self.selected = self.suggestions.len() - 1;
59            } else {
60                self.selected -= 1;
61            }
62        }
63    }
64
65    pub fn refine(&mut self, prefix: &str) {
66        self.prefix = prefix.to_string();
67        let prefix_lower = prefix.to_lowercase();
68        let prev_count = self.suggestions.len();
69        self.suggestions.retain(|s| s.label.to_lowercase().starts_with(&prefix_lower));
70        if self.suggestions.len() < prev_count {
71            self.selected = 0;
72        }
73        if self.suggestions.is_empty() {
74            self.active = false;
75        }
76    }
77}
78
79fn get_suggestions(prefix: &str, ext: Option<&str>) -> Vec<Suggestion> {
80    let keywords = match ext {
81        Some("rs") => rust_keywords(),
82        Some("ts" | "tsx") => ts_keywords(),
83        Some("js" | "jsx") => js_keywords(),
84        Some("py") => py_keywords(),
85        Some("go") => go_keywords(),
86        Some("html" | "htm") => html_keywords(),
87        Some("css") => css_keywords(),
88        Some("json") => json_keywords(),
89        Some("toml") => toml_keywords(),
90        Some("md" | "mdx") => markdown_keywords(),
91        Some("sh" | "bash" | "zsh") => shell_keywords(),
92        Some("yaml" | "yml") => yaml_keywords(),
93        Some("sql") => sql_keywords(),
94        Some("c" | "h") => c_keywords(),
95        Some("cpp" | "hpp" | "cc" | "cxx") => cpp_keywords(),
96        _ => vec![],
97    };
98
99    let prefix_lower = prefix.to_lowercase();
100    keywords
101        .into_iter()
102        .filter(|(label, _)| label.to_lowercase().starts_with(&prefix_lower))
103        .map(|(label, detail)| Suggestion {
104            insert_text: label.to_string(),
105            label: label.to_string(),
106            detail: detail.to_string(),
107        })
108        .collect()
109}
110
111fn rust_keywords() -> Vec<(&'static str, &'static str)> {
112    vec![
113        ("fn", "function"),
114        ("let", "variable binding"),
115        ("let mut", "mutable binding"),
116        ("struct", "struct"),
117        ("impl", "impl block"),
118        ("enum", "enum"),
119        ("trait", "trait"),
120        ("impl", "implementation"),
121        ("pub", "public visibility"),
122        ("pub fn", "public function"),
123        ("pub(crate)", "crate visibility"),
124        ("use", "import"),
125        ("mod", "module"),
126        ("match", "match expression"),
127        ("if", "if expression"),
128        ("if let", "if let pattern"),
129        ("else", "else branch"),
130        ("while", "while loop"),
131        ("for", "for loop"),
132        ("loop", "infinite loop"),
133        ("return", "return statement"),
134        ("self", "self reference"),
135        ("Self", "Self type"),
136        ("const", "constant"),
137        ("static", "static variable"),
138        ("type", "type alias"),
139        ("where", "where clause"),
140        ("unsafe", "unsafe block"),
141        ("async", "async function"),
142        ("await", "await expression"),
143        ("move", "move closure"),
144        ("ref", "ref pattern"),
145        ("mut", "mutable binding"),
146        ("true", "boolean"),
147        ("false", "boolean"),
148        ("Some", "Option::Some"),
149        ("None", "Option::None"),
150        ("Ok", "Result::Ok"),
151        ("Err", "Result::Err"),
152        ("Result", "Result type"),
153        ("Option", "Option type"),
154        ("Vec", "Vec type"),
155        ("String", "String type"),
156        ("HashMap", "HashMap type"),
157        ("println!", "print macro"),
158        ("format!", "format macro"),
159        ("vec!", "vec macro"),
160        ("eprintln!", "stderr print"),
161        ("dbg!", "debug macro"),
162        ("assert!", "assert macro"),
163        ("todo!", "todo macro"),
164        ("unimplemented!", "unimplemented macro"),
165        ("#[derive(", "derive attribute"),
166        ("#[cfg(", "cfg attribute"),
167        ("#![allow(", "allow attribute"),
168        ("crate", "root module"),
169        ("super", "parent module"),
170        ("dyn", "dynamic dispatch"),
171        ("as", "type cast"),
172        ("in", "in keyword"),
173        ("break", "break statement"),
174        ("continue", "continue statement"),
175        ("extern", "external block"),
176        ("macro_rules!", "macro definition"),
177        ("Box", "Box type"),
178        ("Rc", "Rc type"),
179        ("Arc", "Arc type"),
180        ("Cell", "Cell type"),
181        ("RefCell", "RefCell type"),
182        ("Mutex", "Mutex type"),
183        ("RwLock", "RwLock type"),
184        ("Clone", "Clone trait"),
185        ("Copy", "Copy trait"),
186        ("Debug", "Debug trait"),
187        ("Default", "Default trait"),
188        ("Drop", "Drop trait"),
189        ("From", "From trait"),
190        ("Into", "Into trait"),
191        ("Iterator", "Iterator trait"),
192        ("std::", "standard library"),
193    ]
194}
195
196fn ts_keywords() -> Vec<(&'static str, &'static str)> {
197    vec![
198        ("function", "function"),
199        ("const", "constant"),
200        ("let", "variable"),
201        ("var", "variable (legacy)"),
202        ("class", "class"),
203        ("interface", "interface"),
204        ("type", "type alias"),
205        ("enum", "enum"),
206        ("import", "import"),
207        ("export", "export"),
208        ("export default", "default export"),
209        ("async", "async"),
210        ("await", "await"),
211        ("return", "return"),
212        ("if", "if"),
213        ("else", "else"),
214        ("for", "for"),
215        ("while", "while"),
216        ("switch", "switch"),
217        ("case", "case"),
218        ("try", "try"),
219        ("catch", "catch"),
220        ("throw", "throw"),
221        ("new", "new"),
222        ("extends", "extends"),
223        ("implements", "implements"),
224        ("private", "private"),
225        ("protected", "protected"),
226        ("public", "public"),
227        ("readonly", "readonly"),
228        ("static", "static"),
229        ("abstract", "abstract"),
230        ("typeof", "typeof"),
231        ("keyof", "keyof"),
232        ("as", "type assertion"),
233        ("in", "in"),
234        ("null", "null"),
235        ("undefined", "undefined"),
236        ("true", "true"),
237        ("false", "false"),
238    ]
239}
240
241fn js_keywords() -> Vec<(&'static str, &'static str)> {
242    vec![
243        ("function", "function"),
244        ("const", "constant"),
245        ("let", "variable"),
246        ("var", "variable"),
247        ("class", "class"),
248        ("import", "import"),
249        ("export", "export"),
250        ("export default", "default export"),
251        ("async", "async"),
252        ("await", "await"),
253        ("return", "return"),
254        ("if", "if"),
255        ("else", "else"),
256        ("for", "for"),
257        ("while", "while"),
258        ("switch", "switch"),
259        ("try", "try"),
260        ("catch", "catch"),
261        ("throw", "throw"),
262        ("new", "new"),
263        ("null", "null"),
264        ("undefined", "undefined"),
265        ("true", "true"),
266        ("false", "false"),
267        ("console.log(", "log"),
268        ("console.error(", "error"),
269        ("JSON.parse(", "parse JSON"),
270        ("JSON.stringify(", "stringify JSON"),
271        ("Promise", "Promise"),
272        ("async ", "async fn"),
273        ("setTimeout(", "setTimeout"),
274        ("setInterval(", "setInterval"),
275        ("require(", "require"),
276        ("module.exports", "module.exports"),
277    ]
278}
279
280fn py_keywords() -> Vec<(&'static str, &'static str)> {
281    vec![
282        ("def", "function"),
283        ("class", "class"),
284        ("import", "import"),
285        ("from", "import from"),
286        ("if", "if"),
287        ("elif", "elif"),
288        ("else", "else"),
289        ("for", "for"),
290        ("while", "while"),
291        ("try", "try"),
292        ("except", "except"),
293        ("finally", "finally"),
294        ("raise", "raise"),
295        ("with", "with"),
296        ("as", "as"),
297        ("return", "return"),
298        ("yield", "yield"),
299        ("lambda", "lambda"),
300        ("async", "async"),
301        ("await", "await"),
302        ("pass", "pass"),
303        ("break", "break"),
304        ("continue", "continue"),
305        ("self", "self"),
306        ("True", "True"),
307        ("False", "False"),
308        ("None", "None"),
309        ("print(", "print"),
310        ("len(", "len"),
311        ("range(", "range"),
312        ("enumerate(", "enumerate"),
313        ("zip(", "zip"),
314        ("list(", "list"),
315        ("dict(", "dict"),
316        ("set(", "set"),
317        ("tuple(", "tuple"),
318        ("str(", "str"),
319        ("int(", "int"),
320        ("float(", "float"),
321        ("type(", "type"),
322        ("isinstance(", "isinstance"),
323        ("super()", "super"),
324        ("__init__", "__init__"),
325        ("__str__", "__str__"),
326        ("__repr__", "__repr__"),
327    ]
328}
329
330fn go_keywords() -> Vec<(&'static str, &'static str)> {
331    vec![
332        ("func", "function"),
333        ("var", "variable"),
334        ("const", "constant"),
335        ("type", "type"),
336        ("struct", "struct"),
337        ("interface", "interface"),
338        ("package", "package"),
339        ("import", "import"),
340        ("if", "if"),
341        ("else", "else"),
342        ("for", "for"),
343        ("range", "range"),
344        ("switch", "switch"),
345        ("case", "case"),
346        ("default", "default"),
347        ("defer", "defer"),
348        ("go", "goroutine"),
349        ("chan", "channel"),
350        ("select", "select"),
351        ("return", "return"),
352        ("break", "break"),
353        ("continue", "continue"),
354        ("map", "map"),
355        ("make(", "make"),
356        ("new(", "new"),
357        ("nil", "nil"),
358        ("true", "true"),
359        ("false", "false"),
360    ]
361}
362
363fn html_keywords() -> Vec<(&'static str, &'static str)> {
364    vec![
365        ("<!DOCTYPE html>", "doctype"),
366        ("<html>", "html"),
367        ("<head>", "head"),
368        ("<body>", "body"),
369        ("<div>", "div"),
370        ("<span>", "span"),
371        ("<p>", "paragraph"),
372        ("<a href=\"\">", "anchor"),
373        ("<img src=\"\" alt=\"\">", "image"),
374        ("<ul>", "unordered list"),
375        ("<ol>", "ordered list"),
376        ("<li>", "list item"),
377        ("<table>", "table"),
378        ("<tr>", "table row"),
379        ("<td>", "table data"),
380        ("<th>", "table header"),
381        ("<form>", "form"),
382        ("<input>", "input"),
383        ("<button>", "button"),
384        ("<script>", "script"),
385        ("<style>", "style"),
386        ("<link>", "link"),
387        ("<meta>", "meta"),
388        ("<h1>", "heading 1"),
389        ("<h2>", "heading 2"),
390        ("<h3>", "heading 3"),
391        ("<header>", "header"),
392        ("<footer>", "footer"),
393        ("<nav>", "nav"),
394        ("<main>", "main"),
395        ("<section>", "section"),
396        ("<article>", "article"),
397        ("<aside>", "aside"),
398    ]
399}
400
401fn css_keywords() -> Vec<(&'static str, &'static str)> {
402    vec![
403        ("color:", "text color"),
404        ("background:", "background"),
405        ("background-color:", "bg color"),
406        ("margin:", "margin"),
407        ("padding:", "padding"),
408        ("border:", "border"),
409        ("border-radius:", "border radius"),
410        ("font-size:", "font size"),
411        ("font-weight:", "font weight"),
412        ("font-family:", "font family"),
413        ("display:", "display"),
414        ("flex", "flex container"),
415        ("grid", "grid container"),
416        ("position:", "position"),
417        ("width:", "width"),
418        ("height:", "height"),
419        ("max-width:", "max width"),
420        ("min-height:", "min height"),
421        ("overflow:", "overflow"),
422        ("opacity:", "opacity"),
423        ("z-index:", "z-index"),
424        ("text-align:", "text align"),
425        ("line-height:", "line height"),
426        ("cursor:", "cursor"),
427        ("transition:", "transition"),
428        ("transform:", "transform"),
429        ("box-shadow:", "box shadow"),
430        (":hover", "hover pseudo"),
431        ("::before", "before pseudo"),
432        ("::after", "after pseudo"),
433        ("@media", "media query"),
434        ("@import", "import"),
435    ]
436}
437
438fn json_keywords() -> Vec<(&'static str, &'static str)> {
439    vec![
440        ("true", "boolean"),
441        ("false", "boolean"),
442        ("null", "null"),
443    ]
444}
445
446fn toml_keywords() -> Vec<(&'static str, &'static str)> {
447    vec![
448        ("[package]", "package section"),
449        ("[dependencies]", "dependencies"),
450        ("[dev-dependencies]", "dev deps"),
451        ("[build-dependencies]", "build deps"),
452        ("[features]", "features"),
453        ("[profile]", "profile"),
454        ("[workspace]", "workspace"),
455        ("name = ", "package name"),
456        ("version = ", "version"),
457        ("edition = ", "edition"),
458    ]
459}
460
461fn markdown_keywords() -> Vec<(&'static str, &'static str)> {
462    vec![
463        ("# ", "heading 1"),
464        ("## ", "heading 2"),
465        ("### ", "heading 3"),
466        ("#### ", "heading 4"),
467        ("**", "bold"),
468        ("__", "italic"),
469        ("`", "code"),
470        ("```", "code block"),
471        ("> ", "blockquote"),
472        ("- ", "list item"),
473        ("1. ", "ordered list"),
474        ("[text](", "link"),
475        ("![alt](", "image"),
476        ("---", "horizontal rule"),
477        ("- [ ] ", "task"),
478    ]
479}
480
481fn shell_keywords() -> Vec<(&'static str, &'static str)> {
482    vec![
483        ("#!/bin/bash", "shebang bash"),
484        ("#!/bin/sh", "shebang sh"),
485        ("#!/usr/bin/env bash", "shebang env bash"),
486        ("if", "if"),
487        ("then", "then"),
488        ("else", "else"),
489        ("elif", "elif"),
490        ("fi", "fi (end if)"),
491        ("for", "for"),
492        ("while", "while"),
493        ("do", "do"),
494        ("done", "done"),
495        ("case", "case"),
496        ("esac", "esac"),
497        ("function", "function"),
498        ("local", "local"),
499        ("export", "export"),
500        ("source", "source"),
501        ("exit", "exit"),
502        ("return", "return"),
503        ("echo", "echo"),
504        ("read", "read"),
505        ("test", "test"),
506        ("shift", "shift"),
507        ("unset", "unset"),
508        ("alias", "alias"),
509        ("trap", "trap"),
510    ]
511}
512
513fn yaml_keywords() -> Vec<(&'static str, &'static str)> {
514    vec![
515        ("---", "document start"),
516        ("...", "document end"),
517        ("true", "boolean"),
518        ("false", "boolean"),
519        ("null", "null"),
520    ]
521}
522
523fn sql_keywords() -> Vec<(&'static str, &'static str)> {
524    vec![
525        ("SELECT", "select"),
526        ("FROM", "from"),
527        ("WHERE", "where"),
528        ("INSERT INTO", "insert"),
529        ("VALUES", "values"),
530        ("UPDATE", "update"),
531        ("SET", "set"),
532        ("DELETE", "delete"),
533        ("CREATE TABLE", "create table"),
534        ("ALTER TABLE", "alter table"),
535        ("DROP TABLE", "drop table"),
536        ("JOIN", "join"),
537        ("LEFT JOIN", "left join"),
538        ("INNER JOIN", "inner join"),
539        ("ON", "on"),
540        ("GROUP BY", "group by"),
541        ("ORDER BY", "order by"),
542        ("HAVING", "having"),
543        ("LIMIT", "limit"),
544        ("OFFSET", "offset"),
545        ("INDEX", "index"),
546        ("PRIMARY KEY", "primary key"),
547        ("FOREIGN KEY", "foreign key"),
548        ("NOT NULL", "not null"),
549        ("DEFAULT", "default"),
550        ("UNIQUE", "unique"),
551        ("AS", "alias"),
552        ("DISTINCT", "distinct"),
553        ("COUNT(", "count"),
554        ("SUM(", "sum"),
555        ("AVG(", "avg"),
556        ("MAX(", "max"),
557        ("MIN(", "min"),
558    ]
559}
560
561fn c_keywords() -> Vec<(&'static str, &'static str)> {
562    vec![
563        ("int", "integer"),
564        ("char", "character"),
565        ("float", "float"),
566        ("double", "double"),
567        ("void", "void"),
568        ("struct", "struct"),
569        ("union", "union"),
570        ("enum", "enum"),
571        ("typedef", "typedef"),
572        ("sizeof", "sizeof"),
573        ("if", "if"),
574        ("else", "else"),
575        ("for", "for"),
576        ("while", "while"),
577        ("do", "do"),
578        ("switch", "switch"),
579        ("case", "case"),
580        ("break", "break"),
581        ("continue", "continue"),
582        ("return", "return"),
583        ("static", "static"),
584        ("extern", "extern"),
585        ("const", "const"),
586        ("volatile", "volatile"),
587        ("register", "register"),
588        ("auto", "auto"),
589        ("unsigned", "unsigned"),
590        ("signed", "signed"),
591        ("short", "short"),
592        ("long", "long"),
593        ("#include", "include"),
594        ("#define", "define"),
595        ("#ifdef", "ifdef"),
596        ("#ifndef", "ifndef"),
597        ("#endif", "endif"),
598        ("NULL", "null"),
599        ("malloc(", "malloc"),
600        ("free(", "free"),
601        ("printf(", "printf"),
602        ("scanf(", "scanf"),
603    ]
604}
605
606fn cpp_keywords() -> Vec<(&'static str, &'static str)> {
607    let mut keys = c_keywords();
608    keys.extend(vec![
609        ("class", "class"),
610        ("namespace", "namespace"),
611        ("public:", "public"),
612        ("private:", "private"),
613        ("protected:", "protected"),
614        ("virtual", "virtual"),
615        ("override", "override"),
616        ("template", "template"),
617        ("typename", "typename"),
618        ("new", "new"),
619        ("delete", "delete"),
620        ("this", "this"),
621        ("nullptr", "nullptr"),
622        ("constexpr", "constexpr"),
623        ("noexcept", "noexcept"),
624        ("friend", "friend"),
625        ("operator", "operator"),
626        ("explicit", "explicit"),
627        ("mutable", "mutable"),
628        ("using", "using"),
629        ("auto", "auto"),
630        ("decltype", "decltype"),
631        ("try", "try"),
632        ("catch", "catch"),
633        ("throw", "throw"),
634        ("#include", "include"),
635        ("std::", "std namespace"),
636        ("std::string", "string"),
637        ("std::vector", "vector"),
638        ("std::map", "map"),
639        ("std::cout", "cout"),
640        ("std::cin", "cin"),
641        ("std::unique_ptr", "unique ptr"),
642        ("std::shared_ptr", "shared ptr"),
643        ("std::make_unique", "make unique"),
644        ("std::make_shared", "make shared"),
645    ]);
646    keys
647}