Skip to content

Commit e30fba0

Browse files
thdxropencode
andcommitted
Improve LSP server initialization with timeout handling and skip failed servers
🤖 Generated with [opencode](https://opencode.ai) Co-Authored-By: opencode <[email protected]>
1 parent 7fbb2ca commit e30fba0

File tree

3 files changed

+50
-28
lines changed

3 files changed

+50
-28
lines changed

packages/opencode/src/cli/cmd/run.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,6 @@ export const RunCommand = {
115115
})
116116

117117
const { providerID, modelID } = await Provider.defaultModel()
118-
setTimeout(() => {
119-
Session.abort(session.id)
120-
}, 8000)
121118
await Session.chat({
122119
sessionID: session.id,
123120
providerID,

packages/opencode/src/lsp/client.ts

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { LANGUAGE_EXTENSIONS } from "./language"
1111
import { Bus } from "../bus"
1212
import z from "zod"
1313
import type { LSPServer } from "./server"
14+
import { NamedError } from "../util/error"
1415

1516
export namespace LSPClient {
1617
const log = Log.create({ service: "lsp.client" })
@@ -19,6 +20,13 @@ export namespace LSPClient {
1920

2021
export type Diagnostic = VSCodeDiagnostic
2122

23+
export const InitializeError = NamedError.create(
24+
"LSPInitializeError",
25+
z.object({
26+
serverID: z.string(),
27+
}),
28+
)
29+
2230
export const Event = {
2331
Diagnostics: Bus.event(
2432
"lsp.client.diagnostics",
@@ -52,32 +60,40 @@ export namespace LSPClient {
5260
})
5361
connection.listen()
5462

55-
await connection.sendRequest("initialize", {
56-
processId: server.process.pid,
57-
workspaceFolders: [
58-
{
59-
name: "workspace",
60-
uri: "file://" + app.path.cwd,
61-
},
62-
],
63-
initializationOptions: {
64-
...server.initialization,
65-
},
66-
capabilities: {
67-
workspace: {
68-
configuration: true,
63+
log.info("sending initialize", { id: serverID })
64+
await Promise.race([
65+
connection.sendRequest("initialize", {
66+
processId: server.process.pid,
67+
workspaceFolders: [
68+
{
69+
name: "workspace",
70+
uri: "file://" + app.path.cwd,
71+
},
72+
],
73+
initializationOptions: {
74+
...server.initialization,
6975
},
70-
textDocument: {
71-
synchronization: {
72-
didOpen: true,
73-
didChange: true,
76+
capabilities: {
77+
workspace: {
78+
configuration: true,
7479
},
75-
publishDiagnostics: {
76-
versionSupport: true,
80+
textDocument: {
81+
synchronization: {
82+
didOpen: true,
83+
didChange: true,
84+
},
85+
publishDiagnostics: {
86+
versionSupport: true,
87+
},
7788
},
7889
},
79-
},
80-
})
90+
}),
91+
new Promise((_, reject) => {
92+
setTimeout(() => {
93+
reject(new InitializeError({ serverID }))
94+
}, 5_000)
95+
}),
96+
])
8197
await connection.sendNotification("initialized", {})
8298
log.info("initialized")
8399

packages/opencode/src/lsp/index.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ export namespace LSP {
1212
async () => {
1313
log.info("initializing")
1414
const clients = new Map<string, LSPClient.Info>()
15-
15+
const skip = new Set<string>()
1616
return {
1717
clients,
18+
skip,
1819
}
1920
},
2021
async (state) => {
@@ -31,11 +32,19 @@ export namespace LSP {
3132
x.extensions.includes(extension),
3233
)
3334
for (const match of matches) {
35+
if (s.skip.has(match.id)) continue
3436
const existing = s.clients.get(match.id)
3537
if (existing) continue
3638
const handle = await match.spawn(App.info())
37-
if (!handle) continue
38-
const client = await LSPClient.create(match.id, handle)
39+
if (!handle) {
40+
s.skip.add(match.id)
41+
continue
42+
}
43+
const client = await LSPClient.create(match.id, handle).catch(() => {})
44+
if (!client) {
45+
s.skip.add(match.id)
46+
continue
47+
}
3948
s.clients.set(match.id, client)
4049
}
4150
if (waitForDiagnostics) {

0 commit comments

Comments
 (0)