From 1b9f682d26f3e541aee0396c0bc77ccfc937738f Mon Sep 17 00:00:00 2001
From: i582 <51853996+i582@users.noreply.github.com>
Date: Sun, 9 Feb 2025 14:41:56 +0400
Subject: [PATCH] fix(completion): add setting for "Find Usages" scope

Fixes #153
---
 package.json                 | 13 +++++++++++++
 server/src/server.ts         | 13 ++++++++++++-
 server/src/utils/settings.ts | 11 +++++++++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/package.json b/package.json
index b2896efe..14e31e76 100644
--- a/package.json
+++ b/package.json
@@ -243,6 +243,19 @@
                     "type": "boolean",
                     "default": true,
                     "description": "Show message fields in document outline"
+                },
+                "tact.findUsages.scope": {
+                    "type": "string",
+                    "enum": [
+                        "workspace",
+                        "everywhere"
+                    ],
+                    "enumDescriptions": [
+                        "Search only in workspace files (default)",
+                        "Search everywhere including standard library"
+                    ],
+                    "default": "workspace",
+                    "description": "Where to search when using Find Usages"
                 }
             }
         },
diff --git a/server/src/server.ts b/server/src/server.ts
index 0e33ac1a..ba4f5d5c 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -868,7 +868,7 @@ connection.onInitialize(async (params: lsp.InitializeParams): Promise<lsp.Initia
 
     connection.onRequest(
         lsp.ReferencesRequest.type,
-        (params: lsp.ReferenceParams): lsp.Location[] | null => {
+        async (params: lsp.ReferenceParams): Promise<lsp.Location[] | null> => {
             const uri = params.textDocument.uri
 
             if (uri.endsWith(".fif")) {
@@ -900,6 +900,17 @@ connection.onInitialize(async (params: lsp.InitializeParams): Promise<lsp.Initia
             const result = new Referent(referenceNode, file).findReferences(false)
             if (result.length === 0) return null
 
+            const settings = await getDocumentSettings(file.uri)
+            if (settings.findUsages.scope === "workspace") {
+                // filter out references from stdlib
+                return result
+                    .filter(value => !value.file.fromStdlib && !value.file.fromStubs)
+                    .map(value => ({
+                        uri: value.file.uri,
+                        range: asLspRange(value.node),
+                    }))
+            }
+
             return result.map(value => ({
                 uri: value.file.uri,
                 range: asLspRange(value.node),
diff --git a/server/src/utils/settings.ts b/server/src/utils/settings.ts
index d6f5a64a..55c242a0 100644
--- a/server/src/utils/settings.ts
+++ b/server/src/utils/settings.ts
@@ -1,9 +1,14 @@
 import {connection} from "@server/connection"
 
+export type FindUsagesScope = "workspace" | "everywhere"
+
 export interface TactSettings {
     stdlib: {
         path: string | null
     }
+    findUsages: {
+        scope: FindUsagesScope
+    }
     hints: {
         types: boolean
         parameters: boolean
@@ -47,6 +52,9 @@ const defaultSettings: TactSettings = {
     stdlib: {
         path: null,
     },
+    findUsages: {
+        scope: "workspace",
+    },
     hints: {
         types: true,
         parameters: true,
@@ -93,6 +101,9 @@ function mergeSettings(vsSettings: Partial<TactSettings>): TactSettings {
         stdlib: {
             path: vsSettings.stdlib?.path ?? defaultSettings.stdlib.path,
         },
+        findUsages: {
+            scope: vsSettings.findUsages?.scope ?? defaultSettings.findUsages.scope,
+        },
         hints: {
             types: vsSettings.hints?.types ?? defaultSettings.hints.types,
             parameters: vsSettings.hints?.parameters ?? defaultSettings.hints.parameters,