summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-06-06 17:20:01 -0400
committerDax Raad <[email protected]>2025-06-06 17:20:08 -0400
commitd6afebf22a66958393f25caa33236c345584c79d (patch)
tree8a6b7e61c082422014e34387ba634264267b230b
parentb32cb2b9326eb4a1c441507e2c8bf21ca475f5cc (diff)
downloadopencode-d6afebf22a66958393f25caa33236c345584c79d.tar.gz
opencode-d6afebf22a66958393f25caa33236c345584c79d.zip
make lsp better
-rw-r--r--packages/opencode/src/bus/index.ts12
-rw-r--r--packages/opencode/src/cli/cmd/scrap.ts5
-rw-r--r--packages/opencode/src/lsp/client.ts16
-rw-r--r--packages/opencode/src/lsp/index.ts14
-rw-r--r--packages/opencode/src/tool/edit.ts2
-rw-r--r--packages/opencode/src/tool/lsp-diagnostics.ts2
-rw-r--r--packages/opencode/src/tool/lsp-hover.ts4
-rw-r--r--packages/opencode/src/tool/read.ts2
-rw-r--r--packages/opencode/src/tool/write.ts2
9 files changed, 38 insertions, 21 deletions
diff --git a/packages/opencode/src/bus/index.ts b/packages/opencode/src/bus/index.ts
index ef0967dfa..596e6c1c9 100644
--- a/packages/opencode/src/bus/index.ts
+++ b/packages/opencode/src/bus/index.ts
@@ -78,6 +78,18 @@ export namespace Bus {
return raw(def.type, callback)
}
+ export function once<Definition extends EventDefinition>(
+ def: Definition,
+ callback: (event: {
+ type: Definition["type"]
+ properties: z.infer<Definition["properties"]>
+ }) => "done" | undefined,
+ ) {
+ const unsub = subscribe(def, (event) => {
+ if (callback(event)) unsub()
+ })
+ }
+
export function subscribeAll(callback: (event: any) => void) {
return raw("*", callback)
}
diff --git a/packages/opencode/src/cli/cmd/scrap.ts b/packages/opencode/src/cli/cmd/scrap.ts
index 13cd96ad2..f5fb01507 100644
--- a/packages/opencode/src/cli/cmd/scrap.ts
+++ b/packages/opencode/src/cli/cmd/scrap.ts
@@ -12,9 +12,8 @@ export const ScrapCommand = cmd({
await App.provide(
{ cwd: process.cwd(), version: VERSION, printLogs: true },
async () => {
- await LSP.file(args.file)
- const diagnostics = await LSP.diagnostics()
- console.log(diagnostics)
+ await LSP.touchFile(args.file, true)
+ await LSP.diagnostics()
},
)
},
diff --git a/packages/opencode/src/lsp/client.ts b/packages/opencode/src/lsp/client.ts
index 1722db84c..eea989e0c 100644
--- a/packages/opencode/src/lsp/client.ts
+++ b/packages/opencode/src/lsp/client.ts
@@ -117,6 +117,7 @@ export namespace LSPClient {
textDocument: {
synchronization: {
didOpen: true,
+ didChange: true,
},
publishDiagnostics: {
versionSupport: true,
@@ -127,7 +128,9 @@ export namespace LSPClient {
await connection.sendNotification("initialized", {})
log.info("initialized")
- const files = new Set<string>()
+ const files: {
+ [path: string]: number
+ } = {}
const result = {
get clientID() {
@@ -143,8 +146,8 @@ export namespace LSPClient {
: path.resolve(app.path.cwd, input.path)
const file = Bun.file(input.path)
const text = await file.text()
- const opened = files.has(input.path)
- if (!opened) {
+ const version = files[input.path]
+ if (version === undefined) {
log.info("textDocument/didOpen", input)
diagnostics.delete(input.path)
const extension = path.extname(input.path)
@@ -153,11 +156,11 @@ export namespace LSPClient {
textDocument: {
uri: `file://` + input.path,
languageId,
- version: Date.now(),
+ version: 0,
text,
},
})
- files.add(input.path)
+ files[input.path] = 0
return
}
@@ -166,7 +169,7 @@ export namespace LSPClient {
await connection.sendNotification("textDocument/didChange", {
textDocument: {
uri: `file://` + input.path,
- version: Date.now(),
+ version: ++files[input.path],
},
contentChanges: [
{
@@ -213,6 +216,7 @@ export namespace LSPClient {
log.info("shutting down")
connection.end()
connection.dispose()
+ server.kill()
},
}
diff --git a/packages/opencode/src/lsp/index.ts b/packages/opencode/src/lsp/index.ts
index 72cc7363a..e6cee0a4d 100644
--- a/packages/opencode/src/lsp/index.ts
+++ b/packages/opencode/src/lsp/index.ts
@@ -23,7 +23,7 @@ export namespace LSP {
},
)
- export async function file(input: string) {
+ export async function touchFile(input: string, waitForDiagnostics?: boolean) {
const extension = path.parse(input).ext
const s = await state()
const matches = AUTO.filter((x) => x.extensions.includes(extension))
@@ -40,11 +40,13 @@ export namespace LSP {
})
s.clients.set(match.id, client)
}
- await run(async (client) => {
- const wait = client.waitForDiagnostics({ path: input })
- await client.notify.open({ path: input })
- return wait
- })
+ if (waitForDiagnostics) {
+ await run(async (client) => {
+ const wait = client.waitForDiagnostics({ path: input })
+ await client.notify.open({ path: input })
+ return wait
+ })
+ }
}
export async function diagnostics() {
diff --git a/packages/opencode/src/tool/edit.ts b/packages/opencode/src/tool/edit.ts
index a687441e1..23c6b92a6 100644
--- a/packages/opencode/src/tool/edit.ts
+++ b/packages/opencode/src/tool/edit.ts
@@ -90,7 +90,7 @@ export const EditTool = Tool.define({
FileTimes.read(ctx.sessionID, filepath)
let output = ""
- await LSP.file(filepath)
+ await LSP.touchFile(filepath, true)
const diagnostics = await LSP.diagnostics()
for (const [file, issues] of Object.entries(diagnostics)) {
if (issues.length === 0) continue
diff --git a/packages/opencode/src/tool/lsp-diagnostics.ts b/packages/opencode/src/tool/lsp-diagnostics.ts
index ff30a20cc..d1495f603 100644
--- a/packages/opencode/src/tool/lsp-diagnostics.ts
+++ b/packages/opencode/src/tool/lsp-diagnostics.ts
@@ -16,7 +16,7 @@ export const LspDiagnosticTool = Tool.define({
const normalized = path.isAbsolute(args.path)
? args.path
: path.join(app.path.cwd, args.path)
- await LSP.file(normalized)
+ await LSP.touchFile(normalized, true)
const diagnostics = await LSP.diagnostics()
const file = diagnostics[normalized]
return {
diff --git a/packages/opencode/src/tool/lsp-hover.ts b/packages/opencode/src/tool/lsp-hover.ts
index 74023108d..8bd6eb9d3 100644
--- a/packages/opencode/src/tool/lsp-hover.ts
+++ b/packages/opencode/src/tool/lsp-hover.ts
@@ -18,12 +18,12 @@ export const LspHoverTool = Tool.define({
const file = path.isAbsolute(args.file)
? args.file
: path.join(app.path.cwd, args.file)
- await LSP.file(file)
+ await LSP.touchFile(file, true)
const result = await LSP.hover({
...args,
file,
})
- console.log(result)
+
return {
metadata: {
result,
diff --git a/packages/opencode/src/tool/read.ts b/packages/opencode/src/tool/read.ts
index d96b75a44..8685d19f9 100644
--- a/packages/opencode/src/tool/read.ts
+++ b/packages/opencode/src/tool/read.ts
@@ -88,7 +88,7 @@ export const ReadTool = Tool.define({
output += "\n</file>"
// just warms the lsp client
- LSP.file(filePath)
+ await LSP.touchFile(filePath, true)
FileTimes.read(ctx.sessionID, filePath)
return {
diff --git a/packages/opencode/src/tool/write.ts b/packages/opencode/src/tool/write.ts
index 9de7af056..83c4b360b 100644
--- a/packages/opencode/src/tool/write.ts
+++ b/packages/opencode/src/tool/write.ts
@@ -43,7 +43,7 @@ export const WriteTool = Tool.define({
FileTimes.read(ctx.sessionID, filepath)
let output = ""
- await LSP.file(filepath)
+ await LSP.touchFile(filepath, true)
const diagnostics = await LSP.diagnostics()
for (const [file, issues] of Object.entries(diagnostics)) {
if (issues.length === 0) continue