ricecoder_completion/
providers.rs

1/// Pluggable completion providers for language-specific behavior
2///
3/// # Architecture
4///
5/// This module provides language-specific completion providers that generate suggestions
6/// based on language keywords, patterns, and available symbols.
7///
8/// # Fallback Providers
9///
10/// **IMPORTANT**: These providers are now **fallback providers** used when external LSP servers
11/// are unavailable. For production-quality semantic completions, external LSP servers
12/// (rust-analyzer, tsserver, pylsp, etc.) should be configured and used instead.
13///
14/// ## When Fallback Providers Are Used
15///
16/// Fallback providers are used in the following scenarios:
17///
18/// 1. **External LSP Not Configured**: No external LSP server is configured for the language
19/// 2. **External LSP Unavailable**: The configured external LSP server is not installed or fails to start
20/// 3. **External LSP Timeout**: The external LSP server times out or becomes unresponsive
21/// 4. **Graceful Degradation**: When external LSP fails, the system falls back to internal providers
22///    to ensure users still get basic completions
23///
24/// ## Limitations of Fallback Providers
25///
26/// Fallback providers have significant limitations compared to external LSP servers:
27///
28/// - **No Type Inference**: Cannot infer types or resolve type information
29/// - **No Project Context**: Cannot access project configuration or dependencies
30/// - **Limited Scope Analysis**: Cannot determine variable scope or lifetime
31/// - **No Semantic Analysis**: Cannot perform semantic analysis or resolve references
32/// - **Keyword-Based Only**: Provide only keyword and pattern-based completions
33///
34/// ## Recommended Configuration
35///
36/// For best results, configure external LSP servers for your languages:
37///
38/// - **Rust**: Install and configure `rust-analyzer`
39/// - **TypeScript/JavaScript**: Install and configure `typescript-language-server`
40/// - **Python**: Install and configure `pylsp` or `pyright`
41/// - **Go**: Install and configure `gopls`
42/// - **Java**: Install and configure `jdtls`
43/// - **Kotlin**: Install and configure `kotlin-language-server`
44/// - **Dart**: Install and configure `dart-language-server`
45///
46/// See `https://github.com/moabualruz/ricecoder/wiki/External-LSP-Configuration.md` for configuration instructions.
47use crate::types::*;
48use async_trait::async_trait;
49
50/// Helper function to convert symbol kind to completion item kind
51fn symbol_kind_to_completion_kind(kind: SymbolKind) -> CompletionItemKind {
52    match kind {
53        SymbolKind::Variable => CompletionItemKind::Variable,
54        SymbolKind::Function => CompletionItemKind::Function,
55        SymbolKind::Type => CompletionItemKind::Class,
56        SymbolKind::Constant => CompletionItemKind::Constant,
57        SymbolKind::Module => CompletionItemKind::Module,
58        SymbolKind::Class => CompletionItemKind::Class,
59        SymbolKind::Struct => CompletionItemKind::Struct,
60        SymbolKind::Enum => CompletionItemKind::Enum,
61        SymbolKind::Interface => CompletionItemKind::Interface,
62        SymbolKind::Trait => CompletionItemKind::Interface,
63        SymbolKind::Method => CompletionItemKind::Method,
64        SymbolKind::Property => CompletionItemKind::Property,
65        SymbolKind::Field => CompletionItemKind::Field,
66        SymbolKind::Parameter => CompletionItemKind::Variable,
67        SymbolKind::Keyword => CompletionItemKind::Keyword,
68    }
69}
70
71/// Helper function to create a completion item from a symbol
72fn symbol_to_completion_item(symbol: &Symbol, score: f32) -> CompletionItem {
73    let mut item = CompletionItem::new(
74        symbol.name.clone(),
75        symbol_kind_to_completion_kind(symbol.kind),
76        symbol.name.clone(),
77    )
78    .with_score(score);
79
80    // Add type information as detail
81    if let Some(type_info) = &symbol.type_info {
82        item = item.with_detail(type_info.clone());
83    }
84
85    // Add documentation
86    if let Some(documentation) = &symbol.documentation {
87        item = item.with_documentation(documentation.clone());
88    }
89
90    item
91}
92
93/// Helper function to create snippet completions
94fn create_snippet_item(
95    label: &str,
96    template: &str,
97    description: &str,
98    score: f32,
99) -> CompletionItem {
100    CompletionItem::new(
101        label.to_string(),
102        CompletionItemKind::Snippet,
103        template.to_string(),
104    )
105    .with_detail(description.to_string())
106    .with_score(score)
107}
108
109/// Generic text-based completion provider (fallback for unconfigured languages)
110///
111/// This is a **fallback provider** used when no language-specific provider is available
112/// or when external LSP servers are not configured.
113///
114/// # Behavior
115///
116/// Generates completions from available symbols in the code context. This provider
117/// does not perform any language-specific analysis and is suitable only as a fallback.
118///
119/// # When Used
120///
121/// - No language-specific provider is registered
122/// - Language is not recognized
123/// - External LSP server is unavailable
124///
125/// # Limitations
126///
127/// - No language-specific keywords or patterns
128/// - No type inference or semantic analysis
129/// - Limited to available symbols in context
130/// - No project-aware completions
131///
132/// # Recommendation
133///
134/// For better completions, configure an external LSP server for your language.
135pub struct GenericTextProvider;
136
137#[async_trait]
138impl crate::engine::CompletionProvider for GenericTextProvider {
139    fn language(&self) -> &str {
140        "generic"
141    }
142
143    async fn generate_completions(
144        &self,
145        _code: &str,
146        _position: Position,
147        context: &CompletionContext,
148    ) -> CompletionResult<Vec<CompletionItem>> {
149        let mut completions = Vec::new();
150
151        // Generate completions from available symbols
152        for symbol in &context.available_symbols {
153            let item = symbol_to_completion_item(symbol, 0.5);
154            completions.push(item);
155        }
156
157        Ok(completions)
158    }
159}
160
161/// Rust-specific completion provider (fallback)
162///
163/// This is a **fallback provider** for Rust code when external LSP (rust-analyzer) is unavailable.
164///
165/// # Behavior
166///
167/// Generates Rust-specific completions including:
168/// - Rust keywords (fn, let, mut, const, struct, enum, trait, impl, etc.)
169/// - Rust-specific snippets (function templates, impl blocks, match expressions, etc.)
170/// - Rust traits and standard library types
171/// - Rust macros (println!, format!, vec!, etc.)
172/// - Derive attributes
173/// - Available symbols from code context
174///
175/// # When Used
176///
177/// - External LSP (rust-analyzer) is not configured
178/// - rust-analyzer is not installed or fails to start
179/// - rust-analyzer times out or becomes unresponsive
180///
181/// # Limitations
182///
183/// - No type inference or semantic analysis
184/// - Cannot resolve imports or dependencies
185/// - No project-aware completions
186/// - Cannot determine variable scope or lifetime
187/// - Limited to hardcoded keywords and patterns
188///
189/// # Recommended Configuration
190///
191/// For production-quality Rust completions, install and configure rust-analyzer:
192///
193/// ```bash
194/// rustup component add rust-analyzer
195/// ```
196///
197/// Then configure it in `lsp-servers.yaml`:
198///
199/// ```yaml
200/// servers:
201///   rust:
202///     - language: rust
203///       executable: rust-analyzer
204///       enabled: true
205/// ```
206///
207/// See `https://github.com/moabualruz/ricecoder/wiki/External-LSP-Configuration.md` for details.
208pub struct RustCompletionProvider;
209
210#[async_trait]
211impl crate::engine::CompletionProvider for RustCompletionProvider {
212    fn language(&self) -> &str {
213        "rust"
214    }
215
216    async fn generate_completions(
217        &self,
218        _code: &str,
219        _position: Position,
220        context: &CompletionContext,
221    ) -> CompletionResult<Vec<CompletionItem>> {
222        let mut completions = Vec::new();
223
224        // Add symbols from context first (higher priority)
225        for symbol in &context.available_symbols {
226            let mut item = CompletionItem::new(
227                symbol.name.clone(),
228                match symbol.kind {
229                    SymbolKind::Variable => CompletionItemKind::Variable,
230                    SymbolKind::Function => CompletionItemKind::Function,
231                    SymbolKind::Type => CompletionItemKind::Struct,
232                    SymbolKind::Constant => CompletionItemKind::Constant,
233                    SymbolKind::Module => CompletionItemKind::Module,
234                    SymbolKind::Class => CompletionItemKind::Struct,
235                    SymbolKind::Struct => CompletionItemKind::Struct,
236                    SymbolKind::Enum => CompletionItemKind::Enum,
237                    SymbolKind::Interface => CompletionItemKind::Trait,
238                    SymbolKind::Trait => CompletionItemKind::Trait,
239                    SymbolKind::Method => CompletionItemKind::Method,
240                    SymbolKind::Property => CompletionItemKind::Field,
241                    SymbolKind::Field => CompletionItemKind::Field,
242                    SymbolKind::Parameter => CompletionItemKind::Variable,
243                    SymbolKind::Keyword => CompletionItemKind::Keyword,
244                },
245                symbol.name.clone(),
246            )
247            .with_score(0.8);
248
249            // Add type information as detail
250            if let Some(type_info) = &symbol.type_info {
251                item = item.with_detail(type_info.clone());
252            }
253
254            // Add documentation
255            if let Some(documentation) = &symbol.documentation {
256                item = item.with_documentation(documentation.clone());
257            }
258
259            completions.push(item);
260        }
261
262        // Add Rust-specific keywords
263        let rust_keywords = vec![
264            ("fn", "Function declaration"),
265            ("let", "Variable binding"),
266            ("mut", "Mutable binding"),
267            ("const", "Constant declaration"),
268            ("static", "Static variable"),
269            ("struct", "Struct definition"),
270            ("enum", "Enum definition"),
271            ("trait", "Trait definition"),
272            ("impl", "Implementation block"),
273            ("pub", "Public visibility"),
274            ("mod", "Module declaration"),
275            ("use", "Import statement"),
276            ("match", "Pattern matching"),
277            ("if", "Conditional"),
278            ("else", "Else clause"),
279            ("for", "For loop"),
280            ("while", "While loop"),
281            ("loop", "Infinite loop"),
282            ("break", "Break statement"),
283            ("continue", "Continue statement"),
284            ("return", "Return statement"),
285            ("async", "Async function"),
286            ("await", "Await expression"),
287            ("unsafe", "Unsafe block"),
288            ("dyn", "Dynamic trait object"),
289            ("where", "Where clause"),
290            ("as", "Type casting"),
291        ];
292
293        for (keyword, description) in rust_keywords {
294            let item = CompletionItem::new(
295                keyword.to_string(),
296                CompletionItemKind::Keyword,
297                keyword.to_string(),
298            )
299            .with_detail(description.to_string())
300            .with_score(0.6);
301
302            completions.push(item);
303        }
304
305        // Add Rust-specific snippets
306        let rust_snippets = vec![
307            (
308                "fn_snippet",
309                "fn ${1:name}(${2:args}) {\n    ${3:body}\n}",
310                "Function template",
311            ),
312            (
313                "impl_snippet",
314                "impl ${1:Type} {\n    ${2:methods}\n}",
315                "Implementation block",
316            ),
317            (
318                "match_snippet",
319                "match ${1:expr} {\n    ${2:pattern} => ${3:result},\n}",
320                "Match expression",
321            ),
322            (
323                "for_snippet",
324                "for ${1:item} in ${2:iter} {\n    ${3:body}\n}",
325                "For loop",
326            ),
327            (
328                "while_snippet",
329                "while ${1:condition} {\n    ${2:body}\n}",
330                "While loop",
331            ),
332            (
333                "if_snippet",
334                "if ${1:condition} {\n    ${2:then}\n} else {\n    ${3:else}\n}",
335                "If-else block",
336            ),
337            (
338                "struct_snippet",
339                "struct ${1:Name} {\n    ${2:fields}\n}",
340                "Struct definition",
341            ),
342            (
343                "enum_snippet",
344                "enum ${1:Name} {\n    ${2:variants}\n}",
345                "Enum definition",
346            ),
347            (
348                "trait_snippet",
349                "trait ${1:Name} {\n    ${2:methods}\n}",
350                "Trait definition",
351            ),
352            ("closure_snippet", "|${1:args}| ${2:body}", "Closure"),
353        ];
354
355        for (label, template, description) in rust_snippets {
356            let item = create_snippet_item(label, template, description, 0.7);
357            completions.push(item);
358        }
359
360        // Add Rust-specific traits and macros
361        let rust_traits = vec![
362            (
363                "Debug",
364                "Debug trait for formatting",
365                CompletionItemKind::Trait,
366            ),
367            (
368                "Clone",
369                "Clone trait for copying",
370                CompletionItemKind::Trait,
371            ),
372            (
373                "Copy",
374                "Copy trait for stack copying",
375                CompletionItemKind::Trait,
376            ),
377            (
378                "Default",
379                "Default trait for default values",
380                CompletionItemKind::Trait,
381            ),
382            (
383                "Display",
384                "Display trait for formatting",
385                CompletionItemKind::Trait,
386            ),
387            (
388                "Iterator",
389                "Iterator trait for iteration",
390                CompletionItemKind::Trait,
391            ),
392            (
393                "IntoIterator",
394                "IntoIterator trait for conversion",
395                CompletionItemKind::Trait,
396            ),
397            (
398                "From",
399                "From trait for conversion",
400                CompletionItemKind::Trait,
401            ),
402            (
403                "Into",
404                "Into trait for conversion",
405                CompletionItemKind::Trait,
406            ),
407            (
408                "AsRef",
409                "AsRef trait for borrowing",
410                CompletionItemKind::Trait,
411            ),
412            (
413                "AsMut",
414                "AsMut trait for mutable borrowing",
415                CompletionItemKind::Trait,
416            ),
417            (
418                "Deref",
419                "Deref trait for dereferencing",
420                CompletionItemKind::Trait,
421            ),
422            ("Drop", "Drop trait for cleanup", CompletionItemKind::Trait),
423            ("Eq", "Eq trait for equality", CompletionItemKind::Trait),
424            (
425                "PartialEq",
426                "PartialEq trait for partial equality",
427                CompletionItemKind::Trait,
428            ),
429            ("Ord", "Ord trait for ordering", CompletionItemKind::Trait),
430            (
431                "PartialOrd",
432                "PartialOrd trait for partial ordering",
433                CompletionItemKind::Trait,
434            ),
435            ("Hash", "Hash trait for hashing", CompletionItemKind::Trait),
436        ];
437
438        for (name, description, kind) in rust_traits {
439            let item = CompletionItem::new(name.to_string(), kind, name.to_string())
440                .with_detail(description.to_string())
441                .with_score(0.75);
442            completions.push(item);
443        }
444
445        // Add Rust-specific macros
446        let rust_macros = vec![
447            ("println!", "Print with newline"),
448            ("print!", "Print without newline"),
449            ("eprintln!", "Print to stderr with newline"),
450            ("eprint!", "Print to stderr without newline"),
451            ("format!", "Format string"),
452            ("panic!", "Panic with message"),
453            ("assert!", "Assert condition"),
454            ("assert_eq!", "Assert equality"),
455            ("assert_ne!", "Assert inequality"),
456            ("debug_assert!", "Debug assert"),
457            ("vec!", "Create vector"),
458            ("map!", "Map macro"),
459            ("include!", "Include file"),
460            ("include_str!", "Include string"),
461            ("include_bytes!", "Include bytes"),
462            ("concat!", "Concatenate strings"),
463            ("stringify!", "Stringify expression"),
464            ("env!", "Get environment variable"),
465            ("cfg!", "Check configuration"),
466            ("compile_error!", "Compile error"),
467        ];
468
469        for (macro_name, description) in rust_macros {
470            let item = CompletionItem::new(
471                macro_name.to_string(),
472                CompletionItemKind::Operator,
473                macro_name.to_string(),
474            )
475            .with_detail(description.to_string())
476            .with_score(0.7);
477            completions.push(item);
478        }
479
480        // Add Rust-specific derive attributes
481        let rust_derives = vec![
482            ("Debug", "Derive Debug trait"),
483            ("Clone", "Derive Clone trait"),
484            ("Copy", "Derive Copy trait"),
485            ("Default", "Derive Default trait"),
486            ("PartialEq", "Derive PartialEq trait"),
487            ("Eq", "Derive Eq trait"),
488            ("PartialOrd", "Derive PartialOrd trait"),
489            ("Ord", "Derive Ord trait"),
490            ("Hash", "Derive Hash trait"),
491        ];
492
493        for (derive_name, description) in rust_derives {
494            let item = CompletionItem::new(
495                format!("#[derive({})]", derive_name),
496                CompletionItemKind::Keyword,
497                format!("#[derive({})]", derive_name),
498            )
499            .with_detail(description.to_string())
500            .with_score(0.65);
501            completions.push(item);
502        }
503
504        Ok(completions)
505    }
506}
507
508/// TypeScript-specific completion provider (fallback)
509///
510/// This is a **fallback provider** for TypeScript/JavaScript code when external LSP
511/// (typescript-language-server) is unavailable.
512///
513/// # Behavior
514///
515/// Generates TypeScript-specific completions including:
516/// - TypeScript keywords (function, const, let, class, interface, type, enum, etc.)
517/// - TypeScript-specific snippets (function templates, class definitions, etc.)
518/// - TypeScript utility types (Record, Partial, Required, Pick, Omit, etc.)
519/// - TypeScript decorators
520/// - Generic type patterns
521/// - Available symbols from code context
522///
523/// # When Used
524///
525/// - External LSP (typescript-language-server) is not configured
526/// - typescript-language-server is not installed or fails to start
527/// - typescript-language-server times out or becomes unresponsive
528///
529/// # Limitations
530///
531/// - No type inference or semantic analysis
532/// - Cannot resolve imports or dependencies
533/// - No project-aware completions
534/// - Cannot determine variable scope or type information
535/// - Limited to hardcoded keywords and patterns
536///
537/// # Recommended Configuration
538///
539/// For production-quality TypeScript completions, install and configure typescript-language-server:
540///
541/// ```bash
542/// npm install -g typescript-language-server typescript
543/// ```
544///
545/// Then configure it in `lsp-servers.yaml`:
546///
547/// ```yaml
548/// servers:
549///   typescript:
550///     - language: typescript
551///       executable: typescript-language-server
552///       args: ["--stdio"]
553///       enabled: true
554/// ```
555///
556/// See `https://github.com/moabualruz/ricecoder/wiki/External-LSP-Configuration.md` for details.
557pub struct TypeScriptCompletionProvider;
558
559#[async_trait]
560impl crate::engine::CompletionProvider for TypeScriptCompletionProvider {
561    fn language(&self) -> &str {
562        "typescript"
563    }
564
565    async fn generate_completions(
566        &self,
567        _code: &str,
568        _position: Position,
569        context: &CompletionContext,
570    ) -> CompletionResult<Vec<CompletionItem>> {
571        let mut completions = Vec::new();
572
573        // Add symbols from context first (higher priority)
574        for symbol in &context.available_symbols {
575            let mut item = CompletionItem::new(
576                symbol.name.clone(),
577                match symbol.kind {
578                    SymbolKind::Variable => CompletionItemKind::Variable,
579                    SymbolKind::Function => CompletionItemKind::Function,
580                    SymbolKind::Type => CompletionItemKind::Interface,
581                    SymbolKind::Constant => CompletionItemKind::Constant,
582                    SymbolKind::Module => CompletionItemKind::Module,
583                    SymbolKind::Class => CompletionItemKind::Class,
584                    SymbolKind::Struct => CompletionItemKind::Class,
585                    SymbolKind::Enum => CompletionItemKind::Enum,
586                    SymbolKind::Interface => CompletionItemKind::Interface,
587                    SymbolKind::Trait => CompletionItemKind::Interface,
588                    SymbolKind::Method => CompletionItemKind::Method,
589                    SymbolKind::Property => CompletionItemKind::Property,
590                    SymbolKind::Field => CompletionItemKind::Field,
591                    SymbolKind::Parameter => CompletionItemKind::Variable,
592                    SymbolKind::Keyword => CompletionItemKind::Keyword,
593                },
594                symbol.name.clone(),
595            )
596            .with_score(0.8);
597
598            // Add type information as detail
599            if let Some(type_info) = &symbol.type_info {
600                item = item.with_detail(type_info.clone());
601            }
602
603            // Add documentation
604            if let Some(documentation) = &symbol.documentation {
605                item = item.with_documentation(documentation.clone());
606            }
607
608            completions.push(item);
609        }
610
611        // Add TypeScript-specific keywords
612        let ts_keywords = vec![
613            ("function", "Function declaration"),
614            ("const", "Constant declaration"),
615            ("let", "Block-scoped variable"),
616            ("var", "Function-scoped variable"),
617            ("class", "Class definition"),
618            ("interface", "Interface definition"),
619            ("type", "Type alias"),
620            ("enum", "Enum definition"),
621            ("namespace", "Namespace"),
622            ("module", "Module"),
623            ("export", "Export declaration"),
624            ("import", "Import statement"),
625            ("async", "Async function"),
626            ("await", "Await expression"),
627            ("if", "Conditional"),
628            ("else", "Else clause"),
629            ("for", "For loop"),
630            ("while", "While loop"),
631            ("do", "Do-while loop"),
632            ("switch", "Switch statement"),
633            ("case", "Case clause"),
634            ("default", "Default clause"),
635            ("break", "Break statement"),
636            ("continue", "Continue statement"),
637            ("return", "Return statement"),
638            ("throw", "Throw statement"),
639            ("try", "Try block"),
640            ("catch", "Catch block"),
641            ("finally", "Finally block"),
642            ("new", "New instance"),
643            ("this", "This reference"),
644            ("super", "Super reference"),
645            ("extends", "Extends clause"),
646            ("implements", "Implements clause"),
647            ("public", "Public modifier"),
648            ("private", "Private modifier"),
649            ("protected", "Protected modifier"),
650            ("readonly", "Readonly modifier"),
651            ("static", "Static modifier"),
652            ("abstract", "Abstract modifier"),
653            ("declare", "Declare statement"),
654            ("keyof", "Keyof operator"),
655            ("typeof", "Typeof operator"),
656            ("instanceof", "Instanceof operator"),
657            ("in", "In operator"),
658            ("of", "Of operator"),
659        ];
660
661        for (keyword, description) in ts_keywords {
662            let item = CompletionItem::new(
663                keyword.to_string(),
664                CompletionItemKind::Keyword,
665                keyword.to_string(),
666            )
667            .with_detail(description.to_string())
668            .with_score(0.6);
669
670            completions.push(item);
671        }
672
673        // Add TypeScript-specific snippets
674        let ts_snippets = vec![
675            ("fn_snippet", "function ${1:name}(${2:args}): ${3:ReturnType} {\n    ${4:body}\n}", "Function template"),
676            ("arrow_fn_snippet", "const ${1:name} = (${2:args}): ${3:ReturnType} => {\n    ${4:body}\n}", "Arrow function"),
677            ("class_snippet", "class ${1:Name} {\n    constructor(${2:args}) {\n        ${3:init}\n    }\n    ${4:methods}\n}", "Class definition"),
678            ("interface_snippet", "interface ${1:Name} {\n    ${2:properties}\n}", "Interface definition"),
679            ("for_snippet", "for (let ${1:i} = 0; ${1:i} < ${2:length}; ${1:i}++) {\n    ${3:body}\n}", "For loop"),
680            ("for_of_snippet", "for (const ${1:item} of ${2:iterable}) {\n    ${3:body}\n}", "For-of loop"),
681            ("while_snippet", "while (${1:condition}) {\n    ${2:body}\n}", "While loop"),
682            ("if_snippet", "if (${1:condition}) {\n    ${2:then}\n} else {\n    ${3:else}\n}", "If-else block"),
683            ("try_snippet", "try {\n    ${1:body}\n} catch (${2:error}) {\n    ${3:handler}\n}", "Try-catch block"),
684            ("async_fn_snippet", "async function ${1:name}(${2:args}): Promise<${3:Type}> {\n    ${4:body}\n}", "Async function"),
685        ];
686
687        for (label, template, description) in ts_snippets {
688            let item = create_snippet_item(label, template, description, 0.7);
689            completions.push(item);
690        }
691
692        // Add TypeScript-specific interfaces and types
693        let ts_interfaces = vec![
694            (
695                "Record",
696                "Record type for key-value pairs",
697                CompletionItemKind::Interface,
698            ),
699            (
700                "Partial",
701                "Partial type for optional properties",
702                CompletionItemKind::Interface,
703            ),
704            (
705                "Required",
706                "Required type for mandatory properties",
707                CompletionItemKind::Interface,
708            ),
709            (
710                "Readonly",
711                "Readonly type for immutable properties",
712                CompletionItemKind::Interface,
713            ),
714            (
715                "Pick",
716                "Pick type for selecting properties",
717                CompletionItemKind::Interface,
718            ),
719            (
720                "Omit",
721                "Omit type for excluding properties",
722                CompletionItemKind::Interface,
723            ),
724            (
725                "Exclude",
726                "Exclude type for union exclusion",
727                CompletionItemKind::Interface,
728            ),
729            (
730                "Extract",
731                "Extract type for union extraction",
732                CompletionItemKind::Interface,
733            ),
734            (
735                "NonNullable",
736                "NonNullable type for non-null values",
737                CompletionItemKind::Interface,
738            ),
739            (
740                "Parameters",
741                "Parameters type for function parameters",
742                CompletionItemKind::Interface,
743            ),
744            (
745                "ReturnType",
746                "ReturnType type for function return type",
747                CompletionItemKind::Interface,
748            ),
749            (
750                "InstanceType",
751                "InstanceType type for class instances",
752                CompletionItemKind::Interface,
753            ),
754            (
755                "Awaited",
756                "Awaited type for promise resolution",
757                CompletionItemKind::Interface,
758            ),
759        ];
760
761        for (name, description, kind) in ts_interfaces {
762            let item = CompletionItem::new(name.to_string(), kind, name.to_string())
763                .with_detail(description.to_string())
764                .with_score(0.75);
765            completions.push(item);
766        }
767
768        // Add TypeScript-specific decorators
769        let ts_decorators = vec![
770            ("@deprecated", "Mark as deprecated"),
771            ("@sealed", "Seal class"),
772            ("@frozen", "Freeze class"),
773            ("@readonly", "Mark property as readonly"),
774            ("@validate", "Validate input"),
775            ("@memoize", "Memoize function"),
776            ("@throttle", "Throttle function"),
777            ("@debounce", "Debounce function"),
778            ("@observable", "Make observable"),
779            ("@computed", "Computed property"),
780        ];
781
782        for (decorator_name, description) in ts_decorators {
783            let item = CompletionItem::new(
784                decorator_name.to_string(),
785                CompletionItemKind::Keyword,
786                decorator_name.to_string(),
787            )
788            .with_detail(description.to_string())
789            .with_score(0.65);
790            completions.push(item);
791        }
792
793        // Add TypeScript generic patterns
794        let ts_generics = vec![
795            ("Array<T>", "Generic array type"),
796            ("Promise<T>", "Generic promise type"),
797            ("Map<K, V>", "Generic map type"),
798            ("Set<T>", "Generic set type"),
799            ("Record<K, V>", "Generic record type"),
800            ("Tuple<T, U>", "Generic tuple type"),
801        ];
802
803        for (generic_name, description) in ts_generics {
804            let item = CompletionItem::new(
805                generic_name.to_string(),
806                CompletionItemKind::TypeParameter,
807                generic_name.to_string(),
808            )
809            .with_detail(description.to_string())
810            .with_score(0.7);
811            completions.push(item);
812        }
813
814        Ok(completions)
815    }
816}
817
818/// Python-specific completion provider (fallback)
819///
820/// This is a **fallback provider** for Python code when external LSP (pylsp) is unavailable.
821///
822/// # Behavior
823///
824/// Generates Python-specific completions including:
825/// - Python keywords (def, class, if, for, while, try, except, etc.)
826/// - Python-specific snippets (function definitions, class definitions, etc.)
827/// - Python decorators (@property, @staticmethod, @classmethod, etc.)
828/// - Python type hints (List, Dict, Set, Optional, Union, etc.)
829/// - Python context managers (open, lock, transaction, etc.)
830/// - Available symbols from code context
831///
832/// # When Used
833///
834/// - External LSP (pylsp) is not configured
835/// - pylsp is not installed or fails to start
836/// - pylsp times out or becomes unresponsive
837///
838/// # Limitations
839///
840/// - No type inference or semantic analysis
841/// - Cannot resolve imports or dependencies
842/// - No project-aware completions
843/// - Cannot determine variable scope or type information
844/// - Limited to hardcoded keywords and patterns
845///
846/// # Recommended Configuration
847///
848/// For production-quality Python completions, install and configure pylsp:
849///
850/// ```bash
851/// pip install python-lsp-server
852/// ```
853///
854/// Then configure it in `lsp-servers.yaml`:
855///
856/// ```yaml
857/// servers:
858///   python:
859///     - language: python
860///       executable: pylsp
861///       enabled: true
862/// ```
863///
864/// See `https://github.com/moabualruz/ricecoder/wiki/External-LSP-Configuration.md` for details.
865pub struct PythonCompletionProvider;
866
867#[async_trait]
868impl crate::engine::CompletionProvider for PythonCompletionProvider {
869    fn language(&self) -> &str {
870        "python"
871    }
872
873    async fn generate_completions(
874        &self,
875        _code: &str,
876        _position: Position,
877        context: &CompletionContext,
878    ) -> CompletionResult<Vec<CompletionItem>> {
879        let mut completions = Vec::new();
880
881        // Add symbols from context first (higher priority)
882        for symbol in &context.available_symbols {
883            let mut item = CompletionItem::new(
884                symbol.name.clone(),
885                match symbol.kind {
886                    SymbolKind::Variable => CompletionItemKind::Variable,
887                    SymbolKind::Function => CompletionItemKind::Function,
888                    SymbolKind::Type => CompletionItemKind::Class,
889                    SymbolKind::Constant => CompletionItemKind::Constant,
890                    SymbolKind::Module => CompletionItemKind::Module,
891                    SymbolKind::Class => CompletionItemKind::Class,
892                    SymbolKind::Struct => CompletionItemKind::Class,
893                    SymbolKind::Enum => CompletionItemKind::Enum,
894                    SymbolKind::Interface => CompletionItemKind::Interface,
895                    SymbolKind::Trait => CompletionItemKind::Interface,
896                    SymbolKind::Method => CompletionItemKind::Method,
897                    SymbolKind::Property => CompletionItemKind::Property,
898                    SymbolKind::Field => CompletionItemKind::Field,
899                    SymbolKind::Parameter => CompletionItemKind::Variable,
900                    SymbolKind::Keyword => CompletionItemKind::Keyword,
901                },
902                symbol.name.clone(),
903            )
904            .with_score(0.8);
905
906            // Add type information as detail
907            if let Some(type_info) = &symbol.type_info {
908                item = item.with_detail(type_info.clone());
909            }
910
911            // Add documentation
912            if let Some(documentation) = &symbol.documentation {
913                item = item.with_documentation(documentation.clone());
914            }
915
916            completions.push(item);
917        }
918
919        // Add Python-specific keywords
920        let py_keywords = vec![
921            ("def", "Function definition"),
922            ("class", "Class definition"),
923            ("if", "Conditional"),
924            ("elif", "Else-if clause"),
925            ("else", "Else clause"),
926            ("for", "For loop"),
927            ("while", "While loop"),
928            ("break", "Break statement"),
929            ("continue", "Continue statement"),
930            ("return", "Return statement"),
931            ("yield", "Yield statement"),
932            ("import", "Import statement"),
933            ("from", "From import"),
934            ("as", "Alias"),
935            ("try", "Try block"),
936            ("except", "Except block"),
937            ("finally", "Finally block"),
938            ("raise", "Raise exception"),
939            ("with", "Context manager"),
940            ("assert", "Assert statement"),
941            ("pass", "Pass statement"),
942            ("del", "Delete statement"),
943            ("lambda", "Lambda function"),
944            ("and", "Logical and"),
945            ("or", "Logical or"),
946            ("not", "Logical not"),
947            ("in", "In operator"),
948            ("is", "Is operator"),
949            ("None", "None value"),
950            ("True", "True value"),
951            ("False", "False value"),
952            ("async", "Async function"),
953            ("await", "Await expression"),
954            ("global", "Global declaration"),
955            ("nonlocal", "Nonlocal declaration"),
956        ];
957
958        for (keyword, description) in py_keywords {
959            let item = CompletionItem::new(
960                keyword.to_string(),
961                CompletionItemKind::Keyword,
962                keyword.to_string(),
963            )
964            .with_detail(description.to_string())
965            .with_score(0.6);
966
967            completions.push(item);
968        }
969
970        // Add Python-specific snippets
971        let py_snippets = vec![
972            ("def_snippet", "def ${1:name}(${2:args}):\n    ${3:body}", "Function definition"),
973            ("class_snippet", "class ${1:Name}:\n    def __init__(self, ${2:args}):\n        ${3:init}\n    ${4:methods}", "Class definition"),
974            ("for_snippet", "for ${1:item} in ${2:iterable}:\n    ${3:body}", "For loop"),
975            ("while_snippet", "while ${1:condition}:\n    ${2:body}", "While loop"),
976            ("if_snippet", "if ${1:condition}:\n    ${2:then}\nelse:\n    ${3:else}", "If-else block"),
977            ("try_snippet", "try:\n    ${1:body}\nexcept ${2:Exception}:\n    ${3:handler}", "Try-except block"),
978            ("with_snippet", "with ${1:context} as ${2:var}:\n    ${3:body}", "Context manager"),
979            ("lambda_snippet", "lambda ${1:args}: ${2:expr}", "Lambda function"),
980            ("list_comp_snippet", "[${1:expr} for ${2:item} in ${3:iterable}]", "List comprehension"),
981            ("dict_comp_snippet", "{${1:key}: ${2:value} for ${3:item} in ${4:iterable}}", "Dictionary comprehension"),
982        ];
983
984        for (label, template, description) in py_snippets {
985            let item = create_snippet_item(label, template, description, 0.7);
986            completions.push(item);
987        }
988
989        // Add Python-specific decorators
990        let py_decorators = vec![
991            ("@property", "Property decorator for getters"),
992            ("@staticmethod", "Static method decorator"),
993            ("@classmethod", "Class method decorator"),
994            ("@abstractmethod", "Abstract method decorator"),
995            ("@deprecated", "Deprecated decorator"),
996            ("@lru_cache", "LRU cache decorator"),
997            ("@wraps", "Wraps decorator for decorators"),
998            ("@contextmanager", "Context manager decorator"),
999            ("@dataclass", "Dataclass decorator"),
1000            ("@enum.unique", "Unique enum decorator"),
1001        ];
1002
1003        for (decorator_name, description) in py_decorators {
1004            let item = CompletionItem::new(
1005                decorator_name.to_string(),
1006                CompletionItemKind::Keyword,
1007                decorator_name.to_string(),
1008            )
1009            .with_detail(description.to_string())
1010            .with_score(0.65);
1011            completions.push(item);
1012        }
1013
1014        // Add Python-specific type hints
1015        let py_type_hints = vec![
1016            ("List[T]", "List type hint"),
1017            ("Dict[K, V]", "Dictionary type hint"),
1018            ("Set[T]", "Set type hint"),
1019            ("Tuple[T, ...]", "Tuple type hint"),
1020            ("Optional[T]", "Optional type hint"),
1021            ("Union[T, U]", "Union type hint"),
1022            ("Any", "Any type hint"),
1023            ("Callable[[T], U]", "Callable type hint"),
1024            ("Iterator[T]", "Iterator type hint"),
1025            ("Generator[T, U, V]", "Generator type hint"),
1026            ("Iterable[T]", "Iterable type hint"),
1027            ("Sequence[T]", "Sequence type hint"),
1028            ("Mapping[K, V]", "Mapping type hint"),
1029            ("TypeVar", "Type variable"),
1030            ("Generic", "Generic base class"),
1031        ];
1032
1033        for (type_hint, description) in py_type_hints {
1034            let item = CompletionItem::new(
1035                type_hint.to_string(),
1036                CompletionItemKind::TypeParameter,
1037                type_hint.to_string(),
1038            )
1039            .with_detail(description.to_string())
1040            .with_score(0.7);
1041            completions.push(item);
1042        }
1043
1044        // Add Python-specific context managers
1045        let py_context_managers = vec![
1046            ("open()", "File context manager"),
1047            ("lock", "Lock context manager"),
1048            ("pool", "Connection pool context manager"),
1049            ("transaction", "Database transaction context manager"),
1050            (
1051                "tempfile.TemporaryDirectory()",
1052                "Temporary directory context manager",
1053            ),
1054            (
1055                "tempfile.NamedTemporaryFile()",
1056                "Temporary file context manager",
1057            ),
1058            (
1059                "contextlib.suppress()",
1060                "Suppress exceptions context manager",
1061            ),
1062            (
1063                "contextlib.redirect_stdout()",
1064                "Redirect stdout context manager",
1065            ),
1066            (
1067                "contextlib.redirect_stderr()",
1068                "Redirect stderr context manager",
1069            ),
1070        ];
1071
1072        for (cm_name, description) in py_context_managers {
1073            let item = CompletionItem::new(
1074                cm_name.to_string(),
1075                CompletionItemKind::Function,
1076                cm_name.to_string(),
1077            )
1078            .with_detail(description.to_string())
1079            .with_score(0.65);
1080            completions.push(item);
1081        }
1082
1083        Ok(completions)
1084    }
1085}
1086
1087/// Go-specific completion provider (fallback)
1088///
1089/// This is a **fallback provider** for Go code when external LSP (gopls) is unavailable.
1090///
1091/// # Behavior
1092///
1093/// Generates Go-specific completions including:
1094/// - Go keywords (package, import, func, const, var, type, struct, interface, etc.)
1095/// - Go-specific snippets (function templates, interface definitions, etc.)
1096/// - Go built-in functions (make, new, append, copy, delete, len, cap, etc.)
1097/// - Available symbols from code context
1098///
1099/// # When Used
1100///
1101/// - External LSP (gopls) is not configured
1102/// - gopls is not installed or fails to start
1103/// - gopls times out or becomes unresponsive
1104///
1105/// # Limitations
1106///
1107/// - No type inference or semantic analysis
1108/// - Cannot resolve imports or dependencies
1109/// - No project-aware completions
1110/// - Cannot determine variable scope or type information
1111/// - Limited to hardcoded keywords and patterns
1112///
1113/// # Recommended Configuration
1114///
1115/// For production-quality Go completions, install and configure gopls:
1116///
1117/// ```bash
1118/// go install github.com/golang/tools/gopls@latest
1119/// ```
1120///
1121/// Then configure it in `lsp-servers.yaml`:
1122///
1123/// ```yaml
1124/// servers:
1125///   go:
1126///     - language: go
1127///       executable: gopls
1128///       args: ["serve"]
1129///       enabled: true
1130/// ```
1131///
1132/// See `https://github.com/moabualruz/ricecoder/wiki/External-LSP-Configuration.md` for details.
1133pub struct GoCompletionProvider;
1134
1135#[async_trait]
1136impl crate::engine::CompletionProvider for GoCompletionProvider {
1137    fn language(&self) -> &str {
1138        "go"
1139    }
1140
1141    async fn generate_completions(
1142        &self,
1143        _code: &str,
1144        _position: Position,
1145        context: &CompletionContext,
1146    ) -> CompletionResult<Vec<CompletionItem>> {
1147        let mut completions = Vec::new();
1148
1149        // Add symbols from context
1150        for symbol in &context.available_symbols {
1151            let item = symbol_to_completion_item(symbol, 0.8);
1152            completions.push(item);
1153        }
1154
1155        // Add Go-specific keywords
1156        let go_keywords = vec![
1157            ("package", "Package declaration"),
1158            ("import", "Import statement"),
1159            ("func", "Function declaration"),
1160            ("const", "Constant declaration"),
1161            ("var", "Variable declaration"),
1162            ("type", "Type declaration"),
1163            ("struct", "Struct definition"),
1164            ("interface", "Interface definition"),
1165            ("defer", "Defer statement"),
1166            ("go", "Goroutine"),
1167            ("chan", "Channel"),
1168            ("select", "Select statement"),
1169            ("case", "Case clause"),
1170            ("default", "Default clause"),
1171            ("if", "Conditional"),
1172            ("else", "Else clause"),
1173            ("for", "For loop"),
1174            ("range", "Range keyword"),
1175            ("break", "Break statement"),
1176            ("continue", "Continue statement"),
1177            ("return", "Return statement"),
1178            ("fallthrough", "Fallthrough statement"),
1179            ("switch", "Switch statement"),
1180            ("goto", "Goto statement"),
1181            ("map", "Map type"),
1182            ("make", "Make function"),
1183            ("new", "New function"),
1184            ("append", "Append function"),
1185            ("copy", "Copy function"),
1186            ("delete", "Delete function"),
1187            ("len", "Length function"),
1188            ("cap", "Capacity function"),
1189            ("close", "Close function"),
1190            ("panic", "Panic function"),
1191            ("recover", "Recover function"),
1192        ];
1193
1194        for (keyword, description) in go_keywords {
1195            let item = CompletionItem::new(
1196                keyword.to_string(),
1197                CompletionItemKind::Keyword,
1198                keyword.to_string(),
1199            )
1200            .with_detail(description.to_string())
1201            .with_score(0.6);
1202            completions.push(item);
1203        }
1204
1205        // Add Go-specific snippets
1206        let go_snippets = vec![
1207            ("func_snippet", "func ${1:name}(${2:params}) ${3:returnType} {\n    ${4:body}\n}", "Function template"),
1208            ("interface_snippet", "type ${1:Name} interface {\n    ${2:methods}\n}", "Interface definition"),
1209            ("struct_snippet", "type ${1:Name} struct {\n    ${2:fields}\n}", "Struct definition"),
1210            ("for_snippet", "for ${1:i} := 0; ${1:i} < ${2:n}; ${1:i}++ {\n    ${3:body}\n}", "For loop"),
1211            ("for_range_snippet", "for ${1:key}, ${2:value} := range ${3:collection} {\n    ${4:body}\n}", "For-range loop"),
1212            ("if_err_snippet", "if err != nil {\n    ${1:handle error}\n}", "Error handling"),
1213            ("defer_snippet", "defer ${1:function}()", "Defer statement"),
1214            ("goroutine_snippet", "go ${1:function}()", "Goroutine"),
1215            ("channel_snippet", "ch := make(chan ${1:Type})\ngo func() {\n    ch <- ${2:value}\n}()\n${3:result} := <-ch", "Channel pattern"),
1216            ("select_snippet", "select {\ncase ${1:case1}:\n    ${2:body1}\ncase ${3:case2}:\n    ${4:body2}\ndefault:\n    ${5:default}\n}", "Select statement"),
1217        ];
1218
1219        for (label, template, description) in go_snippets {
1220            let item = create_snippet_item(label, template, description, 0.7);
1221            completions.push(item);
1222        }
1223
1224        Ok(completions)
1225    }
1226}
1227
1228/// Java-specific completion provider (fallback)
1229///
1230/// This is a **fallback provider** for Java code when external LSP (jdtls) is unavailable.
1231///
1232/// # Behavior
1233///
1234/// Generates Java-specific completions including:
1235/// - Java keywords (abstract, class, interface, public, private, static, etc.)
1236/// - Java-specific snippets (class declarations, method definitions, etc.)
1237/// - Java primitive types (int, long, double, boolean, etc.)
1238/// - Available symbols from code context
1239///
1240/// # When Used
1241///
1242/// - External LSP (jdtls) is not configured
1243/// - jdtls is not installed or fails to start
1244/// - jdtls times out or becomes unresponsive
1245///
1246/// # Limitations
1247///
1248/// - No type inference or semantic analysis
1249/// - Cannot resolve imports or dependencies
1250/// - No project-aware completions
1251/// - Cannot determine variable scope or type information
1252/// - Limited to hardcoded keywords and patterns
1253///
1254/// # Recommended Configuration
1255///
1256/// For production-quality Java completions, install and configure jdtls:
1257///
1258/// ```bash
1259/// # Download and install Eclipse JDT Language Server
1260/// # See: https://github.com/eclipse/eclipse.jdt.ls
1261/// ```
1262///
1263/// Then configure it in `lsp-servers.yaml`:
1264///
1265/// ```yaml
1266/// servers:
1267///   java:
1268///     - language: java
1269///       executable: jdtls
1270///       enabled: true
1271/// ```
1272///
1273/// See `https://github.com/moabualruz/ricecoder/wiki/External-LSP-Configuration.md` for details.
1274pub struct JavaCompletionProvider;
1275
1276#[async_trait]
1277impl crate::engine::CompletionProvider for JavaCompletionProvider {
1278    fn language(&self) -> &str {
1279        "java"
1280    }
1281
1282    async fn generate_completions(
1283        &self,
1284        _code: &str,
1285        _position: Position,
1286        context: &CompletionContext,
1287    ) -> CompletionResult<Vec<CompletionItem>> {
1288        let mut completions = Vec::new();
1289
1290        // Add symbols from context
1291        for symbol in &context.available_symbols {
1292            let item = symbol_to_completion_item(symbol, 0.8);
1293            completions.push(item);
1294        }
1295
1296        // Add Java-specific keywords
1297        let java_keywords = vec![
1298            ("abstract", "Abstract modifier"),
1299            ("assert", "Assert statement"),
1300            ("boolean", "Boolean type"),
1301            ("break", "Break statement"),
1302            ("byte", "Byte type"),
1303            ("case", "Case clause"),
1304            ("catch", "Catch block"),
1305            ("char", "Char type"),
1306            ("class", "Class definition"),
1307            ("const", "Const keyword"),
1308            ("continue", "Continue statement"),
1309            ("default", "Default clause"),
1310            ("do", "Do-while loop"),
1311            ("double", "Double type"),
1312            ("else", "Else clause"),
1313            ("enum", "Enum definition"),
1314            ("extends", "Extends keyword"),
1315            ("final", "Final modifier"),
1316            ("finally", "Finally block"),
1317            ("float", "Float type"),
1318            ("for", "For loop"),
1319            ("if", "Conditional"),
1320            ("implements", "Implements keyword"),
1321            ("import", "Import statement"),
1322            ("instanceof", "Instanceof operator"),
1323            ("int", "Int type"),
1324            ("interface", "Interface definition"),
1325            ("long", "Long type"),
1326            ("native", "Native modifier"),
1327            ("new", "New keyword"),
1328            ("package", "Package declaration"),
1329            ("private", "Private modifier"),
1330            ("protected", "Protected modifier"),
1331            ("public", "Public modifier"),
1332            ("return", "Return statement"),
1333            ("short", "Short type"),
1334            ("static", "Static modifier"),
1335            ("strictfp", "Strictfp modifier"),
1336            ("super", "Super keyword"),
1337            ("switch", "Switch statement"),
1338            ("synchronized", "Synchronized modifier"),
1339            ("this", "This keyword"),
1340            ("throw", "Throw statement"),
1341            ("throws", "Throws clause"),
1342            ("transient", "Transient modifier"),
1343            ("try", "Try block"),
1344            ("void", "Void type"),
1345            ("volatile", "Volatile modifier"),
1346            ("while", "While loop"),
1347        ];
1348
1349        for (keyword, description) in java_keywords {
1350            let item = CompletionItem::new(
1351                keyword.to_string(),
1352                CompletionItemKind::Keyword,
1353                keyword.to_string(),
1354            )
1355            .with_detail(description.to_string())
1356            .with_score(0.6);
1357            completions.push(item);
1358        }
1359
1360        // Add Java-specific snippets
1361        let java_snippets = vec![
1362            ("class_snippet", "public class ${1:ClassName} {\n    ${2:body}\n}", "Class declaration"),
1363            ("interface_snippet", "public interface ${1:InterfaceName} {\n    ${2:methods}\n}", "Interface definition"),
1364            ("method_snippet", "public ${1:returnType} ${2:methodName}(${3:params}) {\n    ${4:body}\n}", "Method declaration"),
1365            ("constructor_snippet", "public ${1:ClassName}(${2:params}) {\n    ${3:body}\n}", "Constructor"),
1366            ("for_snippet", "for (int ${1:i} = 0; ${1:i} < ${2:n}; ${1:i}++) {\n    ${3:body}\n}", "For loop"),
1367            ("for_each_snippet", "for (${1:Type} ${2:item} : ${3:collection}) {\n    ${4:body}\n}", "For-each loop"),
1368            ("try_catch_snippet", "try {\n    ${1:code}\n} catch (${2:Exception} e) {\n    ${3:handle}\n}", "Try-catch block"),
1369            ("if_snippet", "if (${1:condition}) {\n    ${2:then}\n} else {\n    ${3:else}\n}", "If-else statement"),
1370            ("switch_snippet", "switch (${1:expr}) {\n    case ${2:value1}:\n        ${3:body1}\n        break;\n    default:\n        ${4:default}\n}", "Switch statement"),
1371            ("while_snippet", "while (${1:condition}) {\n    ${2:body}\n}", "While loop"),
1372        ];
1373
1374        for (label, template, description) in java_snippets {
1375            let item = create_snippet_item(label, template, description, 0.7);
1376            completions.push(item);
1377        }
1378
1379        Ok(completions)
1380    }
1381}
1382
1383/// Kotlin-specific completion provider (fallback)
1384///
1385/// This is a **fallback provider** for Kotlin code when external LSP (kotlin-language-server) is unavailable.
1386///
1387/// # Behavior
1388///
1389/// Generates Kotlin-specific completions including:
1390/// - Kotlin keywords (fun, class, interface, object, data, sealed, enum, etc.)
1391/// - Kotlin-specific snippets (function declarations, class definitions, etc.)
1392/// - Kotlin modifiers (val, var, const, open, override, etc.)
1393/// - Available symbols from code context
1394///
1395/// # When Used
1396///
1397/// - External LSP (kotlin-language-server) is not configured
1398/// - kotlin-language-server is not installed or fails to start
1399/// - kotlin-language-server times out or becomes unresponsive
1400///
1401/// # Limitations
1402///
1403/// - No type inference or semantic analysis
1404/// - Cannot resolve imports or dependencies
1405/// - No project-aware completions
1406/// - Cannot determine variable scope or type information
1407/// - Limited to hardcoded keywords and patterns
1408///
1409/// # Recommended Configuration
1410///
1411/// For production-quality Kotlin completions, install and configure kotlin-language-server:
1412///
1413/// ```bash
1414/// # Download and install Kotlin Language Server
1415/// # See: https://github.com/fwcd/kotlin-language-server
1416/// ```
1417///
1418/// Then configure it in `lsp-servers.yaml`:
1419///
1420/// ```yaml
1421/// servers:
1422///   kotlin:
1423///     - language: kotlin
1424///       executable: kotlin-language-server
1425///       enabled: true
1426/// ```
1427///
1428/// See `https://github.com/moabualruz/ricecoder/wiki/External-LSP-Configuration.md` for details.
1429pub struct KotlinCompletionProvider;
1430
1431#[async_trait]
1432impl crate::engine::CompletionProvider for KotlinCompletionProvider {
1433    fn language(&self) -> &str {
1434        "kotlin"
1435    }
1436
1437    async fn generate_completions(
1438        &self,
1439        _code: &str,
1440        _position: Position,
1441        context: &CompletionContext,
1442    ) -> CompletionResult<Vec<CompletionItem>> {
1443        let mut completions = Vec::new();
1444
1445        // Add symbols from context
1446        for symbol in &context.available_symbols {
1447            let item = symbol_to_completion_item(symbol, 0.8);
1448            completions.push(item);
1449        }
1450
1451        // Add Kotlin-specific keywords
1452        let kotlin_keywords = vec![
1453            ("fun", "Function declaration"),
1454            ("class", "Class definition"),
1455            ("interface", "Interface definition"),
1456            ("object", "Object declaration"),
1457            ("companion", "Companion object"),
1458            ("data", "Data class"),
1459            ("sealed", "Sealed class"),
1460            ("enum", "Enum definition"),
1461            ("val", "Immutable variable"),
1462            ("var", "Mutable variable"),
1463            ("const", "Constant declaration"),
1464            ("if", "Conditional"),
1465            ("else", "Else clause"),
1466            ("when", "When expression"),
1467            ("for", "For loop"),
1468            ("while", "While loop"),
1469            ("do", "Do-while loop"),
1470            ("break", "Break statement"),
1471            ("continue", "Continue statement"),
1472            ("return", "Return statement"),
1473            ("try", "Try block"),
1474            ("catch", "Catch block"),
1475            ("finally", "Finally block"),
1476            ("throw", "Throw statement"),
1477            ("as", "Type cast"),
1478            ("is", "Type check"),
1479            ("in", "In operator"),
1480            ("!in", "Not in operator"),
1481            ("by", "Delegation"),
1482            ("get", "Getter"),
1483            ("set", "Setter"),
1484            ("init", "Initializer block"),
1485            ("constructor", "Constructor"),
1486            ("private", "Private modifier"),
1487            ("protected", "Protected modifier"),
1488            ("public", "Public modifier"),
1489            ("internal", "Internal modifier"),
1490            ("abstract", "Abstract modifier"),
1491            ("final", "Final modifier"),
1492            ("open", "Open modifier"),
1493            ("override", "Override modifier"),
1494            ("suspend", "Suspend modifier"),
1495            ("async", "Async modifier"),
1496            ("await", "Await expression"),
1497            ("yield", "Yield expression"),
1498            ("lateinit", "Late initialization"),
1499            ("inline", "Inline modifier"),
1500            ("noinline", "No-inline modifier"),
1501            ("crossinline", "Cross-inline modifier"),
1502            ("reified", "Reified type parameter"),
1503            ("operator", "Operator overload"),
1504            ("infix", "Infix function"),
1505            ("tailrec", "Tail recursive"),
1506            ("external", "External declaration"),
1507            ("expect", "Expect declaration"),
1508            ("actual", "Actual declaration"),
1509        ];
1510
1511        for (keyword, description) in kotlin_keywords {
1512            let item = CompletionItem::new(
1513                keyword.to_string(),
1514                CompletionItemKind::Keyword,
1515                keyword.to_string(),
1516            )
1517            .with_detail(description.to_string())
1518            .with_score(0.6);
1519            completions.push(item);
1520        }
1521
1522        // Add Kotlin-specific snippets
1523        let kotlin_snippets = vec![
1524            ("class_snippet", "class ${1:ClassName} {\n    ${2:body}\n}", "Class declaration"),
1525            ("data_class_snippet", "data class ${1:ClassName}(${2:properties})", "Data class"),
1526            ("fun_snippet", "fun ${1:functionName}(${2:params}): ${3:ReturnType} {\n    ${4:body}\n}", "Function declaration"),
1527            ("lambda_snippet", "{ ${1:params} -> ${2:body} }", "Lambda expression"),
1528            ("extension_snippet", "fun ${1:Type}.${2:functionName}(${3:params}): ${4:ReturnType} {\n    ${5:body}\n}", "Extension function"),
1529            ("for_snippet", "for (${1:item} in ${2:collection}) {\n    ${3:body}\n}", "For loop"),
1530            ("when_snippet", "when (${1:expr}) {\n    ${2:pattern1} -> ${3:result1}\n    ${4:pattern2} -> ${5:result2}\n    else -> ${6:default}\n}", "When expression"),
1531            ("try_catch_snippet", "try {\n    ${1:code}\n} catch (e: ${2:Exception}) {\n    ${3:handle}\n}", "Try-catch block"),
1532            ("if_snippet", "if (${1:condition}) {\n    ${2:then}\n} else {\n    ${3:else}\n}", "If-else statement"),
1533            ("interface_snippet", "interface ${1:InterfaceName} {\n    ${2:methods}\n}", "Interface definition"),
1534        ];
1535
1536        for (label, template, description) in kotlin_snippets {
1537            let item = create_snippet_item(label, template, description, 0.7);
1538            completions.push(item);
1539        }
1540
1541        Ok(completions)
1542    }
1543}
1544
1545/// Dart-specific completion provider (fallback)
1546///
1547/// This is a **fallback provider** for Dart code when external LSP (dart-language-server) is unavailable.
1548///
1549/// # Behavior
1550///
1551/// Generates Dart-specific completions including:
1552/// - Dart keywords (class, abstract, interface, mixin, enum, extension, etc.)
1553/// - Dart-specific snippets (class declarations, method definitions, etc.)
1554/// - Dart modifiers (var, final, const, late, required, etc.)
1555/// - Available symbols from code context
1556///
1557/// # When Used
1558///
1559/// - External LSP (dart-language-server) is not configured
1560/// - dart-language-server is not installed or fails to start
1561/// - dart-language-server times out or becomes unresponsive
1562///
1563/// # Limitations
1564///
1565/// - No type inference or semantic analysis
1566/// - Cannot resolve imports or dependencies
1567/// - No project-aware completions
1568/// - Cannot determine variable scope or type information
1569/// - Limited to hardcoded keywords and patterns
1570///
1571/// # Recommended Configuration
1572///
1573/// For production-quality Dart completions, install and configure dart-language-server:
1574///
1575/// ```bash
1576/// # Dart SDK includes the language server
1577/// dart pub global activate dart_language_server
1578/// ```
1579///
1580/// Then configure it in `lsp-servers.yaml`:
1581///
1582/// ```yaml
1583/// servers:
1584///   dart:
1585///     - language: dart
1586///       executable: dart
1587///       args: ["language-server"]
1588///       enabled: true
1589/// ```
1590///
1591/// See `https://github.com/moabualruz/ricecoder/wiki/External-LSP-Configuration.md` for details.
1592pub struct DartCompletionProvider;
1593
1594#[async_trait]
1595impl crate::engine::CompletionProvider for DartCompletionProvider {
1596    fn language(&self) -> &str {
1597        "dart"
1598    }
1599
1600    async fn generate_completions(
1601        &self,
1602        _code: &str,
1603        _position: Position,
1604        context: &CompletionContext,
1605    ) -> CompletionResult<Vec<CompletionItem>> {
1606        let mut completions = Vec::new();
1607
1608        // Add symbols from context
1609        for symbol in &context.available_symbols {
1610            let item = symbol_to_completion_item(symbol, 0.8);
1611            completions.push(item);
1612        }
1613
1614        // Add Dart-specific keywords
1615        let dart_keywords = vec![
1616            ("class", "Class definition"),
1617            ("abstract", "Abstract class"),
1618            ("interface", "Interface definition"),
1619            ("mixin", "Mixin definition"),
1620            ("enum", "Enum definition"),
1621            ("extension", "Extension definition"),
1622            ("typedef", "Type alias"),
1623            ("void", "Void type"),
1624            ("dynamic", "Dynamic type"),
1625            ("var", "Variable declaration"),
1626            ("final", "Final variable"),
1627            ("const", "Constant declaration"),
1628            ("late", "Late initialization"),
1629            ("required", "Required parameter"),
1630            ("covariant", "Covariant parameter"),
1631            ("factory", "Factory constructor"),
1632            ("get", "Getter"),
1633            ("set", "Setter"),
1634            ("operator", "Operator overload"),
1635            ("static", "Static member"),
1636            ("external", "External declaration"),
1637            ("if", "Conditional"),
1638            ("else", "Else clause"),
1639            ("for", "For loop"),
1640            ("while", "While loop"),
1641            ("do", "Do-while loop"),
1642            ("switch", "Switch statement"),
1643            ("case", "Case clause"),
1644            ("default", "Default clause"),
1645            ("break", "Break statement"),
1646            ("continue", "Continue statement"),
1647            ("return", "Return statement"),
1648            ("try", "Try block"),
1649            ("catch", "Catch block"),
1650            ("finally", "Finally block"),
1651            ("throw", "Throw statement"),
1652            ("rethrow", "Rethrow statement"),
1653            ("async", "Async function"),
1654            ("await", "Await expression"),
1655            ("yield", "Yield statement"),
1656            ("sync", "Sync generator"),
1657            ("as", "Type cast"),
1658            ("is", "Type check"),
1659            ("in", "In operator"),
1660            ("new", "New keyword"),
1661            ("this", "This keyword"),
1662            ("super", "Super keyword"),
1663            ("extends", "Extends keyword"),
1664            ("implements", "Implements keyword"),
1665            ("with", "With keyword"),
1666            ("on", "On keyword"),
1667            ("show", "Show keyword"),
1668            ("hide", "Hide keyword"),
1669            ("deferred", "Deferred import"),
1670            ("export", "Export statement"),
1671            ("import", "Import statement"),
1672            ("library", "Library declaration"),
1673            ("part", "Part declaration"),
1674            ("null", "Null value"),
1675            ("true", "True value"),
1676            ("false", "False value"),
1677        ];
1678
1679        for (keyword, description) in dart_keywords {
1680            let item = CompletionItem::new(
1681                keyword.to_string(),
1682                CompletionItemKind::Keyword,
1683                keyword.to_string(),
1684            )
1685            .with_detail(description.to_string())
1686            .with_score(0.6);
1687            completions.push(item);
1688        }
1689
1690        // Add Dart-specific snippets
1691        let dart_snippets = vec![
1692            ("class_snippet", "class ${1:ClassName} {\n    ${2:body}\n}", "Class declaration"),
1693            ("mixin_snippet", "mixin ${1:MixinName} {\n    ${2:methods}\n}", "Mixin definition"),
1694            ("abstract_class_snippet", "abstract class ${1:ClassName} {\n    ${2:abstract methods}\n}", "Abstract class"),
1695            ("method_snippet", "${1:returnType} ${2:methodName}(${3:params}) {\n    ${4:body}\n}", "Method declaration"),
1696            ("async_method_snippet", "Future<${1:Type}> ${2:methodName}(${3:params}) async {\n    ${4:body}\n}", "Async method"),
1697            ("stream_snippet", "Stream<${1:Type}> ${2:methodName}(${3:params}) async* {\n    ${4:yield statements}\n}", "Stream generator"),
1698            ("for_snippet", "for (var ${1:item} in ${2:collection}) {\n    ${3:body}\n}", "For loop"),
1699            ("for_each_snippet", "${1:collection}.forEach((${2:item}) {\n    ${3:body}\n});", "For-each loop"),
1700            ("if_snippet", "if (${1:condition}) {\n    ${2:then}\n} else {\n    ${3:else}\n}", "If-else statement"),
1701            ("switch_snippet", "switch (${1:expr}) {\n    case ${2:value1}:\n        ${3:body1}\n        break;\n    default:\n        ${4:default}\n}", "Switch statement"),
1702        ];
1703
1704        for (label, template, description) in dart_snippets {
1705            let item = create_snippet_item(label, template, description, 0.7);
1706            completions.push(item);
1707        }
1708
1709        Ok(completions)
1710    }
1711}
1712
1713/// Completion provider factory for creating language-specific providers
1714pub struct CompletionProviderFactory;
1715
1716impl CompletionProviderFactory {
1717    /// Create a completion provider for the given language
1718    pub fn create(
1719        language: crate::language::Language,
1720    ) -> Box<dyn crate::engine::CompletionProvider> {
1721        match language {
1722            crate::language::Language::Rust => Box::new(RustCompletionProvider),
1723            crate::language::Language::TypeScript => Box::new(TypeScriptCompletionProvider),
1724            crate::language::Language::Python => Box::new(PythonCompletionProvider),
1725            crate::language::Language::Go => Box::new(GoCompletionProvider),
1726            crate::language::Language::Java => Box::new(JavaCompletionProvider),
1727            crate::language::Language::Kotlin => Box::new(KotlinCompletionProvider),
1728            crate::language::Language::Dart => Box::new(DartCompletionProvider),
1729            crate::language::Language::Unknown => Box::new(GenericTextProvider),
1730        }
1731    }
1732
1733    /// Create a completion provider from file path and content
1734    pub fn from_file(
1735        path: &std::path::Path,
1736        content: &str,
1737    ) -> Box<dyn crate::engine::CompletionProvider> {
1738        let language = crate::language::LanguageDetector::detect(path, content);
1739        Self::create(language)
1740    }
1741}
1742
1743#[cfg(test)]
1744mod tests {
1745    use super::*;
1746    use crate::engine::CompletionProvider;
1747
1748    #[test]
1749    fn test_generic_provider_language() {
1750        let provider = GenericTextProvider;
1751        assert_eq!(provider.language(), "generic");
1752    }
1753
1754    #[test]
1755    fn test_rust_provider_language() {
1756        let provider = RustCompletionProvider;
1757        assert_eq!(provider.language(), "rust");
1758    }
1759
1760    #[test]
1761    fn test_typescript_provider_language() {
1762        let provider = TypeScriptCompletionProvider;
1763        assert_eq!(provider.language(), "typescript");
1764    }
1765
1766    #[test]
1767    fn test_python_provider_language() {
1768        let provider = PythonCompletionProvider;
1769        assert_eq!(provider.language(), "python");
1770    }
1771
1772    #[test]
1773    fn test_go_provider_language() {
1774        let provider = GoCompletionProvider;
1775        assert_eq!(provider.language(), "go");
1776    }
1777
1778    #[test]
1779    fn test_java_provider_language() {
1780        let provider = JavaCompletionProvider;
1781        assert_eq!(provider.language(), "java");
1782    }
1783
1784    #[test]
1785    fn test_kotlin_provider_language() {
1786        let provider = KotlinCompletionProvider;
1787        assert_eq!(provider.language(), "kotlin");
1788    }
1789
1790    #[test]
1791    fn test_dart_provider_language() {
1792        let provider = DartCompletionProvider;
1793        assert_eq!(provider.language(), "dart");
1794    }
1795
1796    #[test]
1797    fn test_provider_factory_rust() {
1798        let provider = CompletionProviderFactory::create(crate::language::Language::Rust);
1799        assert_eq!(provider.language(), "rust");
1800    }
1801
1802    #[test]
1803    fn test_provider_factory_go() {
1804        let provider = CompletionProviderFactory::create(crate::language::Language::Go);
1805        assert_eq!(provider.language(), "go");
1806    }
1807
1808    #[test]
1809    fn test_provider_factory_java() {
1810        let provider = CompletionProviderFactory::create(crate::language::Language::Java);
1811        assert_eq!(provider.language(), "java");
1812    }
1813
1814    #[test]
1815    fn test_provider_factory_kotlin() {
1816        let provider = CompletionProviderFactory::create(crate::language::Language::Kotlin);
1817        assert_eq!(provider.language(), "kotlin");
1818    }
1819
1820    #[test]
1821    fn test_provider_factory_dart() {
1822        let provider = CompletionProviderFactory::create(crate::language::Language::Dart);
1823        assert_eq!(provider.language(), "dart");
1824    }
1825
1826    #[test]
1827    fn test_provider_factory_unknown() {
1828        let provider = CompletionProviderFactory::create(crate::language::Language::Unknown);
1829        assert_eq!(provider.language(), "generic");
1830    }
1831}