Skip to content
Open
Show file tree
Hide file tree
Changes from all 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