release 0.2.0

+ error linting
+ clearer missing hblang message
+ misc
This commit is contained in:
koniifer 2024-11-07 18:59:47 +00:00
parent 7c48aa6cad
commit c3ade921d7
6 changed files with 124 additions and 48 deletions

13
.vscodeignore Normal file
View file

@ -0,0 +1,13 @@
# ---> VisualStudioCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix

View file

@ -6,6 +6,7 @@ syntax highlighting for hblang in vscode
0. run `rustup default nightly` (you need nightly) 0. run `rustup default nightly` (you need nightly)
1. run `cargo install hblang --git https://git.ablecorp.us/ableos/holey-bytes` 1. run `cargo install hblang --git https://git.ablecorp.us/ableos/holey-bytes`
> remember to keep this updated
2. add `$HOME/.cargo/bin` (or wherever you installed hblang) to `$PATH` 2. add `$HOME/.cargo/bin` (or wherever you installed hblang) to `$PATH`
> in bash, `export PATH=$PATH:$HOME/.cargo/bin`<br> > in bash, `export PATH=$PATH:$HOME/.cargo/bin`<br>
> in other shells, there may be other ways > in other shells, there may be other ways

View file

@ -68,8 +68,8 @@
], ],
"folding": { "folding": {
"markers": { "markers": {
"start": "^\\s*//\\s*#region\\b", "start": "{\n",
"end": "^\\s*//\\s*#endregion\\b" "end": "}"
} }
}, },
"indentationRules": { "indentationRules": {

2
package-lock.json generated
View file

@ -16,7 +16,7 @@
"typescript": "^4.0.0", "typescript": "^4.0.0",
"vscode": "^1.1.37", "vscode": "^1.1.37",
"webpack": "^5.0.0", "webpack": "^5.0.0",
"webpack-cli": "^4.0.0" "webpack-cli": "^4.10.0"
}, },
"engines": { "engines": {
"vscode": "^1.75.0" "vscode": "^1.75.0"

View file

@ -6,7 +6,7 @@
"publisher": "koniifer", "publisher": "koniifer",
"displayName": "hblang", "displayName": "hblang",
"description": "Syntax highlighter and formatter for holey-bytes lang", "description": "Syntax highlighter and formatter for holey-bytes lang",
"version": "0.1.0", "version": "0.2.0",
"engines": { "engines": {
"vscode": "^1.75.0" "vscode": "^1.75.0"
}, },
@ -63,6 +63,6 @@
"typescript": "^4.0.0", "typescript": "^4.0.0",
"vscode": "^1.1.37", "vscode": "^1.1.37",
"webpack": "^5.0.0", "webpack": "^5.0.0",
"webpack-cli": "^4.0.0" "webpack-cli": "^4.10.0"
} }
} }

View file

