Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
node_modules/
out/

# jetbrains ides cache
.idea/

.pnpm-debug.log

*.ast
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,20 @@ SimplicityHL is a high-level language for writing Simplicity smart contracts. Si
- Syntax highlighting and snippets for `.simf` and `.wit` files
- Compiler diagnostics, completion, hover, signature help, symbols, references, and go to definition
- Opt-in imports and enums support in the language server and direct compiler commands
- Formatting of SimplicityHL code using default VSCode bindings

The extension installs or connects to the [SimplicityHL language server][4], which provides language intelligence:
The extension installs or connects to the [SimplicityHL language server][4], which provides language intelligence.
To provide concise and clear code you can also use the [simfmt][5] formatter.

- Error diagnostics
![diagnostics][6]

- Completion of user-defined functions, imported items, built-ins, and jets
![completion][7]

- Formatting of SimplicityHL code
![formatting][8]

## Experimental features

Open Settings and search for `SimplicityHL: Experimental Features`. `Imports` and `Enums` are independent checkboxes and both are disabled by default.
Expand All @@ -43,4 +48,5 @@ To install the extension manually or hack on the source code see [development.md
[5]: https://github.com/BlockstreamResearch/simfmt
[6]: https://raw.githubusercontent.com/BlockstreamResearch/simplicityhl-vscode/master/assets/error_diagnostic.gif
[7]: https://raw.githubusercontent.com/BlockstreamResearch/simplicityhl-vscode/master/assets/completion.gif
[8]: https://raw.githubusercontent.com/BlockstreamResearch/simplicityhl-vscode/master/docs/development.md
[8]: https://raw.githubusercontent.com/BlockstreamResearch/simplicityhl-vscode/master/assets/formatting.gif
[9]: https://raw.githubusercontent.com/BlockstreamResearch/simplicityhl-vscode/master/docs/development.md
Binary file added assets/formatting.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 9 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 46 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
"Programming Languages"
],
"main": "dist/extension.js",
"activationEvents": [
"onStartupFinished"
],
"contributes": {
"languages": [
{
Expand Down Expand Up @@ -95,6 +98,27 @@
"default": "",
"description": "Path to the simc compiler. If empty, searches PATH and common locations."
},
"simplicityhl.suppressMissingFormatterWarning": {
"type": "boolean",
"default": false,
"description": "Do not show missing formatter executable warning."
},
"simplicityhl.formatter.path": {
"type": "string",
"default": "",
"scope": "machine-overridable",
"description": "Path to the simfmt formatter. If empty, searches PATH and common locations."
},
"simplicityhl.formatter.autoSaveBeforeFormat": {
"type": "boolean",
"default": true,
"description": "Automatically save the file before formatting."
},
"simplicityhl.formatter.disableAutoupdate": {
"type": "boolean",
"default": false,
"description": "Do not autoupdate simfmt formatter."
},
"simplicityhl.build.autoSaveBeforeCompile": {
"type": "boolean",
"default": true,
Expand All @@ -118,6 +142,11 @@
}
}
],
"configurationDefaults": {
"[simplicityhl]": {
"editor.defaultFormatter": "Blockstream.simplicityhl"
}
},
"commands": [
{
"command": "simplicityhl.restartServer",
Expand All @@ -144,6 +173,11 @@
"command": "simplicityhl.compileJson",
"title": "Compile to JSON",
"category": "SimplicityHL"
},
{
"command": "simplicityhl.formatFile",
"title": "Format Current File",
"category": "SimplicityHL"
}
],
"menus": {
Expand All @@ -164,6 +198,11 @@
"when": "resourceLangId == simplicityhl",
"command": "simplicityhl.compileWithWitness",
"group": "1_modification"
},
{
"when": "resourceLangId == simplicityhl",
"command": "simplicityhl.formatFile",
"group": "1_modification"
}
],
"commandPalette": [
Expand All @@ -182,6 +221,10 @@
{
"command": "simplicityhl.compileJson",
"when": "resourceLangId == simplicityhl"
},
{
"command": "simplicityhl.formatFile",
"when": "resourceLangId == simplicityhl"
}
]
},
Expand Down Expand Up @@ -240,7 +283,7 @@
"compile": "npm run check-types && node esbuild.mjs --production",
"check": "npm test && npm run eslint-check && npm run compile",
"check-types": "tsc --noEmit",
"test": "node --test -r ts-node/register src/contracts.test.ts src/find_executable.test.ts",
"test": "node --test -r ts-node/register src/contracts.test.ts src/find_executable.test.ts src/update/binary_update_state.test.ts src/update/crates_io.test.ts src/format/updater.test.ts src/format/output.test.ts",
"watch": "npm-run-all -p watch:*",
"watch:esbuild": "node esbuild.mjs --watch",
"watch:tsc": "tsc --noEmit --watch --project tsconfig.json",
Expand All @@ -254,6 +297,7 @@
"devDependencies": {
"@eslint/js": "^10.0.1",
"@types/node": "^22",
"@types/semver": "^7.8.0",
"@types/vscode": "1.91.0",
"@vscode/vsce": "^3.9.2",
"esbuild": "^0.25.9",
Expand All @@ -266,6 +310,7 @@
"typescript-eslint": "^8.65.0"
},
"dependencies": {
"semver": "^7.8.5",
"vscode-languageclient": "^10.1.0"
}
}
36 changes: 36 additions & 0 deletions src/commands/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Command and native provider registration for SimplicityHL formatting.

