【问题标题】:Set programmatically jsonValidation for dynamic mapping以编程方式为动态映射设置 jsonValidation
【发布时间】:2019-10-18 07:59:40
【问题描述】:

我正在创建一个新的 vscode 扩展,我需要扩展已经存在于 vscode 中的 jsonValidation 系统的标准用法。

注意:我说的是package.json中定义的系统:

"contributes" : {
    "languages": [
        {
            "id" : "yml", 
            "filenamePatterns": ["module.service"]
        },
        {
            "id" : "json", 
            "filenamePatterns": ["module.*"]
        }
    ],
    "jsonValidation": [
        {
            "fileMatch": "module.test",
            "url": "./resources/test.schema"
        }
    ]
}

现在,我需要创建一个动态映射,其中 json 字段 filematch/url 是根据一些内部规则(如版本和其他内部内容)定义的。标准用法是静态的:一个文件匹配 -> 一个模式。

例如,我想从 json 文件中读取版本进行验证,然后设置架构:

{
    "version" : "1.1"
}

验证架构必须是 test-schema.1.1 而不是 test-schema.1.0

注意:问题只是关于从 extensions.ts 修改 package.json 提供的配置

感谢支持

【问题讨论】:

    标签: vscode-extensions


    【解决方案1】:

    ** 编辑,因为以前的解决方案并非在所有情况下都有效

    在函数激活时修改package.json有一种解决方案。

    export function activate(context: vscode.ExtensionContext) {
        const myPlugin = vscode.extensions.getExtension("your.plugin.id");
        if (!myPlugin)
        {
            throw new Error("Composer plugin is not found...")
        }
    
        // Get the current workspace path to found the schema later.
        const folderPath = vscode.workspace.workspaceFolders;
        if (!folderPath)
        {
            return;
        }
        const baseUri : vscode.Uri = folderPath[0].uri;
    
        let packageJSON = myPlugin.packageJSON;
        if (packageJSON && packageJSON.contributes && packageJSON.contributes.jsonValidation)
        {
            let jsonValidation = packageJSON.contributes.jsonValidation;
            const schemaUri : vscode.Uri =  vscode.Uri.joinPath(baseUri, "/schema/value-0.3.0.json-schema");            
            const schema = new JsonSchemaMatch("value.ospp", schemaUri)
            jsonValidation.push(schema);
        }
    }
    
    

    还有 json 模式类

    class JsonSchemaMatch 
    {
        fileMatch: string;
        url : string;
    
        constructor(fileMatch : string, url: vscode.Uri) 
        {
            this.fileMatch = fileMatch;
            this.url = url.path;
        }
    }
    

    另外一个重要的信息是contribs的元素的加载在修改后不会重读,例如

    class Language 
    {
        id: string;
        filenamePatterns : string[];
    
        constructor(id : string, filenamePatterns: string[]) 
        {
            this.id = id;
            this.filenamePatterns = filenamePatterns;
        }
    }
    
    if (packageJSON && packageJSON.contributes && packageJSON.contributes.languages)
        {
            let languages : Language[] = packageJSON.contributes.languages;
            for (let language of languages) {
                if (language.id == "json") {
                    language.filenamePatterns.push("test.my-json-type")
                }
            }
        }
    

    这个改动是没有效果的,因为文件关联的加载已经完成了(原因我没有去挖掘,但我觉得是这样的)

    在这种情况下,在工作区目录中创建一个 settings.json 就可以完成这项工作:

    settings.json

    {
      "files.associations": {
        "target.snmp": "json",
        "stack.cfg": "json"
      }
    }
    

    请注意,settings.json 可以由用户出于正当理由创建,因此不要覆盖它,只需填写即可。

    【讨论】:

    • 如何防止vscode.commands.executeCommand('workbench.action.reloadWindow'); 创建无限循环?对我来说,每次 reloadWindow 后,package.json 都会被重置,并且更改不会生效。
    • 在我的用例中,我可以在重新加载时使用条件,因为我知道是否必须重新加载配置。也许你也可以这样做(在我的例子中,我在用户工作区中有一个设置文件)
    • 我的用例是我需要为contributes.languages中的一种语言添加扩展,该扩展必须来自package.json,我认为必须在打包扩展时对其进行处理,然后不再读取,因为我可以查看 package.json 并看到正确的更改,但没有使用它。如果您对如何完成这项工作有任何想法,我将不胜感激。
    • 我第一次发表评论时正在度假,无法访问我的编码站。我做了一些检查,我认为您的问题是您正在更改 vscode 在插件启动时读取的一些设置。我已经为语言关联遇到了这个问题,在这种情况下,我创建了更新 settings.json 的方法。我认为,如果您无法更改 settings.json 以反映您的需求,那么您注定要失败,但我远非 vscode 专家。
    • 我做了同样的工作,有一个解决方法。在文件 settings.json 中添加您的信息(在打开的工作区中)。此设置在工作区打开时读取,请注意不要覆盖 settings.json 而是添加您的信息,因为用户可以合法使用此文件。如果您需要代码示例,请打开一个问题,我将通过示例给出答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多