diff --git a/internal/agent/tools/diagnostics.go b/internal/agent/tools/diagnostics.go index 9697cefb049c3184cff13fe9c3de4ce6dd12dfb6..79b67be95d3312af47a7d5bc1765cc320a9894d1 100644 --- a/internal/agent/tools/diagnostics.go +++ b/internal/agent/tools/diagnostics.go @@ -73,16 +73,13 @@ func waitForLSPDiagnostics( return } - waitCtx, cancel := context.WithTimeout(ctx, timeout) - defer cancel() - var wg sync.WaitGroup for client := range manager.Clients().Seq() { if !client.HandlesFile(filepath) { continue } wg.Go(func() { - client.WaitForDiagnostics(waitCtx, timeout) + client.WaitForDiagnostics(ctx, timeout) }) } wg.Wait() diff --git a/internal/agent/tools/references.go b/internal/agent/tools/references.go index c544886b9de3e60ef6932cbc2932fc0a0ab639f0..e8547264e6725a9062bf767e42f842595a2638dd 100644 --- a/internal/agent/tools/references.go +++ b/internal/agent/tools/references.go @@ -71,7 +71,11 @@ func NewReferencesTool(lspManager *lsp.Manager) fantasy.AgentTool { continue } allLocations = append(allLocations, locations...) - // XXX: should we break here or look for all results? + // Once we have results, we're done - LSP returns all references + // for the symbol, not just from this file. + if len(locations) > 0 { + break + } } if len(allLocations) > 0 { diff --git a/internal/lsp/client.go b/internal/lsp/client.go index bc8d31dba0360aed813d4b9cf6e5b769bb2559d4..ed2ea2633cf3482010ad32a8f2b06aeacb69b243 100644 --- a/internal/lsp/client.go +++ b/internal/lsp/client.go @@ -533,6 +533,11 @@ func (c *Client) FindReferences(ctx context.Context, filepath string, line, char if err := c.OpenFileOnDemand(ctx, filepath); err != nil { return nil, err } + + // Add timeout to prevent hanging on slow LSP servers. + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + // NOTE: line and character should be 0-based. // See: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#position return c.client.FindReferences(ctx, filepath, line-1, character-1, includeDeclaration)