import * as vscode from "vscode";
import { COMMAND_IDS, LANGUAGE_IDS } from "../contracts";

import { getActiveSimplicityHLDocument, DocumentAction } from "../format/document";
import type { SimplicityHLFormatter } from "../format";

export function registerFormattingCommands(
context: vscode.ExtensionContext,
formatter: () => SimplicityHLFormatter,
): void {
const formatFileCommand = vscode.commands.registerCommand(
COMMAND_IDS.formatFile,
async () => {
const document = await getActiveSimplicityHLDocument({
action: DocumentAction.Format,
});
if (!document) return;

await formatter().formatDocument(document);
},
);

const provider = vscode.languages.registerDocumentFormattingEditProvider(
{ language: LANGUAGE_IDS.source },
{
provideDocumentFormattingEdits(document, options, token) {
if (token.isCancellationRequested) return undefined;
return formatter().provideDocumentFormattingEdits(document, options, token);
},
},
);

context.subscriptions.push(formatFileCommand, provider);
}
17 changes: 15 additions & 2 deletions src/contracts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as fs from "node:fs";
import * as path from "node:path";
import { test } from "node:test";

import { SETTINGS, languageClientOptions } from "./contracts";
import { COMMAND_IDS, SETTINGS, languageClientOptions } from "./contracts";

void test("client languages and consumed settings match package contributions", () => {
const manifest = JSON.parse(
Expand All @@ -24,12 +24,25 @@ void test("client languages and consumed settings match package contributions",
),
) as Record<string, { default?: unknown }>;

for (const setting of [SETTINGS.serverPath, SETTINGS.imports, SETTINGS.enums]) {
for (const setting of [
SETTINGS.serverPath,
SETTINGS.imports,
SETTINGS.enums,
SETTINGS.suppressMissingFormatterWarning,
SETTINGS.formatterPath,
SETTINGS.autoSaveBeforeFormat,
SETTINGS.formatterDisableAutoupdate,
]) {
const contribution =
contributedSettings[
`${clientOptions.synchronize.configurationSection}.${setting.key}`
];
assert.ok(contribution, `Missing package contribution for ${setting.key}`);
assert.equal(contribution.default, setting.default);
}

assert.ok(contributions.commands.some(
({ command }: { command: string }) => command === COMMAND_IDS.formatFile,
));
assert.deepEqual(manifest.activationEvents, ["onStartupFinished"]);
});
52 changes: 51 additions & 1 deletion src/contracts.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,54 @@
export const CONFIGURATION_SECTION = "simplicityhl";
export const LANGUAGE_CLIENT_ID = "simplicityhlLspClient";
export const LANGUAGE_CLIENT_NAME = "SimplicityHL LSP";
export const SERVER_BINARY = "simplicityhl-lsp";
export const TASK_TYPE = "simplicityhl";

export const OUTPUT_CHANNEL_NAMES = {
formatter: "SimplicityHL Formatter",
} as const;

export const LANGUAGE_IDS = {
source: "simplicityhl",
witness: "simplicityhl-witness",
} as const;

export enum ManagedBinary {
Simfmt = "simfmt",
LanguageServer = "simplicityhl-lsp",
}

export enum CrateName {
Simfmt = "simfmt",
LanguageServer = "simplicityhl-lsp",
}

export const MANAGED_BINARY_CRATE_NAMES: Record<
ManagedBinary,
CrateName
> = {
[ManagedBinary.Simfmt]: CrateName.Simfmt,
[ManagedBinary.LanguageServer]: CrateName.LanguageServer,
};

export const MANAGED_BINARY_INFO: Record<
ManagedBinary,
{ displayName: string }
> = {
[ManagedBinary.Simfmt]: {
displayName: "SimplicityHL formatter",
},
[ManagedBinary.LanguageServer]: {
displayName: "SimplicityHL language server",
},
};

export const COMMAND_IDS = {
restartServer: "simplicityhl.restartServer",
compileFile: "simplicityhl.compileFile",
compileFileDebug: "simplicityhl.compileFileDebug",
compileWithWitness: "simplicityhl.compileWithWitness",
compileJson: "simplicityhl.compileJson",
formatFile: "simplicityhl.formatFile",
} as const;

export const TASK_COMMANDS = [
Expand All @@ -40,6 +74,22 @@ export const SETTINGS = {
key: "compiler.path",
default: "",
},
suppressMissingFormatterWarning: {
key: "suppressMissingFormatterWarning",
default: false,
},
formatterPath: {
key: "formatter.path",
default: "",
},
autoSaveBeforeFormat: {
key: "formatter.autoSaveBeforeFormat",
default: true,
},
formatterDisableAutoupdate: {
key: "formatter.disableAutoupdate",
default: false,
},
autoSaveBeforeCompile: {
key: "build.autoSaveBeforeCompile",
default: true,
Expand Down
Loading
Loading