我正在创建一个语言服务器,目前有一个静态/预加载完成项列表。该语言服务器将在任何.script
文件上激活。在同一目录中将存在.map
文件(任意扩展名,我不是指JS源地图文件)。映射文件只是一个纯文本文档,其中包含类名和名称列表(对于每个“实体”)。典型条目可能如下所示:
// entity 237
{
"classname" "func_static"
"name" "func_static_237"
"origin" "200 179.5 -181"
"rotation" "0 -1 0 1 0 0 0 0 1"
}
我正在尝试将每个名称/类名对添加到完成列表中(名称是完成项标签,类名是详细信息)。以下是我到目前为止所做的事情:
由于不幸的是单独出现'classname',我选择使用匹配两行的正则表达式。然后我使用两个捕获组(一个用于名称,一个用于类名)将两者都推入一个数组。然后,我遍历数组中的每一对并将其添加到完成列表。
我的想法是我将映射文件中的变量预加载到相应的脚本文件中(它们都具有相同的文件名并且位于同一目录中)。
代码如下所示:
'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();
}
当我在Extension Development Host中调试扩展时,调试控制台显示:
C:\ Program Files \ Microsoft VS Code \ Code.exe --debugBrkPluginHost = 37535 --debugId = cfbf2c6d-c313-46fa-8c44-4e64f44eb97f --extensionDevelopmentPath = c:\ Users \ thefyrewire \ Documents \ VSCode \ quadscript
然后当我输入 func 时,它们会按预期显示它们是从文件中成功读取的(存在于c:\Users\thefyrewire\Documents\VSCode\quadscript\donkey.map
,对应于 extensionDevelopmentPath 如调试控制台中所示。)
我接下来转到c:\Users\thefyrewire\Documents\test
并将donkey.script
和donkey.map
文件移到此处,然后打包并安装了扩展程序。当我进入脚本文件并调出完成列表时,func_static项目不存在。我想这是因为它试图读取.vscode\extensions\<extension>\donkey.map
中安装扩展的位置,因为我移动文件时现在不存在。
所以我试着改变我读取地图文件的路径,并使用绝对路径作为测试。
var text = fs.readFileSync("file:///C:/Users/thefyrewire/Documents/test/donkey.map");
调试时我得到了这个:
ENOENT:没有这样的文件或目录,打开'C:\ Program Files \ Microsoft VS Code \ file:\ C:\ Users \ thefyrewire \ Documents \ test \ donkey.map'。 关 警告
使用类似的相对路径:
var text = fs.readFileSync("./donkey.map");
返回:
ENOENT:没有这样的文件或目录,打开'C:\ Program Files \ Microsoft VS Code \ donkey.map'。 关 警告
我尝试了多种其他fs方法,似乎只是从C:\Program Files\Microsoft VS Code
开始阅读。
最后我的问题是:为了允许我的扩展从与加载的脚本文件相同的目录动态读取,我需要做什么?非常感谢任何建议,谢谢!
编辑:我意识到这一点尚不清楚。通过'脚本文件'我不是指JS脚本文件,它又是自定义语言的一部分(因此是语言服务器)。
答案 0 :(得分:0)
您可以使用__dirname
var fs = require('fs')
var path = require('path')
var text = fs.readFileSync(path.join(__dirname, donkey.map));