0

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).

completion items successfully read from another file

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).

+1

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. –

Antwort

0

können Sie __dirname

var fs = require('fs') 
var path = require('path') 

var text = fs.readFileSync(path.join(__dirname, donkey.map)); 
+0

Danke, aber als ich das versuchte, versuchte es nur, die Datei in demselben Verzeichnis zu öffnen, in dem die js-Datei lief (im Erweiterungsordner), wie beim ersten Mal, als ich es versuchte. Ich versuche eine Möglichkeit zu finden, das aktuelle Verzeichnis der Skriptdatei zu finden (welches ein Benutzer öffnen kann und daher zwischen verschiedenen Dateien wechselt) – thefyrewire

Verwandte Themen