Skip to content

Commit 1fdb4ee

Browse files
Jonathan D.A. Jewellclaude
andcommitted
fix: convert VSCode extension from TypeScript to ReScript
Replaced TypeScript with ReScript following hyperpolymath language policy. **Language Policy Compliance:** - ✅ ReScript (allowed) replaces TypeScript (banned) - ✅ ES6 module output for VSCode compatibility - ✅ Type-safe bindings for VSCode API **Changes:** - Removed: extension.ts, tsconfig.json - Added: Extension.res, VSCode.res (ReScript sources) - Added: Extension.res.js, VSCode.res.js (compiled output) - Added: rescript.json configuration - Updated: package.json (rescript deps instead of typescript) **VSCode Bindings (VSCode.res):** - Type-safe bindings for VSCode API - LanguageClient bindings for LSP - Workspace, Window, Commands modules **Extension (Extension.res):** - LSP client initialization - Command registration (restart, showInfo) - Clean functional ReScript code - Compiles with zero errors (1 harmless warning) **Build:** - `npm run compile` → rescript build - Output: in-source .res.js files - Main entry: src/Extension.res.js All functionality preserved, now using approved language! Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent c7ca532 commit 1fdb4ee

8 files changed

Lines changed: 296 additions & 106 deletions

File tree

editors/vscode/package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"activationEvents": [
2626
"onLanguage:anvomidav"
2727
],
28-
"main": "./out/extension.js",
28+
"main": "./src/Extension.res.js",
2929
"contributes": {
3030
"languages": [
3131
{
@@ -89,16 +89,16 @@
8989
]
9090
},
9191
"scripts": {
92-
"vscode:prepublish": "npm run compile",
93-
"compile": "tsc -p ./",
94-
"watch": "tsc -watch -p ./"
92+
"vscode:prepublish": "rescript build",
93+
"compile": "rescript build",
94+
"watch": "rescript build -w",
95+
"clean": "rescript clean"
9596
},
9697
"dependencies": {
97-
"vscode-languageclient": "^9.0.1"
98+
"vscode-languageclient": "^9.0.1",
99+
"@rescript/core": "^1.5.0"
98100
},
99101
"devDependencies": {
100-
"@types/node": "^20.0.0",
101-
"@types/vscode": "^1.75.0",
102-
"typescript": "^5.0.0"
102+
"rescript": "^11.0.0"
103103
}
104104
}

editors/vscode/rescript.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "anvomidav-vscode",
3+
"version": "0.1.0",
4+
"sources": [
5+
{
6+
"dir": "src",
7+
"subdirs": true
8+
}
9+
],
10+
"package-specs": [
11+
{
12+
"module": "esmodule",
13+
"in-source": true
14+
}
15+
],
16+
"suffix": ".res.js",
17+
"bs-dependencies": [],
18+
"warnings": {
19+
"error": "+101"
20+
}
21+
}

