Ich erstelle einen Sprachserver und habe derzeit eine Liste mit statischen/vorinstallierten Abschlusselementen. Dieser Sprachserver wird auf einer beliebigen .script
Datei aktiviert. Im selben Verzeichnis existiert eine .map
Datei (beliebige Erweiterung, ich beziehe mich nicht auf JS Source Map Dateien). Die Map-Datei ist nur ein einfaches Textdokument, das eine Liste von Klassennamen und Namen (für jede 'Entity') enthält. Ein typischer Eintrag könnte wie folgt aussehen:Lesen einer anderen Datei im selben Verzeichnis wie die aktuelle Datei (VS-Code)
// entity 237
{
"classname" "func_static"
"name" "func_static_237"
"origin" "200 179.5 -181"
"rotation" "0 -1 0 1 0 0 0 0 1"
}
Ich versuche, jeden Namen/classname Paar auf die Vervollständigungsliste hinzuzufügen (Name der Fertigstellung Artikel Label zu sein, und der Klassenname ist das Detail). Hier ist, was ich bis jetzt getan habe:
Da es leider einzelne Fälle von 'Classname' gibt, entschied ich mich für eine Regex, die über beide Zeilen übereinstimmt. Dann benutzte ich zwei Capture-Gruppen (eine für Name und eine für Klassenname), um beide in ein Array zu schieben. Ich wiederhole dann jedes Paar im Array und füge es der Abschlussliste hinzu.
Die Idee ist, dass ich Variablen aus einer Map-Datei in die entsprechende Skript-Datei vorab laden (sie haben beide den gleichen Dateinamen und sind im selben Verzeichnis).
Der Code sieht wie folgt aus:
'use strict';
import * as path from 'path';
import * as vscode from 'vscode';
import * as fs from 'fs';
export function activate(context: vscode.ExtensionContext) {
...
// each pair will go into this
var objArray = new Array;
function readTextFile() {
// load the map file
var text = fs.readFileSync(context.asAbsolutePath(path.join('donkey.map')));
// match classname and name
var regex = /\"classname\"\s\"(\w+)\"(?:\r\n|[\r\n])\"name\"\s\"(\w+)\"/g
getMatches(text.toString(), regex);
}
function getMatches(string: string, regex: RegExp) {
var match;
while (match = regex.exec(string)){
// capture group 1 = classname
// capture group 2 = name
// pushing name first because it's more important
objArray.push([match[2], match[1]]);
}
}
var loop1 = function (i: number) {
// create a new completion item
vscode.languages.registerCompletionItemProvider('quadscript', {
provideCompletionItems: function() {
var compItem = new vscode.CompletionItem(objArray[i][0], vscode.CompletionItemKind.Variable);
compItem.insertText = ("$" + objArray[i][0]);
compItem.detail = (objArray[i][1]);
return [
compItem
];
}
});
}
for (var i = 0; i < objArray.length; i++) {
loop1(i);
}
readTextFile();
}
Als ich die Erweiterung in der Extension Development Host-debuggen, die Debug-Konsole zeigt dies:
C: \ Programme \ Microsoft VS-Code \ Code.exe --debugBrkPluginHost = 37535 --debugId = cfbf2c6d-c313-46fa-8c44-4e64f44eb97f --extensionDevelopmentPath = c: \ Users \ thefyrewire \ Dokumente \ VSCode \ quadscript
Und dann, wenn ich func füge, zeigen sie wie erwartet an, dass sie erfolgreich aus der Datei gelesen wurden (die bei c:\Users\thefyrewire\Documents\VSCode\quadscript\donkey.map
existiert, die dem extensionDevelopmentPath wie in der Debug-Konsole angezeigt wird).
Ich ging neben c:\Users\thefyrewire\Documents\test
und zog die donkey.script
und donkey.map
Dateien hier, dann verpackt und die Erweiterung installiert. Als ich in die Skriptdatei ging und die Abschlussliste anzeigte, waren die func_static-Elemente nicht vorhanden. Ich denke, das ist, weil es versucht zu lesen, wo die Erweiterung in .vscode\extensions\<extension>\donkey.map
installiert ist, die jetzt nicht existiert, wie ich die Datei verschoben habe.
Also habe ich versucht, den Pfad zu ändern, von wo ich die Map-Datei gelesen und einen absoluten Pfad als Test verwendet.
var text = fs.readFileSync("file:///C:/Users/thefyrewire/Documents/test/donkey.map");
Wenn Debuggen erhalte ich diese zurückgegeben:
ENOENT: keine solche Datei oder das Verzeichnis, offen ‚C: \ Programme \ Microsoft VS-Code \ file: \ C: \ Benutzer \ thefyrewire \ Dokumente \ test \ eskey.map '. Schließen Warn
einen relativen Pfad wie folgt:
var text = fs.readFileSync("./donkey.map");
Returns:
ENOENT: keine solche Datei oder das Verzeichnis, offen ‚C: \ Programme \ Microsoft VS Code \ eskey.map '. Schließen Warn
ich mehrere andere fs Methoden ausprobiert und es scheint nur aus C:\Program Files\Microsoft VS Code
Lesen zu beginnen.
Also meine Frage: Was muss ich tun, damit meine Erweiterung dynamisch aus dem selben Verzeichnis lesen kann wie die Skriptdatei? Jeder Rat würde sehr geschätzt werden, danke!
Edit: Ich weiß, das ist unklar. Mit 'Skriptdatei' meine ich keine JS-Skriptdatei, es ist wieder Teil der benutzerdefinierten Sprache (daher der Sprachserver).
verwenden Es ist seltsam Sie LSP-Server-Code in 'activate' haben, um zu sehen, wie die meisten bestehenden Sprach-Server-Implementierungen einen separaten Prozess verwenden. Wann müssen Sie die .map-Datei lesen? Wenn es nur gelesen werden sollte, bevor Abschlusselemente vorbereitet werden, sollten Sie das 'TextDocumentPositionParams.textDocument' verwenden, um zuerst den JS-Dateipfad zu suchen und dann den .map-Dateipfad zu berechnen. Wie auch immer, teile das Problem in kleinere Schritte und erobere sie einzeln. –