fix(lsp): Find usages in unopened files outside the language server's scope (#89)

Reference-based features only asked the language server, which analyses its configured scope (e.g. Pyright's `include`) plus open files, so usages in unopened files outside that scope were silently missing.

Find Usages, Show Usages, usage counts, Safe Delete of a symbol, Rename and incoming calls now also search project files that contain the symbol's name (whole word, same language, .gitignore/excludes respected, unsaved edits included, up to 300 files, cancellable). Candidates the first answer didn't cover are opened in the server temporarily, queried and closed again. Files the user has open are never touched, and diagnostics for the temporary files are dropped. An empty result while the server is still indexing is retried once indexing ends. When results may still be incomplete (indexing, file cap), the usages UI says so. `lsp_references` takes a RequestId and is cancelled by newer searches. Not covered yet: the Safe Delete scan when deleting a file or directory.

Fixes #83

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
Цей коміт міститься в:
l0ng-ai authored and GitHub committed 2026-10-27 17:41:20 +08:00
1 джерело 482f391fd1
коміт 8ec35c94ec
17 files changed
+1116 -97

No files matched your search

+18 -1
Переглянути файл
@@ -287,7 +287,12 @@ export const commands = {
* language server returned a non-`file:` URI for. Cached per project.
*/
lspVirtualDocument: (uri: string) => typedError<VirtualDocument, IdeError>(__TAURI_INVOKE("lsp_virtual_document", { uri })),
lspReferences: (doc: DocId, pos: Pos, includeDeclaration: boolean) => typedError<Location[], IdeError>(__TAURI_INVOKE("lsp_references", { doc, pos, includeDeclaration })),
/**
* References of the symbol at `pos`. `project_wide` also searches project files
* outside the language server's analysis scope; bulk scans over many symbols
* leave it off. Cancel with `cancel_request(request)`.
*/
lspReferences: (request: RequestId, doc: DocId, pos: Pos, includeDeclaration: boolean, projectWide: boolean) => typedError<References, IdeError>(__TAURI_INVOKE("lsp_references", { request, doc, pos, includeDeclaration, projectWide })),
lspDocumentHighlights: (doc: DocId, pos: Pos) => typedError<Highlight[], IdeError>(__TAURI_INVOKE("lsp_document_highlights", { doc, pos })),
lspWorkspaceSymbols: (request: RequestId, query: string) => typedError<WorkspaceSymbol[], IdeError>(__TAURI_INVOKE("lsp_workspace_symbols", { request, query })),
lspCodeActions: (doc: DocId, range: Range, only: string[]) => typedError<CodeAction[], IdeError>(__TAURI_INVOKE("lsp_code_actions", { doc, range, only })),
@@ -4175,6 +4180,18 @@ export type RecentProject = {
branch: string | null,
};
export type References = {
locations: Location[],
incomplete: ReferencesIncomplete | null,
};
/** Why a references search may have missed usages. */
export type ReferencesIncomplete =
/** A language server was still indexing. */
"indexing" |
/** More project files mention the name than were checked. */
"tooManyFiles";
export type Remote = {
name: string,
/** Fetch URL. */