feat: eslint lsp (#1744)
This commit is contained in:
@@ -65,6 +65,66 @@ export namespace LSPServer {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const ESLint: Info = {
|
||||||
|
id: "eslint",
|
||||||
|
root: NearestRoot([
|
||||||
|
"eslint.config.js",
|
||||||
|
"eslint.config.mjs",
|
||||||
|
"eslint.config.cjs",
|
||||||
|
"eslint.config.ts",
|
||||||
|
"eslint.config.mts",
|
||||||
|
"eslint.config.cts",
|
||||||
|
".eslintrc.js",
|
||||||
|
".eslintrc.cjs",
|
||||||
|
".eslintrc.yaml",
|
||||||
|
".eslintrc.yml",
|
||||||
|
".eslintrc.json",
|
||||||
|
"package.json",
|
||||||
|
]),
|
||||||
|
extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"],
|
||||||
|
async spawn(app, root) {
|
||||||
|
const eslint = await Bun.resolve("eslint", app.path.cwd).catch(() => {})
|
||||||
|
if (!eslint) return
|
||||||
|
const serverPath = path.join(Global.Path.bin, "vscode-eslint", "server", "out", "eslintServer.js")
|
||||||
|
if (!(await Bun.file(serverPath).exists())) {
|
||||||
|
log.info("downloading and building VS Code ESLint server")
|
||||||
|
const response = await fetch("https://github.com/microsoft/vscode-eslint/archive/refs/heads/main.zip")
|
||||||
|
if (!response.ok) return
|
||||||
|
|
||||||
|
const zipPath = path.join(Global.Path.bin, "vscode-eslint.zip")
|
||||||
|
await Bun.file(zipPath).write(response)
|
||||||
|
|
||||||
|
await $`unzip -o -q ${zipPath}`.cwd(Global.Path.bin).nothrow()
|
||||||
|
await fs.rm(zipPath, { force: true })
|
||||||
|
|
||||||
|
const extractedPath = path.join(Global.Path.bin, "vscode-eslint-main")
|
||||||
|
const finalPath = path.join(Global.Path.bin, "vscode-eslint")
|
||||||
|
|
||||||
|
if (await Bun.file(finalPath).exists()) {
|
||||||
|
await fs.rm(finalPath, { force: true, recursive: true })
|
||||||
|
}
|
||||||
|
await fs.rename(extractedPath, finalPath)
|
||||||
|
|
||||||
|
await $`npm install`.cwd(finalPath).quiet()
|
||||||
|
await $`npm run compile`.cwd(finalPath).quiet()
|
||||||
|
|
||||||
|
log.info("installed VS Code ESLint server", { serverPath })
|
||||||
|
}
|
||||||
|
|
||||||
|
const proc = spawn(BunProc.which(), ["--max-old-space-size=8192", serverPath, "--stdio"], {
|
||||||
|
cwd: root,
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
BUN_BE_BUN: "1",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
process: proc,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
export const Gopls: Info = {
|
export const Gopls: Info = {
|
||||||
id: "golang",
|
id: "golang",
|
||||||
root: async (file, app) => {
|
root: async (file, app) => {
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ export const EditTool = Tool.define("edit", {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
output += `\n<project_diagnostics>\n${file}\n${issues
|
output += `\n<project_diagnostics>\n${file}\n${issues
|
||||||
|
// TODO: may want to make more leniant for eslint
|
||||||
.filter((item) => item.severity === 1)
|
.filter((item) => item.severity === 1)
|
||||||
.map(LSP.Diagnostic.pretty)
|
.map(LSP.Diagnostic.pretty)
|
||||||
.join("\n")}\n</project_diagnostics>\n`
|
.join("\n")}\n</project_diagnostics>\n`
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ opencode integrates with your Language Server Protocol (LSP) to help the LLM int
|
|||||||
|
|
||||||
opencode comes with several built-in LSP servers for popular languages:
|
opencode comes with several built-in LSP servers for popular languages:
|
||||||
|
|
||||||
| LSP Server | Extensions | Requirements |
|
| LSP Server | Extensions | Requirements |
|
||||||
| ---------- | -------------------------------------------- | ----------------------------------- |
|
| ---------- | -------------------------------------------- | ----------------------------------- |
|
||||||
| typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project |
|
| typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project |
|
||||||
|
| eslint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `eslint` dependency in project |
|
||||||
| gopls | .go | `go` command available |
|
| gopls | .go | `go` command available |
|
||||||
| ruby-lsp | .rb, .rake, .gemspec, .ru | `ruby` and `gem` commands available |
|
| ruby-lsp | .rb, .rake, .gemspec, .ru | `ruby` and `gem` commands available |
|
||||||
| pyright | .py, .pyi | `pyright` dependency installed |
|
| pyright | .py, .pyi | `pyright` dependency installed |
|
||||||
@@ -41,7 +42,7 @@ You can customize LSP servers through the `lsp` section in your opencode config.
|
|||||||
```json title="opencode.json"
|
```json title="opencode.json"
|
||||||
{
|
{
|
||||||
"$schema": "https://opencode.ai/config.json",
|
"$schema": "https://opencode.ai/config.json",
|
||||||
"lsp": { }
|
"lsp": {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ Each LSP server supports the following:
|
|||||||
|
|
||||||
| Property | Type | Description |
|
| Property | Type | Description |
|
||||||
| ---------------- | -------- | ------------------------------------------------- |
|
| ---------------- | -------- | ------------------------------------------------- |
|
||||||
| `disabled` | boolean | Set this to `true` to disable the LSP server |
|
| `disabled` | boolean | Set this to `true` to disable the LSP server |
|
||||||
| `command` | string[] | The command to start the LSP server |
|
| `command` | string[] | The command to start the LSP server |
|
||||||
| `extensions` | string[] | File extensions this LSP server should handle |
|
| `extensions` | string[] | File extensions this LSP server should handle |
|
||||||
| `env` | object | Environment variables to set when starting server |
|
| `env` | object | Environment variables to set when starting server |
|
||||||
|
|||||||
Reference in New Issue
Block a user