Skip to content

Commit 31ed81b

Browse files
committed
feat: Initialize ProXPL VS Code extension with TypeScript configuration, package metadata, run command, basic formatting, and keyword hover support.
1 parent 7d0fe18 commit 31ed81b

3 files changed

Lines changed: 167 additions & 13 deletions

File tree

extension/package.json

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,26 @@
88
"type": "git",
99
"url": "https://github.com/ProgrammerKR/ProXPL"
1010
},
11-
"engines": {
12-
"vscode": "^1.75.0"
13-
},
14-
"categories": [
15-
"Programming Languages"
16-
],
17-
"keywords": [
18-
"proxpl",
19-
"prox",
20-
"syntax",
21-
"highlighting"
11+
"main": "./out/extension.js",
12+
"activationEvents": [
13+
"onLanguage:proxpl"
2214
],
15+
"scripts": {
16+
"vscode:prepublish": "npm run compile",
17+
"compile": "tsc -p ./",
18+
"watch": "tsc -watch -p ./",
19+
"pretest": "npm run compile && npm run lint",
20+
"lint": "eslint src --ext ts",
21+
"test": "node ./out/test/runTest.js"
22+
},
23+
"devDependencies": {
24+
"@types/vscode": "^1.75.0",
25+
"@types/node": "16.x",
26+
"typescript": "^4.9.5",
27+
"eslint": "^8.36.0",
28+
"@typescript-eslint/parser": "^5.55.0",
29+
"@typescript-eslint/eslint-plugin": "^5.55.0"
30+
},
2331
"contributes": {
2432
"languages": [
2533
{
@@ -46,6 +54,22 @@
4654
"language": "proxpl",
4755
"path": "./snippets/proxpl-snippets.json"
4856
}
49-
]
57+
],
58+
"commands": [
59+
{
60+
"command": "proxpl.run",
61+
"title": "ProXPL: Run File",
62+
"icon": "$(play)"
63+
}
64+
],
65+
"menus": {
66+
"editor/title": [
67+
{
68+
"when": "resourceExtname == .prox",
69+
"command": "proxpl.run",
70+
"group": "navigation"
71+
}
72+
]
73+
}
5074
}
51-
}
75+
}

extension/src/extension.ts

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import * as vscode from 'vscode';
2+
import * as cp from 'child_process';
3+
4+
export function activate(context: vscode.ExtensionContext) {
5+
const diagnosticCollection = vscode.languages.createDiagnosticCollection('proxpl');
6+
context.subscriptions.push(diagnosticCollection);
7+
8+
// 1. Code Runner Command
9+
let runCommand = vscode.commands.registerCommand('proxpl.run', () => {
10+
const editor = vscode.window.activeTextEditor;
11+
if (!editor) {
12+
vscode.window.showErrorMessage('No active editor found.');
13+
return;
14+
}
15+
16+
const fileName = editor.document.fileName;
17+
if (!fileName.endsWith('.prox')) {
18+
vscode.window.showErrorMessage('Not a ProXPL (.prox) file.');
19+
return;
20+
}
21+
22+
// Save file before running
23+
editor.document.save().then(() => {
24+
const terminal = vscode.window.activeTerminal || vscode.window.createTerminal('ProXPL');
25+
terminal.show();
26+
terminal.sendText(`proxpl run "${fileName}"`);
27+
28+
// Optional: Background execution for diagnostics
29+
// We run another process to capture output specifically for the "linter"
30+
cp.exec(`proxpl check "${fileName}"`, (error, stdout, stderr) => {
31+
diagnosticCollection.clear();
32+
const diagnostics: vscode.Diagnostic[] = [];
33+
34+
// Simple pattern matching for "Error at line X: message"
35+
const errorLog = stderr || stdout;
36+
const errorLines = errorLog.split('\n');
37+
38+
errorLines.forEach(line => {
39+
const match = line.match(/Error at line (\d+): (.*)/);
40+
if (match) {
41+
const lineNum = parseInt(match[1]) - 1;
42+
const message = match[2];
43+
const range = new vscode.Range(lineNum, 0, lineNum, 100);
44+
diagnostics.push(new vscode.Diagnostic(range, message, vscode.DiagnosticSeverity.Error));
45+
}
46+
});
47+
48+
diagnosticCollection.set(editor.document.uri, diagnostics);
49+
});
50+
});
51+
});
52+
context.subscriptions.push(runCommand);
53+
54+
// 2. Formatter Provider
55+
const formattingProvider = vscode.languages.registerDocumentFormattingEditProvider('proxpl', {
56+
provideDocumentFormattingEdits(document: vscode.TextDocument): vscode.TextEdit[] {
57+
const edits: vscode.TextEdit[] = [];
58+
59+
for (let i = 0; i < document.lineCount; i++) {
60+
const line = document.lineAt(i);
61+
const text = line.text;
62+
63+
// Remove trailing whitespace
64+
if (text.endsWith(' ') || text.endsWith('\t')) {
65+
edits.push(vscode.TextEdit.delete(new vscode.Range(i, text.trimEnd().length, i, text.length)));
66+
}
67+
68+
// Basic Indentation (simplified example - fixes existing whitespace to 4 spaces)
69+
// This is a naive implementation; complex ones use AST
70+
const indentMatch = text.match(/^(\s+)/);
71+
if (indentMatch) {
72+
const oldIndent = indentMatch[1];
73+
// Example: convert tabs to 4 spaces or ensure 4-space blocks
74+
const newIndent = oldIndent.replace(/\t/g, ' ');
75+
if (oldIndent !== newIndent) {
76+
edits.push(vscode.TextEdit.replace(new vscode.Range(i, 0, i, oldIndent.length), newIndent));
77+
}
78+
}
79+
}
80+
return edits;
81+
}
82+
});
83+
context.subscriptions.push(formattingProvider);
84+
85+
// 3. Hover Support
86+
const hoverProvider = vscode.languages.registerHoverProvider('proxpl', {
87+
provideHover(document, position) {
88+
const range = document.getWordRangeAtPosition(position);
89+
const word = document.getText(range);
90+
91+
const descriptions: { [key: string]: string } = {
92+
'func': 'Defines a new function in ProXPL. Syntax: `func name(params) { ... }`',
93+
'var': 'Declares a new variable. ProXPL is dynamically typed but variables must be declared.',
94+
'if': 'Conditional statement. Executes a block if the condition is true.',
95+
'else': 'Defines an alternative block for an `if` statement.',
96+
'while': 'Loop that continues as long as a condition is true.',
97+
'return': 'Exits a function and optionally returns a value.',
98+
'print': 'Built-in function to output values to the terminal.',
99+
'import': 'Incorporates external modules into the current script.'
100+
};
101+
102+
if (descriptions[word]) {
103+
return new vscode.Hover(new vscode.MarkdownString(descriptions[word]));
104+
}
105+
return null;
106+
}
107+
});
108+
context.subscriptions.push(hoverProvider);
109+
}
110+
111+
export function deactivate() { }

extension/tsconfig.json

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

0 commit comments

Comments
 (0)