diff options
Diffstat (limited to 'cli/lsp/completions.rs')
-rw-r--r-- | cli/lsp/completions.rs | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/cli/lsp/completions.rs b/cli/lsp/completions.rs index 06b123783..d0630af22 100644 --- a/cli/lsp/completions.rs +++ b/cli/lsp/completions.rs @@ -25,6 +25,7 @@ use swc_ecmascript::visit::VisitWith; const CURRENT_PATH: &str = "."; const PARENT_PATH: &str = ".."; +const LOCAL_PATHS: &[&str] = &[CURRENT_PATH, PARENT_PATH]; #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -36,7 +37,7 @@ pub struct CompletionItemData { /// Given a specifier, a position, and a snapshot, optionally return a /// completion response, which will be valid import completions for the specific /// context. -pub fn get_import_completions( +pub async fn get_import_completions( specifier: &ModuleSpecifier, position: &lsp::Position, state_snapshot: &language_server::StateSnapshot, @@ -55,17 +56,52 @@ pub fn get_import_completions( items: get_local_completions(specifier, ¤t_specifier, &range)?, })); } - // completion of modules within the workspace + // completion of modules from a module registry or cache if !current_specifier.is_empty() { - return Some(lsp::CompletionResponse::List(lsp::CompletionList { - is_incomplete: false, - items: get_workspace_completions( + let offset = if position.character > range.start.character { + (position.character - range.start.character) as usize + } else { + 0 + }; + let maybe_items = state_snapshot + .module_registries + .get_completions(¤t_specifier, offset, &range, state_snapshot) + .await; + let items = maybe_items.unwrap_or_else(|| { + get_workspace_completions( specifier, ¤t_specifier, &range, state_snapshot, - ), + ) + }); + return Some(lsp::CompletionResponse::List(lsp::CompletionList { + is_incomplete: false, + items, })); + } else { + let mut items: Vec<lsp::CompletionItem> = LOCAL_PATHS + .iter() + .map(|s| lsp::CompletionItem { + label: s.to_string(), + kind: Some(lsp::CompletionItemKind::Folder), + detail: Some("(local)".to_string()), + sort_text: Some("1".to_string()), + insert_text: Some(s.to_string()), + ..Default::default() + }) + .collect(); + if let Some(origin_items) = state_snapshot + .module_registries + .get_origin_completions(¤t_specifier, &range) + { + items.extend(origin_items); + } + return Some(lsp::CompletionResponse::List(lsp::CompletionList { + is_incomplete: false, + items, + })); + // TODO(@kitsonk) add bare specifiers from import map } } } @@ -738,8 +774,8 @@ mod tests { } } - #[test] - fn test_get_import_completions() { + #[tokio::test] + async fn test_get_import_completions() { let specifier = resolve_url("file:///a/b/c.ts").unwrap(); let position = lsp::Position { line: 0, @@ -752,7 +788,8 @@ mod tests { ], &[("https://deno.land/x/a/b/c.ts", "console.log(1);\n")], ); - let actual = get_import_completions(&specifier, &position, &state_snapshot); + let actual = + get_import_completions(&specifier, &position, &state_snapshot).await; assert_eq!( actual, Some(lsp::CompletionResponse::List(lsp::CompletionList { |