From ce107221101c1cb915d6e7f742e0bf143d3575ac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Oct 2025 14:13:40 +0000 Subject: [PATCH 1/5] Initial plan From ad7ba221ed7d18e7de1a62d4c4dec68a4e356666 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Oct 2025 14:35:13 +0000 Subject: [PATCH 2/5] Add workspace symbols support to protols LSP server - Add WorkspaceSymbolRequest handler registration in server.rs - Implement workspace_symbol method in lsp.rs to handle workspace symbol requests - Add workspace_symbol_provider capability in initialize response - Create find_workspace_symbols method in state.rs to collect and filter symbols from all parsed trees - Add comprehensive test for workspace symbols functionality with snapshots - Sort symbols by name and URI for consistent ordering Co-authored-by: coder3101 <22212259+coder3101@users.noreply.github.com> --- src/lsp.rs | 20 ++- src/server.rs | 2 + src/state.rs | 72 +++++++++- src/workspace/mod.rs | 1 + ...rkspace_symbol__test__address_symbols.snap | 28 ++++ ...__workspace_symbol__test__all_symbols.snap | 129 ++++++++++++++++++ ...orkspace_symbol__test__author_symbols.snap | 26 ++++ src/workspace/workspace_symbol.rs | 40 ++++++ 8 files changed, 316 insertions(+), 2 deletions(-) create mode 100644 src/workspace/snapshots/protols__workspace__workspace_symbol__test__address_symbols.snap create mode 100644 src/workspace/snapshots/protols__workspace__workspace_symbol__test__all_symbols.snap create mode 100644 src/workspace/snapshots/protols__workspace__workspace_symbol__test__author_symbols.snap create mode 100644 src/workspace/workspace_symbol.rs diff --git a/src/lsp.rs b/src/lsp.rs index 43e3101..37a5f6b 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -14,7 +14,7 @@ use async_lsp::lsp_types::{ RenameParams, ServerCapabilities, ServerInfo, TextDocumentPositionParams, TextDocumentSyncCapability, TextDocumentSyncKind, TextEdit, Url, WorkspaceEdit, WorkspaceFileOperationsServerCapabilities, WorkspaceFoldersServerCapabilities, - WorkspaceServerCapabilities, + WorkspaceServerCapabilities, WorkspaceSymbolParams, WorkspaceSymbolResponse, }; use async_lsp::{LanguageClient, ResponseError}; use futures::future::BoxFuture; @@ -113,6 +113,7 @@ impl ProtoLanguageServer { definition_provider: Some(OneOf::Left(true)), hover_provider: Some(HoverProviderCapability::Simple(true)), document_symbol_provider: Some(OneOf::Left(true)), + workspace_symbol_provider: Some(OneOf::Left(true)), completion_provider: Some(CompletionOptions::default()), rename_provider: Some(rename_provider), document_formatting_provider: Some(OneOf::Left(true)), @@ -379,6 +380,23 @@ impl ProtoLanguageServer { Box::pin(async move { Ok(Some(response)) }) } + pub(super) fn workspace_symbol( + &mut self, + params: WorkspaceSymbolParams, + ) -> BoxFuture<'static, Result, ResponseError>> { + let query = params.query.to_lowercase(); + + let symbols = self.state.find_workspace_symbols(&query); + + Box::pin(async move { + if symbols.is_empty() { + Ok(None) + } else { + Ok(Some(WorkspaceSymbolResponse::Nested(symbols))) + } + }) + } + pub(super) fn formatting( &mut self, params: DocumentFormattingParams, diff --git a/src/server.rs b/src/server.rs index fcb45af..11e299d 100644 --- a/src/server.rs +++ b/src/server.rs @@ -9,6 +9,7 @@ use async_lsp::{ request::{ Completion, DocumentSymbolRequest, Formatting, GotoDefinition, HoverRequest, Initialize, PrepareRenameRequest, RangeFormatting, References, Rename, + WorkspaceSymbolRequest, }, }, router::Router, @@ -59,6 +60,7 @@ impl ProtoLanguageServer { router.request::(|st, params| st.references(params)); router.request::(|st, params| st.definition(params)); router.request::(|st, params| st.document_symbol(params)); + router.request::(|st, params| st.workspace_symbol(params)); router.request::(|st, params| st.formatting(params)); router.request::(|st, params| st.range_formatting(params)); diff --git a/src/state.rs b/src/state.rs index a687cac..9c9b849 100644 --- a/src/state.rs +++ b/src/state.rs @@ -6,7 +6,10 @@ use std::{ use tracing::info; use async_lsp::lsp_types::ProgressParamsValue; -use async_lsp::lsp_types::{CompletionItem, CompletionItemKind, PublishDiagnosticsParams, Url}; +use async_lsp::lsp_types::{ + CompletionItem, CompletionItemKind, Location, OneOf, PublishDiagnosticsParams, Url, + WorkspaceSymbol, +}; use std::sync::mpsc::Sender; use tree_sitter::Node; use walkdir::WalkDir; @@ -73,6 +76,73 @@ impl ProtoLanguageState { .collect() } + pub fn find_workspace_symbols(&self, query: &str) -> Vec { + let mut symbols = Vec::new(); + + for tree in self.get_trees() { + let content = self.get_content(&tree.uri); + let doc_symbols = tree.find_document_locations(content.as_bytes()); + + for doc_symbol in doc_symbols { + self.collect_workspace_symbols(&doc_symbol, &tree.uri, query, None, &mut symbols); + } + } + + // Sort symbols by name and then by URI for consistent ordering + symbols.sort_by(|a, b| { + let name_cmp = a.name.cmp(&b.name); + if name_cmp != std::cmp::Ordering::Equal { + return name_cmp; + } + // Extract URI from location + match (&a.location, &b.location) { + (OneOf::Left(loc_a), OneOf::Left(loc_b)) => { + loc_a.uri.as_str().cmp(loc_b.uri.as_str()) + } + _ => std::cmp::Ordering::Equal, + } + }); + + symbols + } + + fn collect_workspace_symbols( + &self, + doc_symbol: &async_lsp::lsp_types::DocumentSymbol, + uri: &Url, + query: &str, + container_name: Option, + symbols: &mut Vec, + ) { + let symbol_name_lower = doc_symbol.name.to_lowercase(); + + if query.is_empty() || symbol_name_lower.contains(query) { + symbols.push(WorkspaceSymbol { + name: doc_symbol.name.clone(), + kind: doc_symbol.kind, + tags: doc_symbol.tags.clone(), + container_name: container_name.clone(), + location: OneOf::Left(Location { + uri: uri.clone(), + range: doc_symbol.range, + }), + data: None, + }); + } + + if let Some(children) = &doc_symbol.children { + for child in children { + self.collect_workspace_symbols( + child, + uri, + query, + Some(doc_symbol.name.clone()), + symbols, + ); + } + } + } + fn upsert_content_impl( &mut self, uri: &Url, diff --git a/src/workspace/mod.rs b/src/workspace/mod.rs index cca1e38..827348a 100644 --- a/src/workspace/mod.rs +++ b/src/workspace/mod.rs @@ -1,3 +1,4 @@ mod definition; mod hover; mod rename; +mod workspace_symbol; diff --git a/src/workspace/snapshots/protols__workspace__workspace_symbol__test__address_symbols.snap b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__address_symbols.snap new file mode 100644 index 0000000..06f3207 --- /dev/null +++ b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__address_symbols.snap @@ -0,0 +1,28 @@ +--- +source: src/workspace/workspace_symbol.rs +expression: address_symbols +--- +- name: Address + kind: 23 + containerName: Author + location: + uri: "file:///home/runner/work/protols/protols/src/workspace/input/b.proto" + range: + start: + line: 9 + character: 3 + end: + line: 11 + character: 4 +- name: Address + kind: 23 + containerName: Author + location: + uri: "file://input/b.proto" + range: + start: + line: 9 + character: 3 + end: + line: 11 + character: 4 diff --git a/src/workspace/snapshots/protols__workspace__workspace_symbol__test__all_symbols.snap b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__all_symbols.snap new file mode 100644 index 0000000..956d29d --- /dev/null +++ b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__all_symbols.snap @@ -0,0 +1,129 @@ +--- +source: src/workspace/workspace_symbol.rs +expression: all_symbols +--- +- name: Address + kind: 23 + containerName: Author + location: + uri: "file:///home/runner/work/protols/protols/src/workspace/input/b.proto" + range: + start: + line: 9 + character: 3 + end: + line: 11 + character: 4 +- name: Address + kind: 23 + containerName: Author + location: + uri: "file://input/b.proto" + range: + start: + line: 9 + character: 3 + end: + line: 11 + character: 4 +- name: Author + kind: 23 + location: + uri: "file:///home/runner/work/protols/protols/src/workspace/input/b.proto" + range: + start: + line: 5 + character: 0 + end: + line: 14 + character: 1 +- name: Author + kind: 23 + location: + uri: "file://input/b.proto" + range: + start: + line: 5 + character: 0 + end: + line: 14 + character: 1 +- name: Baz + kind: 23 + containerName: Foobar + location: + uri: "file:///home/runner/work/protols/protols/src/workspace/input/c.proto" + range: + start: + line: 8 + character: 3 + end: + line: 10 + character: 4 +- name: Baz + kind: 23 + containerName: Foobar + location: + uri: "file://input/c.proto" + range: + start: + line: 8 + character: 3 + end: + line: 10 + character: 4 +- name: Book + kind: 23 + location: + uri: "file://input/a.proto" + range: + start: + line: 9 + character: 0 + end: + line: 14 + character: 1 +- name: Foobar + kind: 23 + location: + uri: "file:///home/runner/work/protols/protols/src/workspace/input/c.proto" + range: + start: + line: 5 + character: 0 + end: + line: 13 + character: 1 +- name: Foobar + kind: 23 + location: + uri: "file://input/c.proto" + range: + start: + line: 5 + character: 0 + end: + line: 13 + character: 1 +- name: SomeSecret + kind: 23 + location: + uri: "file:///home/runner/work/protols/protols/src/workspace/input/inner/secret/y.proto" + range: + start: + line: 5 + character: 0 + end: + line: 7 + character: 1 +- name: Why + kind: 23 + location: + uri: "file:///home/runner/work/protols/protols/src/workspace/input/inner/x.proto" + range: + start: + line: 7 + character: 0 + end: + line: 11 + character: 1 diff --git a/src/workspace/snapshots/protols__workspace__workspace_symbol__test__author_symbols.snap b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__author_symbols.snap new file mode 100644 index 0000000..229fdd0 --- /dev/null +++ b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__author_symbols.snap @@ -0,0 +1,26 @@ +--- +source: src/workspace/workspace_symbol.rs +expression: author_symbols +--- +- name: Author + kind: 23 + location: + uri: "file:///home/runner/work/protols/protols/src/workspace/input/b.proto" + range: + start: + line: 5 + character: 0 + end: + line: 14 + character: 1 +- name: Author + kind: 23 + location: + uri: "file://input/b.proto" + range: + start: + line: 5 + character: 0 + end: + line: 14 + character: 1 diff --git a/src/workspace/workspace_symbol.rs b/src/workspace/workspace_symbol.rs new file mode 100644 index 0000000..1cc967c --- /dev/null +++ b/src/workspace/workspace_symbol.rs @@ -0,0 +1,40 @@ +#[cfg(test)] +mod test { + use insta::assert_yaml_snapshot; + + use crate::config::Config; + use crate::state::ProtoLanguageState; + + #[test] + fn test_workspace_symbols() { + let ipath = vec![std::env::current_dir().unwrap().join("src/workspace/input")]; + let a_uri = "file://input/a.proto".parse().unwrap(); + let b_uri = "file://input/b.proto".parse().unwrap(); + let c_uri = "file://input/c.proto".parse().unwrap(); + + let a = include_str!("input/a.proto"); + let b = include_str!("input/b.proto"); + let c = include_str!("input/c.proto"); + + let mut state: ProtoLanguageState = ProtoLanguageState::new(); + state.upsert_file(&a_uri, a.to_owned(), &ipath, 3, &Config::default(), false); + state.upsert_file(&b_uri, b.to_owned(), &ipath, 2, &Config::default(), false); + state.upsert_file(&c_uri, c.to_owned(), &ipath, 2, &Config::default(), false); + + // Test empty query - should return all symbols + let all_symbols = state.find_workspace_symbols(""); + assert_yaml_snapshot!("all_symbols", all_symbols); + + // Test query for "author" - should match Author and Address + let author_symbols = state.find_workspace_symbols("author"); + assert_yaml_snapshot!("author_symbols", author_symbols); + + // Test query for "address" - should match Address + let address_symbols = state.find_workspace_symbols("address"); + assert_yaml_snapshot!("address_symbols", address_symbols); + + // Test query that should not match anything + let no_match = state.find_workspace_symbols("nonexistent"); + assert!(no_match.is_empty()); + } +} From 9d63252e0dfb1d0c7d2da6df91ba8c8fee457985 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Oct 2025 05:40:51 +0000 Subject: [PATCH 3/5] Add full workspace parsing to workspace_symbol request - Add get_workspaces() method to WorkspaceProtoConfigs to retrieve all workspace folders - Update workspace_symbol handler to parse all files from all workspaces before collecting symbols - Add progress reporting support for workspace symbol requests - Now workspace symbols work across entire workspace, not just opened files Co-authored-by: coder3101 <22212259+coder3101@users.noreply.github.com> --- src/config/workspace.rs | 4 ++++ src/lsp.rs | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/config/workspace.rs b/src/config/workspace.rs index 87ed113..d094d1e 100644 --- a/src/config/workspace.rs +++ b/src/config/workspace.rs @@ -131,6 +131,10 @@ impl WorkspaceProtoConfigs { Some(ipath) } + pub fn get_workspaces(&self) -> Vec<&Url> { + self.workspaces.iter().collect() + } + pub fn no_workspace_mode(&mut self) { let wr = ProtolsConfig::default(); let rp = if cfg!(target_os = "windows") { diff --git a/src/lsp.rs b/src/lsp.rs index 37a5f6b..62bf5a9 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -385,6 +385,18 @@ impl ProtoLanguageServer { params: WorkspaceSymbolParams, ) -> BoxFuture<'static, Result, ResponseError>> { let query = params.query.to_lowercase(); + let work_done_token = params.work_done_progress_params.work_done_token; + + // Parse all files from all workspaces + let workspaces = self.configs.get_workspaces(); + let progress_sender = work_done_token.map(|token| self.with_report_progress(token)); + + for workspace in workspaces { + if let Ok(workspace_path) = workspace.to_file_path() { + self.state + .parse_all_from_workspace(workspace_path, progress_sender.clone()); + } + } let symbols = self.state.find_workspace_symbols(&query); From 0f8013f208d0495b9379ac86ce6951d855235a8a Mon Sep 17 00:00:00 2001 From: Ashar Date: Sun, 23 Nov 2025 13:13:56 +0530 Subject: [PATCH 4/5] fix: redact file paths from test --- Cargo.lock | 122 ++++++++++++++++++ Cargo.toml | 2 +- src/state.rs | 4 +- src/workspace/definition.rs | 14 +- ...on__test__workspace_test_definition-5.snap | 12 ++ ...__workspace_symbol__test__all_symbols.snap | 68 ---------- ...ace_symbol__test__workspace_symbols-2.snap | 15 +++ ...ace_symbol__test__workspace_symbols-3.snap | 16 +++ ...space_symbol__test__workspace_symbols.snap | 83 ++++++++++++ src/workspace/workspace_symbol.rs | 67 +++++++++- 10 files changed, 316 insertions(+), 87 deletions(-) create mode 100644 src/workspace/snapshots/protols__workspace__definition__test__workspace_test_definition-5.snap create mode 100644 src/workspace/snapshots/protols__workspace__workspace_symbol__test__workspace_symbols-2.snap create mode 100644 src/workspace/snapshots/protols__workspace__workspace_symbol__test__workspace_symbols-3.snap create mode 100644 src/workspace/snapshots/protols__workspace__workspace_symbol__test__workspace_symbols.snap diff --git a/Cargo.lock b/Cargo.lock index d55d6c1..5b95e2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -138,6 +138,15 @@ version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bytes" version = "1.10.1" @@ -218,6 +227,15 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -233,6 +251,16 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "deranged" version = "0.5.3" @@ -242,6 +270,16 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -385,6 +423,16 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.3.3" @@ -565,6 +613,8 @@ checksum = "46fdb647ebde000f43b5b53f773c30cf9b0cb4300453208713fa38b2c70935a0" dependencies = [ "console", "once_cell", + "pest", + "pest_derive", "serde", "similar", ] @@ -742,6 +792,49 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "pest" +version = "2.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f72981ade67b1ca6adc26ec221be9f463f2b5839c7508998daa17c23d94d7f" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee9efd8cdb50d719a80088b76f81aec7c41ed6d522ee750178f83883d271625" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "pest_meta" +version = "2.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82" +dependencies = [ + "pest", + "sha2", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -957,6 +1050,17 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -1329,6 +1433,18 @@ dependencies = [ "tree-sitter-language", ] +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + [[package]] name = "unicode-ident" version = "1.0.19" @@ -1365,6 +1481,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "waitpid-any" version = "0.3.0" diff --git a/Cargo.toml b/Cargo.toml index 17e29c4..a02e0fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,4 +32,4 @@ pkg-config = "0.3" clap = { version = "4.5", features = ["derive"] } [dev-dependencies] -insta = { version = "1.43", features = ["yaml"] } +insta = { version = "1.43", features = ["yaml", "redactions"] } diff --git a/src/state.rs b/src/state.rs index 9c9b849..9075fc9 100644 --- a/src/state.rs +++ b/src/state.rs @@ -5,7 +5,7 @@ use std::{ }; use tracing::info; -use async_lsp::lsp_types::ProgressParamsValue; +use async_lsp::lsp_types::{DocumentSymbol, ProgressParamsValue}; use async_lsp::lsp_types::{ CompletionItem, CompletionItemKind, Location, OneOf, PublishDiagnosticsParams, Url, WorkspaceSymbol, @@ -108,7 +108,7 @@ impl ProtoLanguageState { fn collect_workspace_symbols( &self, - doc_symbol: &async_lsp::lsp_types::DocumentSymbol, + doc_symbol: &DocumentSymbol, uri: &Url, query: &str, container_name: Option, diff --git a/src/workspace/definition.rs b/src/workspace/definition.rs index f23131e..4558529 100644 --- a/src/workspace/definition.rs +++ b/src/workspace/definition.rs @@ -60,7 +60,7 @@ mod test { use crate::context::jumpable::Jumpable; use std::path::PathBuf; - use insta::assert_yaml_snapshot; + use insta::{assert_yaml_snapshot}; use crate::config::Config; use crate::state::ProtoLanguageState; @@ -107,13 +107,9 @@ mod test { Jumpable::Import("c.proto".to_owned()), ); - assert_eq!(loc.len(), 1); - assert!( - loc[0] - .uri - .to_file_path() - .unwrap() - .ends_with(ipath[0].join("c.proto")) - ) + assert_yaml_snapshot!(loc, {"[0].uri" => insta::dynamic_redaction(|c, _| { + assert!(c.as_str().unwrap().ends_with("c.proto")); + "file:///c.proto".to_string() + })}); } } diff --git a/src/workspace/snapshots/protols__workspace__definition__test__workspace_test_definition-5.snap b/src/workspace/snapshots/protols__workspace__definition__test__workspace_test_definition-5.snap new file mode 100644 index 0000000..401acac --- /dev/null +++ b/src/workspace/snapshots/protols__workspace__definition__test__workspace_test_definition-5.snap @@ -0,0 +1,12 @@ +--- +source: src/workspace/definition.rs +expression: loc +--- +- uri: "file:///c.proto" + range: + start: + line: 0 + character: 0 + end: + line: 0 + character: 0 diff --git a/src/workspace/snapshots/protols__workspace__workspace_symbol__test__all_symbols.snap b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__all_symbols.snap index 956d29d..f40ba5b 100644 --- a/src/workspace/snapshots/protols__workspace__workspace_symbol__test__all_symbols.snap +++ b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__all_symbols.snap @@ -2,18 +2,6 @@ source: src/workspace/workspace_symbol.rs expression: all_symbols --- -- name: Address - kind: 23 - containerName: Author - location: - uri: "file:///home/runner/work/protols/protols/src/workspace/input/b.proto" - range: - start: - line: 9 - character: 3 - end: - line: 11 - character: 4 - name: Address kind: 23 containerName: Author @@ -26,17 +14,6 @@ expression: all_symbols end: line: 11 character: 4 -- name: Author - kind: 23 - location: - uri: "file:///home/runner/work/protols/protols/src/workspace/input/b.proto" - range: - start: - line: 5 - character: 0 - end: - line: 14 - character: 1 - name: Author kind: 23 location: @@ -48,18 +25,6 @@ expression: all_symbols end: line: 14 character: 1 -- name: Baz - kind: 23 - containerName: Foobar - location: - uri: "file:///home/runner/work/protols/protols/src/workspace/input/c.proto" - range: - start: - line: 8 - character: 3 - end: - line: 10 - character: 4 - name: Baz kind: 23 containerName: Foobar @@ -83,17 +48,6 @@ expression: all_symbols end: line: 14 character: 1 -- name: Foobar - kind: 23 - location: - uri: "file:///home/runner/work/protols/protols/src/workspace/input/c.proto" - range: - start: - line: 5 - character: 0 - end: - line: 13 - character: 1 - name: Foobar kind: 23 location: @@ -105,25 +59,3 @@ expression: all_symbols end: line: 13 character: 1 -- name: SomeSecret - kind: 23 - location: - uri: "file:///home/runner/work/protols/protols/src/workspace/input/inner/secret/y.proto" - range: - start: - line: 5 - character: 0 - end: - line: 7 - character: 1 -- name: Why - kind: 23 - location: - uri: "file:///home/runner/work/protols/protols/src/workspace/input/inner/x.proto" - range: - start: - line: 7 - character: 0 - end: - line: 11 - character: 1 diff --git a/src/workspace/snapshots/protols__workspace__workspace_symbol__test__workspace_symbols-2.snap b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__workspace_symbols-2.snap new file mode 100644 index 0000000..807e053 --- /dev/null +++ b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__workspace_symbols-2.snap @@ -0,0 +1,15 @@ +--- +source: src/workspace/workspace_symbol.rs +expression: author_symbols +--- +- name: Author + kind: 23 + location: + uri: "file:///src/workspace/input/b.proto" + range: + start: + line: 5 + character: 0 + end: + line: 14 + character: 1 diff --git a/src/workspace/snapshots/protols__workspace__workspace_symbol__test__workspace_symbols-3.snap b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__workspace_symbols-3.snap new file mode 100644 index 0000000..629e820 --- /dev/null +++ b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__workspace_symbols-3.snap @@ -0,0 +1,16 @@ +--- +source: src/workspace/workspace_symbol.rs +expression: address_symbols +--- +- name: Address + kind: 23 + containerName: Author + location: + uri: "file:///src/workspace/input/b.proto" + range: + start: + line: 9 + character: 3 + end: + line: 11 + character: 4 diff --git a/src/workspace/snapshots/protols__workspace__workspace_symbol__test__workspace_symbols.snap b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__workspace_symbols.snap new file mode 100644 index 0000000..0fb8224 --- /dev/null +++ b/src/workspace/snapshots/protols__workspace__workspace_symbol__test__workspace_symbols.snap @@ -0,0 +1,83 @@ +--- +source: src/workspace/workspace_symbol.rs +expression: all_symbols +--- +- name: Address + kind: 23 + containerName: Author + location: + uri: "file:///src/workspace/input/b.proto" + range: + start: + line: 9 + character: 3 + end: + line: 11 + character: 4 +- name: Author + kind: 23 + location: + uri: "file:///src/workspace/input/b.proto" + range: + start: + line: 5 + character: 0 + end: + line: 14 + character: 1 +- name: Baz + kind: 23 + containerName: Foobar + location: + uri: "file:///src/workspace/input/c.proto" + range: + start: + line: 8 + character: 3 + end: + line: 10 + character: 4 +- name: Book + kind: 23 + location: + uri: "file:///src/workspace/input/a.proto" + range: + start: + line: 9 + character: 0 + end: + line: 14 + character: 1 +- name: Foobar + kind: 23 + location: + uri: "file:///src/workspace/input/c.proto" + range: + start: + line: 5 + character: 0 + end: + line: 13 + character: 1 +- name: SomeSecret + kind: 23 + location: + uri: "file:///src/workspace/input/y.proto" + range: + start: + line: 5 + character: 0 + end: + line: 7 + character: 1 +- name: Why + kind: 23 + location: + uri: "file:///src/workspace/input/x.proto" + range: + start: + line: 7 + character: 0 + end: + line: 11 + character: 1 diff --git a/src/workspace/workspace_symbol.rs b/src/workspace/workspace_symbol.rs index 1cc967c..a353d76 100644 --- a/src/workspace/workspace_symbol.rs +++ b/src/workspace/workspace_symbol.rs @@ -1,16 +1,33 @@ #[cfg(test)] mod test { use insta::assert_yaml_snapshot; + use insta::internals::{Content, ContentPath}; use crate::config::Config; use crate::state::ProtoLanguageState; #[test] fn test_workspace_symbols() { - let ipath = vec![std::env::current_dir().unwrap().join("src/workspace/input")]; - let a_uri = "file://input/a.proto".parse().unwrap(); - let b_uri = "file://input/b.proto".parse().unwrap(); - let c_uri = "file://input/c.proto".parse().unwrap(); + let current_dir = std::env::current_dir().unwrap(); + let ipath = vec![current_dir.join("src/workspace/input")]; + let a_uri = (&format!( + "file://{}/src/workspace/input/a.proto", + current_dir.to_str().unwrap() + )) + .parse() + .unwrap(); + let b_uri = (&format!( + "file://{}/src/workspace/input/b.proto", + current_dir.to_str().unwrap() + )) + .parse() + .unwrap(); + let c_uri = (&format!( + "file://{}/src/workspace/input/c.proto", + current_dir.to_str().unwrap() + )) + .parse() + .unwrap(); let a = include_str!("input/a.proto"); let b = include_str!("input/b.proto"); @@ -23,15 +40,51 @@ mod test { // Test empty query - should return all symbols let all_symbols = state.find_workspace_symbols(""); - assert_yaml_snapshot!("all_symbols", all_symbols); + let cdir = current_dir.to_str().unwrap().to_string(); + assert_yaml_snapshot!(all_symbols, { "[].location.uri" => insta::dynamic_redaction(move |c, _| { + assert!( + c.as_str() + .unwrap() + .contains(&cdir) + ); + format!( + "file://{}/src/workspace/input/{}", + "", + c.as_str().unwrap().split('/').last().unwrap() + ) + + })}); // Test query for "author" - should match Author and Address let author_symbols = state.find_workspace_symbols("author"); - assert_yaml_snapshot!("author_symbols", author_symbols); + let cdir = current_dir.to_str().unwrap().to_string(); + assert_yaml_snapshot!(author_symbols, {"[].location.uri" => insta::dynamic_redaction(move |c ,_|{ + assert!( + c.as_str() + .unwrap() + .contains(&cdir) + ); + format!( + "file://{}/src/workspace/input/{}", + "", + c.as_str().unwrap().split('/').last().unwrap() + ) + })}); // Test query for "address" - should match Address let address_symbols = state.find_workspace_symbols("address"); - assert_yaml_snapshot!("address_symbols", address_symbols); + assert_yaml_snapshot!(address_symbols, {"[].location.uri" => insta::dynamic_redaction(move |c ,_|{ + assert!( + c.as_str() + .unwrap() + .contains(¤t_dir.to_str().unwrap()) + ); + format!( + "file://{}/src/workspace/input/{}", + "", + c.as_str().unwrap().split('/').last().unwrap() + ) + })}); // Test query that should not match anything let no_match = state.find_workspace_symbols("nonexistent"); From a3603244291719754d1ea66fe904a74162f6226f Mon Sep 17 00:00:00 2001 From: Ashar Date: Sun, 23 Nov 2025 13:21:40 +0530 Subject: [PATCH 5/5] ci: fix linting + formatting --- src/state.rs | 15 ++++++++++----- src/workspace/definition.rs | 2 +- src/workspace/workspace_symbol.rs | 9 +++------ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/state.rs b/src/state.rs index 9075fc9..9d89a31 100644 --- a/src/state.rs +++ b/src/state.rs @@ -5,11 +5,11 @@ use std::{ }; use tracing::info; -use async_lsp::lsp_types::{DocumentSymbol, ProgressParamsValue}; use async_lsp::lsp_types::{ CompletionItem, CompletionItemKind, Location, OneOf, PublishDiagnosticsParams, Url, WorkspaceSymbol, }; +use async_lsp::lsp_types::{DocumentSymbol, ProgressParamsValue}; use std::sync::mpsc::Sender; use tree_sitter::Node; use walkdir::WalkDir; @@ -84,7 +84,13 @@ impl ProtoLanguageState { let doc_symbols = tree.find_document_locations(content.as_bytes()); for doc_symbol in doc_symbols { - self.collect_workspace_symbols(&doc_symbol, &tree.uri, query, None, &mut symbols); + Self::find_workspace_symbols_impl( + &doc_symbol, + &tree.uri, + query, + None, + &mut symbols, + ); } } @@ -106,8 +112,7 @@ impl ProtoLanguageState { symbols } - fn collect_workspace_symbols( - &self, + fn find_workspace_symbols_impl( doc_symbol: &DocumentSymbol, uri: &Url, query: &str, @@ -132,7 +137,7 @@ impl ProtoLanguageState { if let Some(children) = &doc_symbol.children { for child in children { - self.collect_workspace_symbols( + Self::find_workspace_symbols_impl( child, uri, query, diff --git a/src/workspace/definition.rs b/src/workspace/definition.rs index 4558529..c541d75 100644 --- a/src/workspace/definition.rs +++ b/src/workspace/definition.rs @@ -60,7 +60,7 @@ mod test { use crate::context::jumpable::Jumpable; use std::path::PathBuf; - use insta::{assert_yaml_snapshot}; + use insta::assert_yaml_snapshot; use crate::config::Config; use crate::state::ProtoLanguageState; diff --git a/src/workspace/workspace_symbol.rs b/src/workspace/workspace_symbol.rs index a353d76..5a57b15 100644 --- a/src/workspace/workspace_symbol.rs +++ b/src/workspace/workspace_symbol.rs @@ -48,8 +48,7 @@ mod test { .contains(&cdir) ); format!( - "file://{}/src/workspace/input/{}", - "", + "file:///src/workspace/input/{}", c.as_str().unwrap().split('/').last().unwrap() ) @@ -65,8 +64,7 @@ mod test { .contains(&cdir) ); format!( - "file://{}/src/workspace/input/{}", - "", + "file:///src/workspace/input/{}", c.as_str().unwrap().split('/').last().unwrap() ) })}); @@ -80,8 +78,7 @@ mod test { .contains(¤t_dir.to_str().unwrap()) ); format!( - "file://{}/src/workspace/input/{}", - "", + "file:///src/workspace/input/{}", c.as_str().unwrap().split('/').last().unwrap() ) })});