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,
475 (",
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}