summaryrefslogtreecommitdiff
path: root/cli/lsp/completions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/lsp/completions.rs')
-rw-r--r--cli/lsp/completions.rs55
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, &current_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(&current_specifier, offset, &range, state_snapshot)
+ .await;
+ let items = maybe_items.unwrap_or_else(|| {
+ get_workspace_completions(
specifier,
&current_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(&current_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 {