Skip to content

Commit

Permalink
Implement completions for npm package names
Browse files Browse the repository at this point in the history
  • Loading branch information
filiptibell committed Oct 27, 2023
1 parent 637cb9f commit 6c28b49
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 35 deletions.
41 changes: 21 additions & 20 deletions src/tools/javascript/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,6 @@ use crate::server::*;

use super::constants::*;

async fn complete_package_name(
_clients: &Clients,
document: &Document,
replace_range: StdRange<usize>,
name: &str,
) -> Result<Vec<CompletionItem>> {
Ok(find_matching_package_infos(name)
.iter()
.map(|p| CompletionItem {
label: p.name.to_string(),
kind: Some(CompletionItemKind::VALUE),
text_edit: Some(CompletionTextEdit::Edit(
document.create_edit(replace_range.clone(), p.name.to_string()),
)),
..Default::default()
})
.collect::<Vec<_>>())
}

async fn complete_package_version(
clients: &Clients,
document: &Document,
Expand Down Expand Up @@ -77,7 +58,27 @@ async fn complete_package_version(
.collect())
}

pub async fn get_package_completions(
pub async fn get_package_name_completions(
_clients: &Clients,
document: &Document,
replace_range: StdRange<usize>,
name: &str,
) -> Result<CompletionResponse> {
let items = find_matching_package_infos(name)
.iter()
.map(|p| CompletionItem {
label: p.name.to_string(),
kind: Some(CompletionItemKind::VALUE),
text_edit: Some(CompletionTextEdit::Edit(
document.create_edit(replace_range.clone(), p.name.to_string()),
)),
..Default::default()
})
.collect::<Vec<_>>();
Ok(CompletionResponse::Array(items))
}

pub async fn get_package_version_completions(
clients: &Clients,
document: &Document,
range: StdRange<usize>,
Expand Down
36 changes: 21 additions & 15 deletions src/tools/javascript/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,23 +169,24 @@ impl Tool for JavaScript {
let offset = document.lsp_position_to_offset(pos);
let try_find = |deps: &HashMap<String, ManifestDependency>| {
deps.iter().find_map(|(_, dep)| {
let span = dep.version_span();
if offset >= span.start && offset <= span.end {
Some((span.clone(), dep.clone()))
let nspan = dep.name_span();
let vspan = dep.version_span();
if offset >= nspan.start && offset <= nspan.end {
Some((true, nspan.clone(), dep.clone()))
} else if offset >= vspan.start && offset <= vspan.end {
Some((false, vspan.clone(), dep.clone()))
} else {
None
}
})
};

// TODO: Completion for package names

let found = try_find(&manifest.dependencies)
.or_else(|| try_find(&manifest.dev_dependencies))
.or_else(|| try_find(&manifest.build_dependencies))
.or_else(|| try_find(&manifest.optional_dependencies));
let (found_range, found_dep) = match found {
Some((range, dep)) => (range, dep),
let (found_is_name, found_range, found_dep) = match found {
Some((is_name, range, dep)) => (is_name, range, dep),
_ => return Ok(CompletionResponse::Array(Vec::new())),
};

Expand All @@ -195,14 +196,19 @@ impl Tool for JavaScript {
});

let slice_before = &document.as_str()[range_before.clone()];
get_package_completions(
&self.clients,
&document,
range_before,
found_dep.name_text(),
slice_before,
)
.await

if found_is_name {
get_package_name_completions(&self.clients, &document, range_before, slice_before).await
} else {
get_package_version_completions(
&self.clients,
&document,
range_before,
found_dep.name_text(),
slice_before,
)
.await
}
}

async fn diagnostics(&self, _params: DocumentDiagnosticParams) -> Result<Vec<Diagnostic>> {
Expand Down

0 comments on commit 6c28b49

Please sign in to comment.