Skip to content
This repository has been archived by the owner on Jul 19, 2023. It is now read-only.

Commit

Permalink
0.4.4 final update
Browse files Browse the repository at this point in the history
  • Loading branch information
Jacob Friedman committed Aug 31, 2021
1 parent 93880e6 commit c71afc0
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 180 deletions.
5 changes: 5 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recommendations": [
"jacobfriedman.vsc-logtalk"
]
}
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
{
"logtalk.home.path": "/home/jfriedman/logtalk3",
"logtalk.executable.path": "lvmlgt.sh"
}
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ Feel free to report bugs or suggestions via [issues](https://github.com/arthwang

## Development

This extension has been package and tested with node v14.17.5 (latest LTS).
This extension has been package and tested with node v12.
You may install the extension directly from the .vsix file included in this repo.

`vsix:make` makes the .vsix file, `vsix:install` installs it.
Expand All @@ -178,6 +178,7 @@ You may install the extension directly from the .vsix file included in this repo

### Version 4:

- Regex overhaul & document lint
- Logtalk linter does not run upon opening a document or workspace .
- F8 performs `logtalk_make`.
- F9 loads via `logtalk_load`.
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "vsc-logtalk",
"displayName": "VSC-Logtalk",
"description": "Support for Logtalk language",
"version": "0.4.2",
"version": "0.4.4",
"publisher": "jacobfriedman",
"icon": "images/logtalk.png",
"license": "MIT",
Expand Down Expand Up @@ -294,7 +294,7 @@
"test": "tsc ./tests/runTest.ts",
"syntax4logtalk": "yaml2json --pretty --save ./syntaxes/logtalk.tmLanguage.yaml",
"vsix:make": "vsce package --baseImagesUrl https://raw.githubusercontent.com/llvm/llvm-project/master/clang-tools-extra/clangd/clients/clangd-vscode/",
"vsix:install": "code --install-extension vsc-logtalk-0.4.2.vsix"
"vsix:install": "code --install-extension vsc-logtalk-0.4.4.vsix"
},
"devDependencies": {
"@types/bluebird": "^3.5.25",
Expand Down
181 changes: 57 additions & 124 deletions src/features/logtalkLinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,15 @@ export default class LogtalkLinter implements CodeActionProvider {
private diagnostics: { [docName: string]: Diagnostic[] } = {};
private filePathIds: { [id: string]: string } = {};
private sortedDiagIndex: { [docName: string]: number[] } = {};
private msgRegex = /([^:]+):\s*([^:]+):(\d+):((\d+):)?((\d+):)?\s*([\s\S]*)/;
private msgRegex = /([^:]+):\s*([^:]+):(\d+):?\s*([\s\S]*)/;

private msgRegexSingle = /(\*|\!)+\s{5}(.+)\n[\*|\!]+\s{7}(.+)\n[\*|\!]\s{7}in file\s(\S+).+line\s(\d+)/;
private msgRegexMulti = /(\*|\!)+\s{5}(.+)\n[\*|\!]+\s{7}(.+)\n[\*|\!]\s{7}in file\s(\S+).+between lines\s(\d+)-(\d+)/;

private executable: string;
private documentListener: Disposable;
private openDocumentListener: Disposable;
private outputChannel: OutputChannel = null;
public outputChannel: OutputChannel = null;

constructor(private context: ExtensionContext) {
this.executable = null;
Expand All @@ -53,24 +57,27 @@ export default class LogtalkLinter implements CodeActionProvider {
return codeActions;
}
private parseIssue(issue: string) {
let match = issue.match(this.msgRegex);
if (match == null) return null;
let fileName = this.filePathIds[match[2]]
? this.filePathIds[match[2]]
: match[2];
let match = issue.match(this.msgRegexSingle) || issue.match(this.msgRegexMulti);
if (match == null) { return null; }

let severity: DiagnosticSeverity;
if (match[1] == "ERROR") severity = DiagnosticSeverity.Error;
else if (match[1] == "Warning") severity = DiagnosticSeverity.Warning;
let line = parseInt(match[3]) - 1;
// move up to above line if the line to mark error is empty
line = line < 0 ? 0 : line;
let fromCol = match[5] ? parseInt(match[5]) : 0;
fromCol = fromCol < 0 ? 0 : fromCol;
let toCol = match[7] ? parseInt(match[7]) : 200;
if(match[1] == '*') {
severity = DiagnosticSeverity.Warning
} else {
severity = DiagnosticSeverity.Error
}

let fileName = this.filePathIds[match[4]]
? this.filePathIds[match[4]]
: match[4];

let line = parseInt(match[5]);
let fromCol = 0
let toCol = 200 // Default horizontal range
let fromPos = new Position(line, fromCol);
let toPos = new Position(line, toCol);
let toPos = match.length == 7 ? new Position(parseInt(match[6]), toCol) : new Position(line, toCol);
let range = new Range(fromPos, toPos);
let errMsg = match[8];
let errMsg = match[2] + ' ' + match[3];
let diag = new Diagnostic(range, errMsg, severity);
if (diag) {
if (!this.diagnostics[fileName]) {
Expand All @@ -79,118 +86,46 @@ export default class LogtalkLinter implements CodeActionProvider {
this.diagnostics[fileName].push(diag);
}
}
}

public doPlint(textDocument: TextDocument, sendString) {
if (textDocument.languageId != "logtalk") {
return;
}
}

public lint(textDocument: TextDocument, message) {
console.log(message);
this.diagnostics = {};
this.sortedDiagIndex = {};
this.diagnosticCollection.delete(textDocument.uri);

let args: string[] = [],
goals: string = `logtalk_load('${textDocument.fileName}').`,
lineErr: string = "";

let cwd = dirname(textDocument.fileName);

let child = spawn(this.executable, args, {cwd})
.on("process", process => {
console.log('spawned!');
if (process.pid) {
process.stdin.write(goals);
process.stdin.end();
this.outputChannel.clear();
}
})
.on("stdout", out => {
console.log("lintout:" + out + "\n");
})
.on("stderr", (errStr: string) => {
console.log("linterr: " + errStr);
if (lineErr === "") {
let type: string;
let regex = /^(\*|\!)\s*(.+)/;
let match = errStr.match(regex);
if (match) {
if (match[1] === "*") {
type = "Warning";
}
if (match[1] === "!") {
type = "ERROR";
}
lineErr = type + ":" + match[2];
}
} else if (/in file/.test(errStr)) {
let regex = /in file (\S+).+lines?\s+(\d+)/;
let match = errStr.match(regex);
let errMsg: string;
if (match) {
lineErr = lineErr.replace(":", `:${match[1]}:${match[2]}`);
this.parseIssue(lineErr + "\n");
lineErr = "";
}
}
})
.then(result => {
console.log('fulfilled');
if (lineErr) {
this.parseIssue(lineErr + "\n");
}
for (let doc in this.diagnostics) {
let index = this.diagnostics[doc]
.map((diag, i) => {
return [diag.range.start.line, i];
})
.sort((a, b) => {
return a[0] - b[0];
});
this.sortedDiagIndex[doc] = index.map(item => {
return item[1];
});
this.diagnosticCollection.set(Uri.file(doc), this.diagnostics[doc]);
}
this.outputChannel.clear();
for (let doc in this.sortedDiagIndex) {
let si = this.sortedDiagIndex[doc];
for (let i = 0; i < si.length; i++) {
let diag = this.diagnostics[doc][si[i]];
let severity =
diag.severity === DiagnosticSeverity.Error ? "ERROR" : "Warning";
let msg = `${basename(doc)}:${diag.range.start.line +
1}:\t${severity}:\t${diag.message}\n`;
this.outputChannel.append(msg);
}
if (si.length > 0) {
this.outputChannel.show(true);
}
}
})
.catch(error => {
let message: string = null;
console.log(error);
if ((<any>error).code === "ENOENT") {
message =
"Cannot lint the logtalk file. The Logtalk executable was not found. Use the 'logtalk.executable.path' setting to configure";
} else {
message = error.message
? error.message
: `Failed to run logtalk executable using path: ${this.executable}. Reason is unknown.`;
}
this.outputMsg(message);
this.parseIssue(message);

console.log('Single:', message.match(this.msgRegexSingle));
console.log('Multi:', message.match(this.msgRegexMulti));

for (let doc in this.diagnostics) {
let index = this.diagnostics[doc]
.map((diag, i) => {
return [diag.range.start.line, i];
})
.sort((a, b) => {
return a[0] - b[0];
});
this.sortedDiagIndex[doc] = index.map(item => {
return item[1];
});
}

/*public triggerLinter(textDocument: TextDocument) {
if (textDocument.languageId !== "logtalk") {
return;
this.diagnosticCollection.set(Uri.file(doc), this.diagnostics[doc]);
}
for (let doc in this.sortedDiagIndex) {
let si = this.sortedDiagIndex[doc];
for (let i = 0; i < si.length; i++) {
let diag = this.diagnostics[doc][si[i]];
let severity =
diag.severity === DiagnosticSeverity.Error ? "ERROR" : "Warning";
this.outputChannel.append(message)
}
if (si.length > 0) {
this.outputChannel.show(true);
}
}
this.doPlint(textDocument);
}
*/

private loadConfiguration(): void {
let section = workspace.getConfiguration("logtalk");
Expand All @@ -203,10 +138,6 @@ export default class LogtalkLinter implements CodeActionProvider {
this.openDocumentListener.dispose();
}
}

this.documentListener = workspace.onDidSaveTextDocument(e => this.doPlint, this);
/* workspace.textDocuments.forEach(this.triggerLinter, this); */

}

public activate(subscriptions): void {
Expand Down Expand Up @@ -289,6 +220,7 @@ export default class LogtalkLinter implements CodeActionProvider {
position = diagnostics[si[i]].range.start;
}
}

editor.revealRange(diagnostics[si[i]].range, TextEditorRevealType.InCenter);

diagnostics.forEach(item => {
Expand All @@ -302,5 +234,6 @@ export default class LogtalkLinter implements CodeActionProvider {
});
editor.selection = new Selection(position, position);
this.outputChannel.show(true);

}
}
Loading

0 comments on commit c71afc0

Please sign in to comment.