diff --git a/.vscodeignore b/.vscodeignore new file mode 100644 index 0000000..fa6b93a --- /dev/null +++ b/.vscodeignore @@ -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 diff --git a/README.md b/README.md index 6b7a8d6..4f4f213 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ syntax highlighting for hblang in vscode 0. run `rustup default nightly` (you need nightly) 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` > in bash, `export PATH=$PATH:$HOME/.cargo/bin`
> in other shells, there may be other ways diff --git a/language-configuration.json b/language-configuration.json index 54cf2e6..53ea046 100644 --- a/language-configuration.json +++ b/language-configuration.json @@ -68,8 +68,8 @@ ], "folding": { "markers": { - "start": "^\\s*//\\s*#region\\b", - "end": "^\\s*//\\s*#endregion\\b" + "start": "{\n", + "end": "}" } }, "indentationRules": { diff --git a/package-lock.json b/package-lock.json index 25d7c8b..827fb85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "typescript": "^4.0.0", "vscode": "^1.1.37", "webpack": "^5.0.0", - "webpack-cli": "^4.0.0" + "webpack-cli": "^4.10.0" }, "engines": { "vscode": "^1.75.0" diff --git a/package.json b/package.json index 95adbc0..9432b28 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "publisher": "koniifer", "displayName": "hblang", "description": "Syntax highlighter and formatter for holey-bytes lang", - "version": "0.1.0", + "version": "0.2.0", "engines": { "vscode": "^1.75.0" }, @@ -63,6 +63,6 @@ "typescript": "^4.0.0", "vscode": "^1.1.37", "webpack": "^5.0.0", - "webpack-cli": "^4.0.0" + "webpack-cli": "^4.10.0" } } \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index c59c60e..7f48e3b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,62 +1,124 @@ import * as vscode from 'vscode'; -import { spawn } from 'child_process'; +import { execFile } from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; vscode.languages.registerDocumentFormattingEditProvider('hblang', { async provideDocumentFormattingEdits(document: vscode.TextDocument): Promise { - try { - const filePath = document.uri.fsPath; - const tempFilePath = path.join(path.dirname(filePath), `temp_${path.basename(filePath)}`); + const filePath = document.uri.fsPath; + const tempFilePath = path.join(path.dirname(filePath), `temp_${path.basename(filePath)}`); + try { await fs.promises.writeFile(tempFilePath, document.getText()); - return new Promise((resolve, reject) => { - const hbcProcess = spawn('hbc', ['--fmt-stdout', tempFilePath]); - - let stdout = ''; - let stderr = ''; - - hbcProcess.stdout.on('data', (data) => { - 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); + const stdout = await new Promise((resolve, reject) => { + execFile('hbc', ['--fmt-stdout', tempFilePath], (error, stdout, stderr) => { + if (error) { + if (error.code === 'ENOENT') { + vscode.window.showErrorMessage("hblang compiler not found. ensure 'hbc' is installed and available in PATH."); + } else { + vscode.window.showErrorMessage(`error formatting document with hbc: ${stderr || `exit code: ${error.code}`}`); } - }); - - if (code === 0) { - const fullRange = new vscode.Range( - document.positionAt(0), - document.positionAt(document.getText().length) - ); - const edit = vscode.TextEdit.replace(fullRange, stdout); - resolve([edit]); - } else { - vscode.window.showErrorMessage(`hbc formatting failed: ${stderr}`); - reject(new Error(stderr)); + return reject(new Error(stderr || `exit code: ${error.code}`)); } - }); - - hbcProcess.on('error', (err) => { - vscode.window.showErrorMessage(`Failed to start hbc: ${err.message}`); - reject(err); + resolve(stdout); }); }); + + const fullRange = new vscode.Range( + document.positionAt(0), + document.positionAt(document.getText().length) + ); + const edit = vscode.TextEdit.replace(fullRange, stdout); + return [edit]; + } catch (error) { - if (error instanceof Error) { - vscode.window.showErrorMessage(`Error formatting document: ${error.message}`); - } else { - vscode.window.showErrorMessage('An unknown error occurred while formatting the document.'); + + if (error instanceof Error && error.message.includes('ENOENT')) { + 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 { + return new Promise((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; +} \ No newline at end of file