diff --git a/docs/src/content/docs/en/user-guide/features/references.mdx b/docs/src/content/docs/en/user-guide/features/references.mdx index 3773f8a1..3baf09b3 100644 --- a/docs/src/content/docs/en/user-guide/features/references.mdx +++ b/docs/src/content/docs/en/user-guide/features/references.mdx @@ -45,6 +45,18 @@ Vide searches references in all Verilog/SystemVerilog files scanned from the wor After `vide.toml` is configured, reference search follows the project scope described by `sources` and `libraries`, and uses include directories and macro definitions to decide which files participate in analysis. +## Result Display + +By default, the references view also includes the declaration location so you can confirm where the symbol comes from. If you want usage locations only, add this to VS Code Settings: + +```json +{ + "vide.references.includeDeclaration": false +} +``` + +See [Scope settings](../../vscode-settings/#scope) for the full reference. + ## Relationship to Rename Find References only shows locations and does not modify files. Rename edits declarations and references, so it usually needs `vide.toml` to make the editable project scope explicit. diff --git a/docs/src/content/docs/en/user-guide/vscode-settings.mdx b/docs/src/content/docs/en/user-guide/vscode-settings.mdx index 2a664429..d1a5d139 100644 --- a/docs/src/content/docs/en/user-guide/vscode-settings.mdx +++ b/docs/src/content/docs/en/user-guide/vscode-settings.mdx @@ -16,6 +16,7 @@ All settings are under the `vide.*` namespace. Search for `Vide` in the VS Code | Point VS Code at a local Qihe executable | `vide.qihe.command` | | Point Vide at `verible-verilog-format` | `vide.formatter.path` | | Refresh diagnostics on save or while typing | `vide.diagnostics.update` | +| Show usage locations only in Find References | `vide.references.includeDeclaration` | | Toggle port, parameter, and end-structure annotations | `vide.inlayHints.*` | | Toggle instance-count annotations above module declarations | `vide.lens.instantiations.enable` | | Refresh project information after configuration changes | `vide.workspace.auto.reload` | @@ -71,11 +72,14 @@ Related docs: [Configure the First Project](../first-project/) and [Project Conf ## Scope -This setting affects local-symbol visibility in find references, rename, and document highlights. Keep the default when unsure. +These settings affect local-symbol visibility in find references, rename, and document highlights, and whether the declaration location is included in reference results. Keep the defaults when unsure. Related features: [Find References](../features/references/) and [Rename](../features/rename/). - + ## Formatter and Formatting diff --git a/docs/src/content/docs/user-guide/features/references.mdx b/docs/src/content/docs/user-guide/features/references.mdx index 3cea6ca5..350887ad 100644 --- a/docs/src/content/docs/user-guide/features/references.mdx +++ b/docs/src/content/docs/user-guide/features/references.mdx @@ -44,3 +44,15 @@ Vide 会在工作区扫描到的所有 Verilog/SystemVerilog 文件中查找引 ### 有完整配置时 写好 `vide.toml` 后,引用搜索会按 `sources` 和 `libraries` 描述的工程范围执行,并结合 include 目录和宏定义判断实际参与分析的文件。 + +## 结果显示 + +默认情况下,引用结果会把声明位置一起显示,方便你从列表里确认符号是从哪里引入的。如果你只想看真正的使用位置,可以在 VS Code Settings 中写: + +```json +{ + "vide.references.includeDeclaration": false +} +``` + +完整参考见 [Scope 设置](../../vscode-settings/#scope)。 diff --git a/docs/src/content/docs/user-guide/vscode-settings.mdx b/docs/src/content/docs/user-guide/vscode-settings.mdx index e97cc0db..285e79e6 100644 --- a/docs/src/content/docs/user-guide/vscode-settings.mdx +++ b/docs/src/content/docs/user-guide/vscode-settings.mdx @@ -16,6 +16,7 @@ VS Code 设置控制编辑器里的行为,例如诊断刷新、Qihe 命令、 | 让 VS Code 调用本机的 Qihe | `vide.qihe.command` | | 指定本机的 `verible-verilog-format` | `vide.formatter.path` | | 控制诊断刷新是保存后还是输入时 | `vide.diagnostics.update` | +| 让引用搜索只显示实际使用位置 | `vide.references.includeDeclaration` | | 开关端口、参数、结构结尾的代码注解 | `vide.inlayHints.*` | | 开关模块声明上方的实例数量注解 | `vide.lens.instantiations.enable` | | 项目配置变化后是否自动刷新 | `vide.workspace.auto.reload` | @@ -71,11 +72,14 @@ VS Code 设置控制编辑器里的行为,例如诊断刷新、Qihe 命令、 ## Scope -这组设置会影响引用搜索、重命名和当前位置高亮里的局部符号可见性;常规使用保持默认值即可。 +这组设置会影响引用搜索、重命名和当前位置高亮里的局部符号可见性,以及引用搜索是否把声明位置一起显示;常规使用保持默认值即可。 相关功能:[引用搜索](../features/references/) 和 [重命名](../features/rename/)。 - + ## Formatter 和 Formatting diff --git a/editors/vscode/package.json b/editors/vscode/package.json index 38863088..3323aae1 100644 --- a/editors/vscode/package.json +++ b/editors/vscode/package.json @@ -199,6 +199,11 @@ "default": "private", "description": "%configuration.scope.visibility.description%" }, + "vide.references.includeDeclaration": { + "type": "boolean", + "default": true, + "description": "%configuration.references.includeDeclaration.description%" + }, "vide.formatter.provider": { "type": "string", "enum": [ diff --git a/editors/vscode/package.nls.json b/editors/vscode/package.nls.json index 9128628e..61f12fe2 100644 --- a/editors/vscode/package.nls.json +++ b/editors/vscode/package.nls.json @@ -16,6 +16,7 @@ "configuration.files.watcher.description": "Controls how Vide watches project files.", "configuration.workspace.auto.reload.description": "Automatically refresh project information when project manifests change.", "configuration.scope.visibility.description": "Controls whether symbols inside scopes, except ports, are visible outside those scopes.", + "configuration.references.includeDeclaration.description": "Include declarations when finding references.", "configuration.formatter.provider.enum.verible": "Use an external verible-verilog-format executable. Supports Format Document and Format Selection.", "configuration.formatter.provider.description": "Formatter backend used by Vide.", "configuration.formatter.path.description": "Path to verible-verilog-format when vide.formatter.provider is verible. Leave empty to find it on PATH.", diff --git a/editors/vscode/package.nls.zh-cn.json b/editors/vscode/package.nls.zh-cn.json index ad889f7a..8d151564 100644 --- a/editors/vscode/package.nls.zh-cn.json +++ b/editors/vscode/package.nls.zh-cn.json @@ -16,6 +16,7 @@ "configuration.files.watcher.description": "控制 Vide 如何监视项目文件。", "configuration.workspace.auto.reload.description": "项目配置文件变化时自动刷新项目信息。", "configuration.scope.visibility.description": "控制作用域内除端口以外的符号是否在作用域外可见。", + "configuration.references.includeDeclaration.description": "查找引用时是否包含声明位置。", "configuration.formatter.provider.enum.verible": "使用外部 verible-verilog-format 可执行文件。支持格式化文档和格式化选区。", "configuration.formatter.provider.description": "Vide 使用的格式化后端。", "configuration.formatter.path.description": "当 vide.formatter.provider 为 verible 时,verible-verilog-format 的路径。留空则从 PATH 中查找。", diff --git a/editors/vscode/src/extension.ts b/editors/vscode/src/extension.ts index 08362f11..24774756 100644 --- a/editors/vscode/src/extension.ts +++ b/editors/vscode/src/extension.ts @@ -381,6 +381,14 @@ function readConfiguration(): ServerConfiguration { }; } +function includeDeclarationInReferences(document: vscode.TextDocument): boolean { + return ( + vscode.workspace + .getConfiguration('vide', document) + .get('references.includeDeclaration') ?? true + ); +} + function resolveWorkingDirectory( context: vscode.ExtensionContext, configuredCwd: string | undefined, @@ -649,6 +657,12 @@ async function createClient(context: vscode.ExtensionContext): Promise { + options.includeDeclaration = includeDeclarationInReferences(document); + return await next(document, position, options, token); + }, + }, ...(config.trace !== 'off' && { trace: config.trace }), }; diff --git a/editors/vscode/test/configuration.test.ts b/editors/vscode/test/configuration.test.ts index 3fde3c48..af3e6e34 100644 --- a/editors/vscode/test/configuration.test.ts +++ b/editors/vscode/test/configuration.test.ts @@ -90,6 +90,7 @@ test('contributes settings for the complete Vide user configuration surface', () 'vide.files.watcher', 'vide.workspace.auto.reload', 'vide.scope.visibility', + 'vide.references.includeDeclaration', 'vide.formatter.provider', 'vide.formatter.path', 'vide.formatter.args', diff --git a/src/global_state/handlers/request.rs b/src/global_state/handlers/request.rs index a5e4dcef..a24c2ffe 100644 --- a/src/global_state/handlers/request.rs +++ b/src/global_state/handlers/request.rs @@ -347,6 +347,7 @@ pub(crate) fn handle_references( snap: GlobalStateSnapshot, params: lsp_types::ReferenceParams, ) -> anyhow::Result>> { + let include_declaration = params.context.include_declaration; let position = from_proto::file_position(&snap, params.text_document_position)?; let config = snap.config.references(); let Some(refs) = snap.analysis.references(position, config)? else { @@ -356,9 +357,8 @@ pub(crate) fn handle_references( let locations = refs .into_iter() .flat_map(|References { def, refs }| { - let decl = def + let decl = if include_declaration { def.unwrap_or_default() } else { Vec::new() } .into_iter() - .flatten() .map(|nav| FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() }); let refs = refs.into_iter().flat_map(|(file_id, refs)| { diff --git a/src/tests.rs b/src/tests.rs index e861ff1f..9ccc2b0c 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -420,6 +420,17 @@ fn request_reference_uris( text: &str, needle: &str, request_id: i32, +) -> Vec { + request_reference_uris_with_include_declaration(client, uri, text, needle, request_id, true) +} + +fn request_reference_uris_with_include_declaration( + client: &Connection, + uri: Url, + text: &str, + needle: &str, + request_id: i32, + include_declaration: bool, ) -> Vec { let request_id = lsp_server::RequestId::from(request_id); client @@ -432,7 +443,7 @@ fn request_reference_uris( text_document: TextDocumentIdentifier { uri }, position: position_of(text, needle), }, - context: lsp_types::ReferenceContext { include_declaration: true }, + context: lsp_types::ReferenceContext { include_declaration }, work_done_progress_params: WorkDoneProgressParams::default(), partial_result_params: Default::default(), }, @@ -3255,3 +3266,61 @@ fn include_expanded_parameter_decls_keep_module_navigation_available() { shutdown_test_server(&client, server_thread); } + +#[test] +fn references_request_respects_include_declaration() { + let temp_dir = TempDir::new("references-include-declaration"); + let rtl_dir = temp_dir.path().join("rtl"); + fs::create_dir_all(&rtl_dir).unwrap(); + + let top_text = "module top;\n child u_child();\nendmodule\n"; + let child_text = "module child();\nendmodule\n"; + + fs::write( + temp_dir.path().join("vide.toml"), + "top_modules = [\"top\"]\nsources = [\"rtl/*.v\"]\ninclude_dirs = [\"rtl\"]\n", + ) + .unwrap(); + let top_path = rtl_dir.join("top.v"); + let child_path = rtl_dir.join("child.v"); + fs::write(&top_path, top_text).unwrap(); + fs::write(&child_path, child_text).unwrap(); + + let root_path = temp_dir.path().to_path_buf(); + let (client, server_thread) = + spawn_test_workspace(root_path, ClientCapabilities::default(), UserConfig::default()); + let top_uri = to_proto::url_from_abs_path(top_path.as_path()).unwrap(); + let child_uri = to_proto::url_from_abs_path(child_path.as_path()).unwrap(); + + open_test_document(&client, top_uri.clone(), top_text); + open_test_document(&client, child_uri.clone(), child_text); + let _ = request_document_diagnostics(&client, top_uri.clone(), 1); + + let refs_with_decl = request_reference_uris_with_include_declaration( + &client, + child_uri.clone(), + child_text, + "child()", + 2, + true, + ); + assert!( + refs_with_decl.contains(&child_uri) && refs_with_decl.contains(&top_uri), + "include_declaration=true should include the declaration and instantiation: {refs_with_decl:?}" + ); + + let refs_without_decl = request_reference_uris_with_include_declaration( + &client, + child_uri.clone(), + child_text, + "child()", + 3, + false, + ); + assert!( + !refs_without_decl.contains(&child_uri) && refs_without_decl.contains(&top_uri), + "include_declaration=false should exclude the declaration while keeping instantiations: {refs_without_decl:?}" + ); + + shutdown_test_server(&client, server_thread); +}