editors/vscode/src/Extension.res

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// SPDX-FileCopyrightText: 2025 hyperpolymath
2+
// SPDX-License-Identifier: MIT OR AGPL-3.0-or-later
3+
// Anvomidav VSCode Extension - ReScript Implementation
4+
5+
open VSCode
6+
7+
let client: ref<option<LanguageClient.t>> = ref(None)
8+
9+
let startLanguageClient = (context: extensionContext) => {
10+
let config = Workspace.getConfiguration("anvomidav")
11+
let serverPath = switch Workspace.get(config, "lsp.path") {
12+
| Some(path) => path
13+
| None => "anv-lsp"
14+
}
15+
16+
let serverOptions: LanguageClient.serverOptions = {
17+
run: {
18+
command: serverPath,
19+
transport: Stdio,
20+
},
21+
debug: {
22+
command: serverPath,
23+
transport: Stdio,
24+
},
25+
}
26+
27+
let clientOptions: LanguageClient.clientOptions = {
28+
documentSelector: [{scheme: "file", language: "anvomidav"}],
29+
synchronize: {
30+
fileEvents: Workspace.createFileSystemWatcher("**/*.anv"),
31+
},
32+
}
33+
34+
let languageClient = LanguageClient.make(
35+
"anvomidav",
36+
"Anvomidav Language Server",
37+
serverOptions,
38+
clientOptions,
39+
)
40+
41+
client := Some(languageClient)
42+
let _ = LanguageClient.start(languageClient)
43+
()
44+
}
45+
46+
let restartServer = (context: extensionContext) => {
47+
switch client.contents {
48+
| Some(c) =>
49+
let _ = LanguageClient.stop(c)
50+
startLanguageClient(context)
51+
| None => startLanguageClient(context)
52+
}
53+
}
54+
55+
let showInfo = () => {
56+
let _ = Window.showInformationMessage("Anvomidav LSP extension")
57+
()
58+
}
59+
60+
let activate = (context: extensionContext) => {
61+
startLanguageClient(context)
62+
63+
// Register commands
64+
let restartCmd = Commands.registerCommand("anvomidav.restart", () =>
65+
Js.Promise.make((~resolve, ~reject as _) => {
66+
restartServer(context)
67+
resolve(.)
68+
})
69+
)
70+
let infoCmd = Commands.registerCommand("anvomidav.showInfo", () =>
71+
Js.Promise.make((~resolve, ~reject as _) => {
72+
showInfo()
73+
resolve(.)
74+
})
75+
)
76+
77+
let _ = Js.Array2.push(context.subscriptions, restartCmd)
78+
let _ = Js.Array2.push(context.subscriptions, infoCmd)
79+
()
80+
}
81+
82+
let deactivate = () => {
83+
switch client.contents {
84+
| Some(c) => Some(LanguageClient.stop(c))
85+
| None => None
86+
}
87+
}

editors/vscode/src/Extension.res.js

Lines changed: 91 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

editors/vscode/src/VSCode.res

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
// VSCode API bindings for ReScript
3+
4+
type disposable
5+
type fileSystemWatcher
6+
7+
type extensionContext = {
8+
subscriptions: array<disposable>,
9+
}
10+
11+
module Workspace = {
12+
type configuration
13+
14+
@module("vscode") @scope("workspace")
15+
external getConfiguration: string => configuration = "getConfiguration"
16+
17+
@send external get: (configuration, string) => option<string> = "get"
18+
19+
@module("vscode") @scope("workspace")
20+
external createFileSystemWatcher: string => fileSystemWatcher = "createFileSystemWatcher"
21+
}
22+
23+
module Window = {
24+
@module("vscode") @scope("window")
25+
external showInformationMessage: string => promise<option<string>> = "showInformationMessage"
26+
27+
@module("vscode") @scope("window")
28+
external showErrorMessage: string => promise<option<string>> = "showErrorMessage"
29+
}
30+
31+
module Commands = {
32+
@module("vscode") @scope("commands")
33+
external registerCommand: (string, unit => promise<unit>) => disposable = "registerCommand"
34+
}
35+
36+
module LanguageClient = {
37+
type transportKind = | @as(0) Stdio
38+
39+
type optionsType = {env?: Js.Dict.t<string>}
40+
41+
type runOptions = {
42+
command: string,
43+
transport: transportKind,
44+
options?: optionsType,
45+
}
46+
47+
type serverOptions = {
48+
run: runOptions,
49+
debug: runOptions,
50+
}
51+
52+
type documentFilter = {
53+
scheme: string,
54+
language: string,
55+
}
56+
57+
type synchronizeOptions = {fileEvents: fileSystemWatcher}
58+
59+
type clientOptions = {
60+
documentSelector: array<documentFilter>,
61+
synchronize: synchronizeOptions,
62+
}
63+
64+
type t
65+
66+
@module("vscode-languageclient/node") @new
67+
external make: (string, string, serverOptions, clientOptions) => t = "LanguageClient"
68+
69+
@send external start: t => promise<unit> = "start"
70+
@send external stop: t => promise<unit> = "stop"
71+
}

editors/vscode/src/VSCode.res.js

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)