@ -1,62 +1,124 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { spawn } from 'child_process'; import { execFile } from 'child_process';
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
vscode.languages.registerDocumentFormattingEditProvider('hblang', { vscode.languages.registerDocumentFormattingEditProvider('hblang', {
async provideDocumentFormattingEdits(document: vscode.TextDocument): Promise<vscode.TextEdit[]> { async provideDocumentFormattingEdits(document: vscode.TextDocument): Promise<vscode.TextEdit[]> {
try {
const filePath = document.uri.fsPath; const filePath = document.uri.fsPath;
const tempFilePath = path.join(path.dirname(filePath), `temp_${path.basename(filePath)}`); const tempFilePath = path.join(path.dirname(filePath), `temp_${path.basename(filePath)}`);
try {
await fs.promises.writeFile(tempFilePath, document.getText()); await fs.promises.writeFile(tempFilePath, document.getText());
return new Promise((resolve, reject) => { const stdout = await new Promise<string>((resolve, reject) => {
const hbcProcess = spawn('hbc', ['--fmt-stdout', tempFilePath]); execFile('hbc', ['--fmt-stdout', tempFilePath], (error, stdout, stderr) => {
if (error) {
let stdout = ''; if (error.code === 'ENOENT') {
let stderr = ''; vscode.window.showErrorMessage("hblang compiler not found. ensure 'hbc' is installed and available in PATH.");
} else {
hbcProcess.stdout.on('data', (data) => { vscode.window.showErrorMessage(`error formatting document with hbc: ${stderr || `exit code: ${error.code}`}`);
stdout += data.toString();
});
hbcProcess.stderr.on('data', (data) => {
stderr += data.toString();
});
hbcProcess.on('close', (code) => {
fs.unlink(tempFilePath, (err) => {
if (err) {
console.error('Error removing temp file:', err);
} }
return reject(new Error(stderr || `exit code: ${error.code}`));
}
resolve(stdout);
});
}); });
if (code === 0) {
const fullRange = new vscode.Range( const fullRange = new vscode.Range(
document.positionAt(0), document.positionAt(0),
document.positionAt(document.getText().length) document.positionAt(document.getText().length)
); );
const edit = vscode.TextEdit.replace(fullRange, stdout); const edit = vscode.TextEdit.replace(fullRange, stdout);
resolve([edit]); return [edit];
} else {
vscode.window.showErrorMessage(`hbc formatting failed: ${stderr}`);
reject(new Error(stderr));
}
});
hbcProcess.on('error', (err) => {
vscode.window.showErrorMessage(`Failed to start hbc: ${err.message}`);
reject(err);
});
});
} catch (error) { } catch (error) {
if (error instanceof Error) {
vscode.window.showErrorMessage(`Error formatting document: ${error.message}`); if (error instanceof Error && error.message.includes('ENOENT')) {
} else {
vscode.window.showErrorMessage('An unknown error occurred while formatting the document.');
}
return []; return [];
} }
const message = error instanceof Error ? error.message : 'unknown error occurred.';
vscode.window.showErrorMessage(`error formatting document: ${message}`);
return [];
} finally {
fs.promises.unlink(tempFilePath).catch((err) => {
console.error('error removing temp file:', err);
});
}
} }
}); });
let diagnosticCollection: vscode.DiagnosticCollection;
export function activate(context: vscode.ExtensionContext) {
diagnosticCollection = vscode.languages.createDiagnosticCollection('hblang');
context.subscriptions.push(diagnosticCollection);
vscode.workspace.onDidSaveTextDocument(onDocumentSaved);
}
async function onDocumentSaved(document: vscode.TextDocument) {
if (document.languageId === 'hblang') {
await lintDocument(document);
}
}
async function lintDocument(document: vscode.TextDocument) {
const filePath = document.uri.fsPath;
try {
const stderr = await runCompiler(filePath);
const diagnostics = parseLintingErrors(stderr);
diagnosticCollection.set(document.uri, diagnostics);
} catch (error) {
if (error instanceof Error) {
const diagnostics = parseLintingErrors(error.message);
diagnosticCollection.set(document.uri, diagnostics);
} else {
vscode.window.showErrorMessage(`error linting hblang document for some reason`)
}
}
}
async function runCompiler(filePath: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
execFile('hbc', [filePath], (error, stdout, stderr) => {
if (error) {
if (error.code === 'ENOENT') {
vscode.window.showErrorMessage("hblang compiler not found. ensure 'hbc' is installed and available in PATH.");
}
reject(new Error(stderr || `Exit code: ${error.code}`));
} else {
resolve(stderr);
}
});
});
}
function parseLintingErrors(stderr: string): vscode.Diagnostic[] {
const diagnostics: vscode.Diagnostic[] = [];
const lines = stderr.trim().split('\n');
for (const line of lines) {
const match = line.match(/^([^:]+):(\d+):(\d+):\s*(.+)$/);
if (match && !line.includes('missing main function')) {
const [, filePath, lineStr, columnStr, message] = match;
const line = parseInt(lineStr, 10) - 1;
const column = parseInt(columnStr, 10) - 1;
const diagnostic = new vscode.Diagnostic(
new vscode.Range(line, column, line, column + message.length),
message,
vscode.DiagnosticSeverity.Error
);
diagnostic.source = 'hbc';
diagnostics.push(diagnostic);
}
}
return diagnostics;
}