improvements to editors

This commit is contained in:
2025-07-10 21:35:48 -04:00
parent 9bd9ab21b6
commit 8569c9c304
3 changed files with 81 additions and 49 deletions

View File

@@ -41,13 +41,13 @@ export function activate(context: vscode.ExtensionContext) {
const lineText = document.lineAt(position.line).text; const lineText = document.lineAt(position.line).text;
const start = Math.max(0, position.character - 10); const start = Math.max(0, position.character - 10);
const snippet = lineText.slice(start, position.character); const snippet = lineText.slice(start, position.character);
console.log(`change '${text}' snippet ${snippet}`) console.log(`change '${text}' snippet ${snippet}`);
const m = snippet.match(/(\\[^ ]+)$/); const m = snippet.match(/(\\[^ ]+)$/);
if (m) { if (m) {
const cand = m[0]; const cand = m[0];
console.log('cand', cand); console.log("cand", cand);
const replacement = ABBREV[cand]; const replacement = ABBREV[cand];
console.log('repl', replacement); console.log("repl", replacement);
if (replacement) { if (replacement) {
const range = new vscode.Range( const range = new vscode.Range(
position.line, position.line,
@@ -70,6 +70,7 @@ export function activate(context: vscode.ExtensionContext) {
? workspaceFolder.uri.fsPath ? workspaceFolder.uri.fsPath
: path.dirname(fileName); : path.dirname(fileName);
const config = vscode.workspace.getConfiguration("newt"); const config = vscode.workspace.getConfiguration("newt");
// FIXME wrong newt now.
const cmd = config.get<string>("path", "build/exec/newt"); const cmd = config.get<string>("path", "build/exec/newt");
const command = `${cmd} --top ${fileName}`; const command = `${cmd} --top ${fileName}`;
let st = +new Date(); let st = +new Date();
@@ -85,7 +86,6 @@ export function activate(context: vscode.ExtensionContext) {
// extract errors and messages from stdout // extract errors and messages from stdout
const lines = stdout.split("\n"); const lines = stdout.split("\n");
const diagnostics: vscode.Diagnostic[] = []; const diagnostics: vscode.Diagnostic[] = [];
const others: Record<string, vscode.Diagnostic[]> = {};
if (err) { if (err) {
let start = new vscode.Position(0, 0); let start = new vscode.Position(0, 0);
@@ -118,26 +118,7 @@ export function activate(context: vscode.ExtensionContext) {
let [_full, kind, file, line, column, message] = match; let [_full, kind, file, line, column, message] = match;
let lnum = Number(line); let lnum = Number(line);
let cnum = Number(column); let cnum = Number(column);
if (file !== fileName) lnum = cnum = 0;
let severity;
if (kind === "ERROR") severity = vscode.DiagnosticSeverity.Error;
else if (kind === "WARN") severity = vscode.DiagnosticSeverity.Warning;
else severity = vscode.DiagnosticSeverity.Information;
// anything indented after the ERROR/INFO line are part of
// the message
while (lines[i + 1]?.match(/^( )/)) message += "\n" + lines[++i];
if (file !== fileName) {
console.log('MM', file, fileName, lnum, cnum);
let start = new vscode.Position(lnum, cnum);
let end = new vscode.Position(lnum, cnum + 1);
let range = new vscode.Range(start, end);
const diag = new vscode.Diagnostic(range, message, severity);
if (!others[file]) others[file] = [];
others[file].push(diag);
lnum = cnum = 0;
}
let start = new vscode.Position(lnum, cnum); let start = new vscode.Position(lnum, cnum);
// we don't have the full range, so grab the surrounding word // we don't have the full range, so grab the surrounding word
@@ -145,28 +126,32 @@ export function activate(context: vscode.ExtensionContext) {
let range = let range =
document.getWordRangeAtPosition(start) ?? document.getWordRangeAtPosition(start) ??
new vscode.Range(start, end); new vscode.Range(start, end);
// anything indented after the ERROR/INFO line are part of
// the message
while (lines[i + 1]?.match(/^( )/)) message += "\n" + lines[++i];
let severity;
if (kind === "ERROR") severity = vscode.DiagnosticSeverity.Error;
else if (kind === "WARN")
severity = vscode.DiagnosticSeverity.Warning;
else severity = vscode.DiagnosticSeverity.Information;
const diag = new vscode.Diagnostic(range, message, severity); const diag = new vscode.Diagnostic(range, message, severity);
if (kind === "ERROR" || lnum > 0) diagnostics.push(diag); if (kind === "ERROR" || lnum > 0) diagnostics.push(diag);
} }
} }
for (let file in others) {
diagnosticCollection.set(vscode.Uri.file(file), others[file])
}
diagnosticCollection.set(vscode.Uri.file(fileName), diagnostics); diagnosticCollection.set(vscode.Uri.file(fileName), diagnostics);
} }
); );
} }
const runPiForall = vscode.commands.registerCommand( const runNewt = vscode.commands.registerCommand("newt-vscode.check", () => {
"newt-vscode.check", const editor = vscode.window.activeTextEditor;
() => { if (editor) {
const editor = vscode.window.activeTextEditor; const document = editor.document;
if (editor) { if (document.fileName.endsWith(".newt")) checkDocument(document);
const document = editor.document;
if (document.fileName.endsWith(".newt")) checkDocument(document);
}
} }
); });
context.subscriptions.push( context.subscriptions.push(
vscode.languages.registerDefinitionProvider( vscode.languages.registerDefinitionProvider(
@@ -187,7 +172,11 @@ export function activate(context: vscode.ExtensionContext) {
console.error("Workspace folder not found"); console.error("Workspace folder not found");
return null; return null;
} }
let uri = vscode.Uri.file(path.resolve(root.uri.fsPath, entry.fc.file)); // let uri = vscode.Uri.file(path.join(root.uri.fsPath, entry.fc.file));
let fileName = entry.fc.file;
if (!fileName.startsWith('/')) fileName = path.join(root.uri.fsPath, fileName);
let uri = vscode.Uri.file(fileName);
console.log('root', root.uri.fsPath, 'file', entry.fc.file, 'uri', uri);
let start = new vscode.Position(entry.fc.line, entry.fc.col); let start = new vscode.Position(entry.fc.line, entry.fc.col);
let range = new vscode.Range(start, start); let range = new vscode.Range(start, start);
return new vscode.Location(uri, range); return new vscode.Location(uri, range);
@@ -216,7 +205,51 @@ export function activate(context: vscode.ExtensionContext) {
) )
); );
context.subscriptions.push(runPiForall); context.subscriptions.push(
vscode.languages.registerDocumentSymbolProvider(
{ language: "newt" },
{
provideDocumentSymbols(document, token) {
console.log("DSP!!");
const symbols: vscode.DocumentSymbol[] = [];
// we should ask the compiler
const RE_FUNC = /^(|data|record|class|instance)\s*([\d\w']+)\s*:/;
for (let i = 0; i < document.lineCount; i++) {
const line = document.lineAt(i);
const match = line.text.match(RE_FUNC);
if (match) {
const prefix = match[1];
const functionName = match[2];
const range = new vscode.Range(
new vscode.Position(i, 0),
new vscode.Position(i, line.text.length)
);
let type = vscode.SymbolKind.Function;
let details = "Function";
if (prefix === "class") type = vscode.SymbolKind.Interface;
if (prefix === "instance") type = vscode.SymbolKind.Class;
if (prefix === "record") type = vscode.SymbolKind.Struct;
if (prefix === "data") type = vscode.SymbolKind.Struct;
const symbol = new vscode.DocumentSymbol(
functionName,
details,
type,
range, // full range
range // selection
);
symbols.push(symbol);
}
}
console.log("SYMBOLS", symbols);
return symbols;
},
}
)
);
context.subscriptions.push(runNewt);
vscode.workspace.onDidSaveTextDocument((document) => { vscode.workspace.onDidSaveTextDocument((document) => {
if (document.fileName.endsWith(".newt")) if (document.fileName.endsWith(".newt"))

View File

@@ -13,6 +13,9 @@ import {
} from "@codemirror/language"; } from "@codemirror/language";
import { ABBREV } from "./abbrev.js"; import { ABBREV } from "./abbrev.js";
// maybe use https://github.com/codemirror/legacy-modes/blob/main/mode/simple-mode.js instead.
// @codemirror/legacy-modes/mode/simple-mode.js
// prettier flattened this... // prettier flattened this...
const keywords = [ const keywords = [
"let", "let",

View File

@@ -169,14 +169,6 @@ const LOADING = "module Loading\n";
let value = localStorage.code || LOADING; let value = localStorage.code || LOADING;
let initialVertical = localStorage.vertical == "true"; let initialVertical = localStorage.vertical == "true";
// the editor might handle this itself with the right prodding.
effect(() => {
let text = state.output.value;
let editor = state.editor.value;
// TODO - abstract this for both editors
// if (editor) processOutput(editor, text);
});
interface EditorProps { interface EditorProps {
initialValue: string; initialValue: string;
} }
@@ -201,8 +193,12 @@ const language: EditorDelegate = {
console.log("LINT"); console.log("LINT");
let src = view.state.doc.toString(); let src = view.state.doc.toString();
localStorage.code = src localStorage.code = src
// we'll want to pull it from the file. let module = src.match(/module\s+([^\s]+)/)?.[1]
const fileName = state.currentFile.value; if (module) {
// This causes problems with stuff like aoc/... that reference files in the same directory
// state.currentFile.value = module.replace('.','/')+'.newt'
}
let fileName = state.currentFile.value;
console.log("FN", fileName); console.log("FN", fileName);
try { try {
let out = await runCommand({ let out = await runCommand({
@@ -411,7 +407,7 @@ const processOutput = (
if (m) fn = m[1]; if (m) fn = m[1];
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
const line = lines[i]; const line = lines[i];
const match = line.match(/(INFO|ERROR) at (.*):\((\d+), (\d+)\):\s*(.*)/); const match = line.match(/(INFO|ERROR) at ([^:]+):\((\d+), (\d+)\):\s*(.*)/);
if (match) { if (match) {
let [_full, kind, file, line, col, message] = match; let [_full, kind, file, line, col, message] = match;
let lineNumber = +line + 1; let lineNumber = +line + 1;