Skip to content

Commit f9450e5

Browse files
authored
VS Code LSP support (#114)
1 parent ec167dc commit f9450e5

12 files changed

Lines changed: 189 additions & 30 deletions

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Publish VS Code Extension
2+
3+
on:
4+
push:
5+
tags:
6+
- 'vscode*'
7+
8+
jobs:
9+
publish:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Setup Node.js
15+
uses: actions/setup-node@v4
16+
with:
17+
node-version: '20'
18+
19+
- name: Install dependencies
20+
working-directory: code
21+
run: npm ci
22+
23+
- name: Compile
24+
working-directory: code
25+
run: npm run compile
26+
27+
- name: Publish to Marketplace
28+
working-directory: code
29+
run: npx @vscode/vsce publish
30+
env:
31+
VSCE_PAT: ${{ secrets.VSCE_PAT }}

AGENTS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,8 @@ msh build.msh
6565
Files in `doc/build` are build artifacts. Do not edit these.
6666
There is a main base template at `doc/base.html`, which has most of the general purpose CSS and styles for code.
6767
You should rebuild the docs when you make edits.
68+
69+
## VS Code
70+
71+
Code for the VS Code extension is at `code/`.
72+
If we update syntax, ensure to update appropriately.

CLAUDE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,8 @@ msh build.msh
6565
Files in `doc/build` are build artifacts. Do not edit these.
6666
There is a main base template at `doc/base.html`, which has most of the general purpose CSS and styles for code.
6767
You should rebuild the docs when you make edits.
68+
69+
## VS Code
70+
71+
Code for the VS Code extension is at `code/`.
72+
If we update syntax, ensure to update appropriately.

code/.vscodeignore

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
.vscode-test/**
33
.git/**
44
.gitignore
5-
**/*.map
5+
src/**
66
**/*.ts
7+
**/*.map
78
node_modules/**
8-
!.vscodeignore
9-
!.**/*.json
9+
tsconfig.json

code/README.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,18 @@
22

33
This is the official extension for the concatenative shell-like programming language [`mshell`](https://github.com/mitchpaulus/mshell).
44

5-
# Features
5+
## Features
66

7-
Currently, this extension supports syntax highlighting.
8-
The canonical file name extension for `mshell` files is `.msh` or `.mshell`.
7+
- Syntax highlighting for `.msh` and `.mshell` files
8+
- Language Server Protocol (LSP) support:
9+
- Hover documentation for built-in functions
10+
- Variable name completion (triggered by `@`)
11+
- Variable rename support
12+
13+
## Requirements
14+
15+
For LSP features, the `msh` executable must be installed and available in your PATH, or configured via the `mshell.lspPath` setting.
16+
17+
## Extension Settings
18+
19+
- `mshell.lspPath`: Path to the msh executable for the language server (default: `"msh"`)

code/package.json

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11
{
22
"name": "mshell",
33
"displayName": "mshell",
4-
"publisher": "MitchellPaulus",
5-
"version": "0.6.4",
6-
"engines": { "vscode": "^1.90.0" },
4+
"description": "Syntax highlighting and language support for the mshell concatenative shell language",
5+
"publisher": "MitchellPaulus",
6+
"version": "0.9.0",
7+
"engines": { "vscode": "^1.90.0" },
78
"categories": ["Programming Languages"],
9+
"main": "./out/extension.js",
10+
"activationEvents": [
11+
"onLanguage:mshell"
12+
],
813
"contributes": {
914
"languages": [
1015
{
1116
"id": "mshell",
1217
"aliases": ["msh"],
1318
"extensions": [".msh", ".mshell"],
14-
"firstLine": "^#!.*\\b(mshell|msh)\\b"
19+
"firstLine": "^#!.*\\b(mshell|msh)\\b",
20+
"configuration": "./language-configuration.json"
1521
}
1622
],
1723
"grammars": [
1824
{
1925
"language": "mshell",
20-
"scopeName": "source.mshell",
26+
"scopeName": "source.mshell",
2127
"path": "./syntaxes/mshell.textmate.json"
2228
}
2329
],
@@ -26,8 +32,31 @@
2632
"editor.insertSpaces": true,
2733
"editor.tabSize": 2
2834
}
35+
},
36+
"configuration": {
37+
"title": "mshell",
38+
"properties": {
39+
"mshell.lspPath": {
40+
"type": "string",
41+
"default": "msh",
42+
"description": "Path to the msh executable for the language server"
43+
}
44+
}
2945
}
3046
},
47+
"scripts": {
48+
"vscode:prepublish": "npm run compile",
49+
"compile": "tsc -p ./",
50+
"watch": "tsc -watch -p ./"
51+
},
52+
"dependencies": {
53+
"vscode-languageclient": "^9.0.1"
54+
},
55+
"devDependencies": {
56+
"@types/node": "^20.11.0",
57+
"@types/vscode": "^1.90.0",
58+
"typescript": "^5.3.3"
59+
},
3160
"repository": { "type": "git", "url": "https://github.com/mitchpaulus/mshell" },
3261
"bugs": { "url": "https://github.com/mitchpaulus/mshell" },
3362
"license": "MIT"

code/src/extension.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import * as path from "path";
2+
import { ExtensionContext, workspace } from "vscode";
3+
import {
4+
LanguageClient,
5+
LanguageClientOptions,
6+
ServerOptions,
7+
} from "vscode-languageclient/node";
8+
9+
let client: LanguageClient | undefined;
10+
11+
export function activate(context: ExtensionContext): void {
12+
const config = workspace.getConfiguration("mshell");
13+
const serverPath = config.get<string>("lspPath") || "msh";
14+
15+
const serverOptions: ServerOptions = {
16+
command: serverPath,
17+
args: ["lsp"],
18+
};
19+
20+
const clientOptions: LanguageClientOptions = {
21+
documentSelector: [{ scheme: "file", language: "mshell" }],
22+
};
23+
24+
client = new LanguageClient(
25+
"mshell",
26+
"mshell Language Server",
27+
serverOptions,
28+
clientOptions
29+
);
30+
31+
client.start();
32+
}
33+
34+
export function deactivate(): Thenable<void> | undefined {
35+
if (!client) {
36+
return undefined;
37+
}
38+
return client.stop();
39+
}

code/syntaxes/mshell.textmate.json

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
},
1111
{
1212
"name": "constant.language.bool",
13-
"match": "\b(true|false)\b"
13+
"match": "\\b(true|false)\\b"
1414
},
1515
{
1616
"name": "string.quoted.single.mshell",
@@ -24,6 +24,12 @@
2424
"begin": "`",
2525
"end": "`"
2626
},
27+
{
28+
"include": "#string_interpolated"
29+
},
30+
{
31+
"include": "#string_double"
32+
},
2733
{
2834
"name": "variable.other.set",
2935
"match": "\\$[a-zA-Z0-9_]+!"
@@ -52,9 +58,34 @@
5258
{ "include": "#escape_simple" }
5359
]
5460
},
61+
"string_interpolated": {
62+
"name": "string.quoted.double.interpolated.mshell",
63+
"begin": "\\$\"",
64+
"beginCaptures": { "0": { "name": "punctuation.definition.string.begin.mshell" } },
65+
"end": "\"",
66+
"endCaptures": { "0": { "name": "punctuation.definition.string.end.mshell" } },
67+
"patterns": [
68+
{ "include": "#interpolation" },
69+
{ "include": "#escape_format" }
70+
]
71+
},
72+
"interpolation": {
73+
"name": "meta.interpolation.mshell",
74+
"begin": "\\{",
75+
"beginCaptures": { "0": { "name": "punctuation.section.interpolation.begin.mshell" } },
76+
"end": "\\}",
77+
"endCaptures": { "0": { "name": "punctuation.section.interpolation.end.mshell" } },
78+
"patterns": [
79+
{ "include": "$self" }
80+
]
81+
},
5582
"escape_simple": {
5683
"name": "constant.character.escape.mshell",
57-
"match": "\\\\(e|n|t|r|\"|\\\\)"
84+
"match": "\\\\[entr\"\\\\]"
85+
},
86+
"escape_format": {
87+
"name": "constant.character.escape.mshell",
88+
"match": "\\\\[entr\"\\\\{]"
5889
}
5990
}
6091
}

code/tsconfig.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"compilerOptions": {
3+
"module": "commonjs",
4+
"target": "ES2020",
5+
"lib": ["ES2020"],
6+
"outDir": "out",
7+
"rootDir": "src",
8+
"sourceMap": true,
9+
"strict": true,
10+
"esModuleInterop": true,
11+
"skipLibCheck": true
12+
},
13+
"include": ["src"],
14+
"exclude": ["node_modules"]
15+
}

mshell/Main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func main() {
6666
var err error
6767

6868
if len(os.Args) >= 2 && os.Args[1] == "lsp" {
69-
if runErr := RunLSP(os.Args[2:], os.Stdin, os.Stdout); runErr != nil {
69+
if runErr := RunLSP(os.Stdin, os.Stdout); runErr != nil {
7070
if runErr == errExitBeforeShutdown {
7171
os.Exit(1)
7272
}

0 commit comments

Comments
 (0)