Skip to content

Commit

Permalink
filtering out existing
Browse files Browse the repository at this point in the history
  • Loading branch information
frederik-uni committed Sep 1, 2024
1 parent 783b2ef commit d26a9c4
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cargotom"
version = "0.11.0"
version = "0.12.0"
edition = "2021"

[dependencies]
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@
- code action make optional if not & diagnostics if not
- diagnostics if version is set & dep in workspace
- diagnostics when workspace modules have dep overlap
- diagnostics when feature duplicate
21 changes: 21 additions & 0 deletions src/generate_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ use taplo::{
pub(crate) struct Tree(pub Vec<TreeValue>);

impl Tree {
pub fn by_array_child(&self, child: &Value) -> Option<&Value> {
self.0.iter().find_map(|v| v.value.by_array_child(child))
}

pub fn by_key(&self, key: &Key) -> Option<&Tree> {
match self.0.iter().find(|v| &v.key == key) {
Some(_) => Some(self),
Expand Down Expand Up @@ -215,6 +219,17 @@ impl Value {
}
}

fn by_array_child(&self, child: &Value) -> Option<&Value> {
match self {
Value::Tree { value, .. } => value.by_array_child(child),
Value::Array(arr) => match arr.iter().find(|v| v == &child).is_some() {
true => return Some(&self),
false => arr.iter().find_map(|v| v.by_array_child(child)),
},
_ => None,
}
}

fn find(&self, str: &str) -> Vec<&TreeValue> {
match self {
Value::Tree { value, .. } => value.find(str),
Expand Down Expand Up @@ -389,6 +404,12 @@ pub enum KeyOrValue<'a> {
}

impl<'a> KeyOrValue<'a> {
pub fn as_str(&self) -> Option<String> {
match self {
KeyOrValue::Key(k) => Some(k.value.clone()),
KeyOrValue::Value(v) => v.as_str(),
}
}
pub fn owned(&self) -> KeyOrValueOwned {
match self {
KeyOrValue::Key(v) => KeyOrValueOwned::Key((*v).clone()),
Expand Down
52 changes: 47 additions & 5 deletions src/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,25 +533,46 @@ impl LanguageServer for Backend {
};
} else if let Some(path) = get_after_key("features", &info) {
if path.len() == 2 {
if let KeyOrValue::Value(v) = path[1] {
if let Some(v) = v.as_str() {
if let Some(query) = v.strip_prefix("dep:") {
if let KeyOrValue::Value(val) = path[1] {
if let Some(query) = val.as_str() {
let mut existing = store
.tree
.by_array_child(*val)
.and_then(|v| v.as_array())
.and_then(|v| {
Some(
v.into_iter()
.flat_map(|v| v.as_str())
.collect::<Vec<_>>(),
)
})
.unwrap_or_default();
if let Some(query) = query.strip_prefix("dep:") {
let existing: Vec<_> = existing
.iter()
.filter_map(|v| v.strip_prefix("dep:"))
.collect();
let v = store
.crates_info
.iter()
.map(|v| &v.key.value)
.filter(|v| v.as_str().starts_with(query))
.filter(|v| !existing.contains(&v.as_str()))
.map(|v| CompletionItem {
label: v.to_string(),
..Default::default()
})
.collect::<Vec<_>>();
return Ok(Some(CompletionResponse::Array(v)));
} else {
if let Some(v) = path[0].as_str() {
existing.push(v);
}
let v = store
.features
.keys()
.filter(|v| v.as_str().starts_with(v.as_str()))
.filter(|v| v.as_str().starts_with(query.as_str()))
.filter(|v| !existing.contains(v))
.map(|v| CompletionItem {
label: v.to_string(),
..Default::default()
Expand Down Expand Up @@ -592,11 +613,21 @@ impl Backend {
}
async fn complete_1(&self, crate_name: Option<&Key>, uri: &str) -> Option<Vec<CompletionItem>> {
let crate_name = crate_name?;
let existing_crates = {
let lock = self.toml_store.lock().await;
if let Some(v) = lock.get(uri) {
v.crates_info.iter().map(|v| v.key.value.clone()).collect()
} else {
vec![]
}
};

let root_dep = self.get_root_dependencies(uri).await.unwrap_or_default();
let result = self.crates.read().await.search(&crate_name.value).await;
Some(
result
.into_iter()
.filter(|(crate_name, _, _)| !existing_crates.contains(crate_name))
.map(|(name, detail, version)| CompletionItem {
label: name.clone(),
detail,
Expand Down Expand Up @@ -728,7 +759,17 @@ impl Backend {
) -> Option<Vec<CompletionItem>> {
let crate_name = crate_name?;
let expanded_key = expanded_key?;
let (value, range) = data?.as_str_value()?;
let data = data?;
let (value, range) = data.as_str_value()?;
let lock = self.toml_store.lock().await;
let others = lock
.get(uri)?
.tree
.by_array_child(data)
.and_then(|v| v.as_array())
.and_then(|v| Some(v.into_iter().flat_map(|v| v.as_str()).collect::<Vec<_>>()))
.unwrap_or_default();
drop(lock);
match expanded_key.value.as_str() {
"features" => {
let version = self.get_version_for_features(&uri, expanded_key).await?;
Expand All @@ -740,6 +781,7 @@ impl Backend {
.await
.unwrap_or_default()
.into_iter()
.filter(|v| !others.contains(v))
.map(|v| CompletionItem {
label: v.to_string(),
detail: None,
Expand Down

0 comments on commit d26a9c4

Please sign in to comment.