Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix error underlining and popup problems #153

Merged
merged 4 commits into from
Nov 11, 2024
Merged
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
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.2.4",
"version": "0.2.5",
"configurations": [
{
"name": "Run Extension",
Expand Down
2 changes: 1 addition & 1 deletion juvix.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.6.6
0.6.8
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 17 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "juvix-mode",
"version": "0.2.4",
"version": "0.2.5",
"license": "GPL-3.0",
"description": "Juvix Mode for VSCode",
"displayName": "Juvix",
Expand Down Expand Up @@ -442,23 +442,17 @@
"owner": "juvixerror",
"source": "Juvix Error",
"fileLocation": "autoDetect",
"pattern": [
{
"kind": "location",
"regexp": "^(.+):(\\d+)(?:-(\\d+))?:(\\d+)-(\\d+): (\\w+).*",
"file": 1,
"line": 2,
"endLine": 3,
"column": 4,
"endColumn": 5,
"severity": 6
},
{
"regexp": "(.*)",
"message": 1,
"loop": true
}
]
"pattern": {
"kind": "location",
"regexp": "^(.+):(\\d+)(?:-(\\d+))?:(\\d+)-(\\d+):\\s+(\\w+):(.*)$",
"file": 1,
"line": 2,
"endLine": 3,
"column": 4,
"endColumn": 5,
"severity": 6,
"message": 7
}
}
],
"commands": [
Expand Down Expand Up @@ -818,6 +812,11 @@
"default": true,
"description": "Disable ANSI formatting."
},
"juvix-mode.vscodeErrors": {
"type": "boolean",
"default": true,
"description": "Enable VSCode compatible error formatting."
},
"juvix-mode.showNameIds": {
"type": "boolean",
"default": false,
Expand Down
79 changes: 8 additions & 71 deletions src/check.ts
Original file line number Diff line number Diff line change
@@ -1,92 +1,29 @@
/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/

import * as vscode from 'vscode';
import * as user from './config';
import { isJuvixFile, runShellCommand, getDiagnosticFromError } from './utils/base';
import { isJuvixFile } from './utils/base';
import { logger } from './utils/debug';
import { setJuvixCommandStatusBarItem, inProgressJuvixCommandStatusBar, showExecResultJuvixStatusBar } from './statusbar';

export async function activate(context: vscode.ExtensionContext, diagnosticCollection: vscode.DiagnosticCollection) {
export async function activate(context: vscode.ExtensionContext, typecheckTask: vscode.Task) {
const config = new user.JuvixConfig();

const command = 'juvix-mode.typecheck-silent';

const commandHandler = async (doc: vscode.TextDocument, content: string) => {
const activeEditor = vscode.window.activeTextEditor;

if (activeEditor && activeEditor.document == doc) {
if (doc && isJuvixFile(doc)) {
const filePath = doc.fileName;

const typecheckerCall = [
config.getJuvixExec(),
config.getGlobalFlags(),
'typecheck',
config.getTypeckeckFlags(),
filePath,
].join(' ');

inProgressJuvixCommandStatusBar('Typecheck');
const { stdout, stderr, status } = await runShellCommand(typecheckerCall, content);

if (status !== 0) {
showExecResultJuvixStatusBar(false, 'Typecheck', stderr);
const diag = getDiagnosticFromError(stderr);
if (diag)
diagnosticCollection.set(doc.uri, [diag]);
}
else {
showExecResultJuvixStatusBar(true, 'Typecheck', stdout);
diagnosticCollection.delete(doc.uri);
}
return { stdout, stderr, status };
}
}
return undefined;
};

context.subscriptions.push(
vscode.commands.registerCommand(command, commandHandler),
);


context.subscriptions.push(
vscode.workspace.onDidCloseTextDocument(doc => diagnosticCollection.delete(doc.uri))
);

context.subscriptions.push(
vscode.window.onDidChangeActiveTextEditor(_ => {
setJuvixCommandStatusBarItem();
}
));

switch (config.typecheckOn()) {
case 'change':
context.subscriptions.push(
vscode.workspace.onDidChangeTextDocument(e => {
vscode.workspace.onDidChangeTextDocument(async e => {
const doc = e.document;
const activeEditor = vscode.window.activeTextEditor;
if (activeEditor && activeEditor.document === doc && isJuvixFile(doc))
vscode.commands.executeCommand(
'juvix-mode.typecheck-silent',
doc,
doc.getText(),
)
await vscode.tasks.executeTask(typecheckTask);
}),
);
break;
case 'save':
context.subscriptions.push(
vscode.workspace.onDidSaveTextDocument(doc => {
vscode.workspace.onDidSaveTextDocument(async doc => {
const activeEditor = vscode.window.activeTextEditor;
if (activeEditor && activeEditor.document === doc && isJuvixFile(doc))
vscode.commands.executeCommand(
'juvix-mode.typecheck-silent',
doc,
doc.getText(),
)
if (activeEditor && activeEditor.document === doc && isJuvixFile(doc)) {
await vscode.tasks.executeTask(typecheckTask);
}
}),
);
break;
Expand Down
5 changes: 5 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ export class JuvixConfig {
return this.workspaceConfig.get('noColors', true);
}

public vscodeErrors(): boolean {
return this.workspaceConfig.get('vscodeErrors', true);
}

public showNameIds(): boolean {
return this.workspaceConfig.get('showNameIds', false);
}
Expand Down Expand Up @@ -160,6 +164,7 @@ export class JuvixConfig {
public getGlobalFlags(): string {
const flags: string[] = [];
if (this.noColors()) flags.push('--no-colors');
if (this.vscodeErrors()) flags.push('--vscode');
if (this.showNameIds()) flags.push('--show-name-ids');
if (this.noTermination()) flags.push('--no-termination');
if (this.noPositivity()) flags.push('--no-positivity');
Expand Down
4 changes: 0 additions & 4 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ export async function activate(context: vscode.ExtensionContext) {
];
modules.forEach(module => module.activate(context));

let juvixDiagnosticCollection = vscode.languages.createDiagnosticCollection('juvix');
check.activate(context, juvixDiagnosticCollection);
context.subscriptions.push(juvixDiagnosticCollection);

vscode.commands.executeCommand('setContext', 'juvix-mode:ready', true);
}
}
1 change: 1 addition & 0 deletions src/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export function activate(_context: vscode.ExtensionContext) {
// this is the way to protect from unexpected behaviour of the `format` command
return stdout !== '' ? [vscode.TextEdit.replace(range, stdout)] : [];
} else {
// TODO: this should be parsed with the problem matcher
const errMsg: string = res.stderr.toString();
logger.warn(errMsg);
return [];
Expand Down
12 changes: 10 additions & 2 deletions src/highlighting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ map that associates a file path to the corresponding information for that file.
export async function activate(context: vscode.ExtensionContext) {
if (!config.enableSemanticSyntax()) return;
try {
const semanticTokensProvider = new Highlighter();
const highlighterProvider =
vscode.languages.registerDocumentSemanticTokensProvider(
{ language: 'Juvix', scheme: 'file' },
Expand Down Expand Up @@ -101,6 +100,13 @@ export const legend: vscode.SemanticTokensLegend = (function () {
})();

export class Highlighter implements vscode.DocumentSemanticTokensProvider {
private _onDidChangeSemanticTokens = new vscode.EventEmitter<void>();
public onDidChangeSemanticTokens = this._onDidChangeSemanticTokens.event;

public triggerRehighlighting(): void {
this._onDidChangeSemanticTokens.fire();
}

async provideDocumentSemanticTokens(
document: vscode.TextDocument,
_token: vscode.CancellationToken,
Expand Down Expand Up @@ -184,7 +190,7 @@ export class Highlighter implements vscode.DocumentSemanticTokensProvider {
? tk.interval.length
: tk.interval.endCol
: contentLines[l].length;
// lineLength represent the number of symbols we can see on the screen.
// lineLength represents the number of symbols we can see on the screen.
// However, in js, length for unicode symbols works not as expected, but
// rather shows the code units number.
// So we need to actually calculate all the code units.
Expand Down Expand Up @@ -267,3 +273,5 @@ export class Highlighter implements vscode.DocumentSemanticTokensProvider {
return token;
}
}

export const semanticTokensProvider = new Highlighter();
14 changes: 12 additions & 2 deletions src/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import * as vscode from 'vscode';
import * as user from './config';
import { logger } from './utils/debug';
import * as check from './check';
import { inProgressJuvixCommandStatusBar, showExecResultJuvixStatusBar } from './statusbar';

export const TASK_TYPE = 'Juvix';
Expand Down Expand Up @@ -37,6 +38,7 @@ export async function activate(context: vscode.ExtensionContext) {
const cmdName = task.name.replace(' ', '-');
let useCmdName;
if (cmdName === 'typecheck-silent') {
check.activate(context, task);
useCmdName = 'typecheck';
} else {
useCmdName = cmdName;
Expand Down Expand Up @@ -68,7 +70,6 @@ export async function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(initDisp);

const disp = vscode.tasks.onDidEndTaskProcess(e => {

if (e.execution.task.name === task.name) {
if (e.exitCode === 0) {
showExecResultJuvixStatusBar(true, useCmdName, '');
Expand Down Expand Up @@ -107,7 +108,13 @@ export class JuvixTaskProvider implements vscode.TaskProvider {
command: 'typecheck',
args: [config.getTypeckeckFlags(), '${file}'],
group: vscode.TaskGroup.Build,
reveal: vscode.TaskRevealKind.Silent,
reveal: vscode.TaskRevealKind.Always,
},
{
command: 'typecheck-silent',
args: [config.getTypeckeckFlags(), '${file}'],
group: vscode.TaskGroup.Build,
reveal: vscode.TaskRevealKind.Never,
},
{
command: 'compile',
Expand Down Expand Up @@ -227,6 +234,9 @@ export async function JuvixTask(
case 'update-dependencies':
exec = new vscode.ShellExecution(JuvixExec + `dependencies update`);
break;
case 'typecheck-silent':
exec = new vscode.ShellExecution(JuvixExec + ` typecheck ${fl}`);
break;
default:
exec = new vscode.ShellExecution(JuvixExec + ` ${input}`);
break;
Expand Down
30 changes: 0 additions & 30 deletions src/utils/autorunDisposable.ts

This file was deleted.

29 changes: 0 additions & 29 deletions src/utils/base.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/
import { spawn, spawnSync } from 'child_process';
import * as vscode from 'vscode';
import { Mutex } from 'async-mutex';
Expand Down Expand Up @@ -81,29 +78,3 @@ export async function runShellCommand(command: string, input?: string): Promise<
}
});
}

const regexJuvixError = /(?<file>.*):(?<line>\d+):(?<begin_col>\d+)-?(?<end_col>\d+)?:\s(?<err_type>.*):\s?(?<msg>((\n|.)*))/g;

export function getDiagnosticFromError(output: string): vscode.Diagnostic | undefined {
const { file, line, begin_col, end_col, err_type, msg } = regexJuvixError.exec(output)!.groups!;
if (!msg || !line || !begin_col) return undefined;
const range = new vscode.Range(
new vscode.Position(parseInt(line) - 1, parseInt(begin_col) - 1),
new vscode.Position(parseInt(line) - 1, parseInt(end_col ?? begin_col) - 1),
);
let severity;
switch (err_type) {
case 'error':
severity = vscode.DiagnosticSeverity.Error;
break;
case 'warning':
severity = vscode.DiagnosticSeverity.Warning;
break;
case 'info':
severity = vscode.DiagnosticSeverity.Information;
break;
}
const diag = new vscode.Diagnostic(range, msg, severity);
diag.source = 'Juvix';
return diag;
}