From 783b2ef56684992400181ef852d3f8b015abc0f1 Mon Sep 17 00:00:00 2001 From: frederik Date: Sun, 1 Sep 2024 14:27:57 +0200 Subject: [PATCH] feature suggestion feature & version bump --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 6 ++++-- src/lsp.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b70d98..ac3fbcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,7 +191,7 @@ checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "cargotom" -version = "0.10.0" +version = "0.11.0" dependencies = [ "clap", "git2", diff --git a/Cargo.toml b/Cargo.toml index 779617a..d9cdf38 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargotom" -version = "0.10.0" +version = "0.11.0" edition = "2021" [dependencies] diff --git a/README.md b/README.md index 2294582..37c4410 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,10 @@ - crate features(online/offline) - feature key when version after the key `crate = "0.1.0"` => `crate = {ve"0.1.0"` to `crate = { version = "0.1.0" }` +### Features +- feature names +- possible dependencies + ### Diagnostics - check if crate needs update - check if crate version exists @@ -26,8 +30,6 @@ ## Plans - features - - suggest features in default - - suggest dep:crate-name - code action make optional if not & diagnostics if not - diagnostics if version is set & dep in workspace - diagnostics when workspace modules have dep overlap diff --git a/src/lsp.rs b/src/lsp.rs index e2c7506..643d611 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -10,7 +10,8 @@ use tower_lsp::{Client, LanguageServer, LspService, Server}; use crate::crate_lookup::{CratesIoStorage, Shared}; use crate::generate_tree::{ - get_after_key, parse_toml, Key, KeyOrValueOwned, RangeExclusive, Tree, TreeValue, Value, + get_after_key, parse_toml, Key, KeyOrValue, KeyOrValueOwned, RangeExclusive, Tree, TreeValue, + Value, }; use crate::helper::{get_byte_index_from_position, new_workspace_edit, shared}; use crate::rust_version::RustVersion; @@ -37,6 +38,7 @@ struct Store { content: String, tree: Tree, crates_info: Vec, + features: HashMap>, } impl Store { @@ -47,6 +49,7 @@ impl Store { crates_info: vec![], workspace_root, workspace_members: vec![], + features: Default::default(), }; s.crates().await; s @@ -164,6 +167,23 @@ impl Store { .cloned() .collect::>(); self.crates_info = v; + let v = self + .tree + .find("features") + .iter() + .filter_map(|v| v.value.as_tree()) + .flat_map(|v| &v.0) + .flat_map(|v| { + v.value.as_array().map(|a| { + ( + v.key.value.clone(), + a.iter().filter_map(|v| v.as_str()).collect::>(), + ) + }) + }) + .collect::>(); + self.features = v; + let root = &*self.workspace_root.read().await; if let Some(root) = root { let ws: Vec<_> = self @@ -251,7 +271,7 @@ impl LanguageServer for Backend { }, )), completion_provider: Some(CompletionOptions { - trigger_characters: Some(vec!["\"".to_string(), ".".to_string()]), + trigger_characters: Some(vec!["\"".to_string(), ".".to_string(), ":".to_string()]), ..Default::default() }), signature_help_provider: Some(SignatureHelpOptions { @@ -464,12 +484,12 @@ impl LanguageServer for Backend { return Ok(Some(CompletionResponse::Array(vec![]))); } let lock = self.toml_store.lock().await; - if let Some(v) = lock.get(&uri) { + if let Some(store) = lock.get(&uri) { let byte_offset = - get_byte_index_from_position(v.text(), params.text_document_position.position) + get_byte_index_from_position(store.text(), params.text_document_position.position) as u32; - if let Some(info) = v.tree.get_item_by_pos(byte_offset) { + if let Some(info) = store.tree.get_item_by_pos(byte_offset) { if let Some(path) = get_after_key("dependencies", &info) .or(get_after_key("dev-dependencies", &info)) { @@ -511,6 +531,37 @@ impl LanguageServer for Backend { .await } }; + } 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:") { + let v = store + .crates_info + .iter() + .map(|v| &v.key.value) + .filter(|v| v.as_str().starts_with(query)) + .map(|v| CompletionItem { + label: v.to_string(), + ..Default::default() + }) + .collect::>(); + return Ok(Some(CompletionResponse::Array(v))); + } else { + let v = store + .features + .keys() + .filter(|v| v.as_str().starts_with(v.as_str())) + .map(|v| CompletionItem { + label: v.to_string(), + ..Default::default() + }) + .collect(); + return Ok(Some(CompletionResponse::Array(v))); + } + } + } + } } } }