当前位置: 首页 > 知识库问答 >
问题:

如何在vscode扩展中实现“保存到文件”检查覆盖?

姚新霁
2023-03-14

我必须在Visual Studio Code扩展中实现一个非常典型的编程模式:将一些东西保存到文件中,但是在这样做之前检查目标文件是否存在,并询问用户是否可以覆盖它,如果可以的话。

通常我会打开一个文件保存对话框,要求用户给我一个文件名,这个对话框会进行所有必要的检查,并在必要时得到用户的确认。然而,在vscode中,我们没有文件保存对话框(但是有一个特性请求)。所以我试图用我们有限的手段来实现这一点。幸运的是,几周前,一个新的选项参数被添加到消息对话框中,使它们成为模态。但不知怎么的,我没能把握好时机。这是我的代码:

    window.showInputBox({
        placeHolder: "<Enter full file name here>",
        prompt: "Enter the name to an html file to save the diagram\n" }
    ).then((value: string) => {
        if (value) {
            let canWrite = true;
            if (fs.existsSync(value)) {
                canWrite = false;
                window.showWarningMessage("The specified file exists already", { modal: true }, ...[ "Overwrite" ]).then((action: string) => {
                    if (action === "Overwrite") {
                        canWrite = true;
                    }
                });
            }

            if (canWrite) {
                var stream = fs.createWriteStream(value, { encoding: "utf-8", autoClose: true });
                stream.on("error", function (error: any) {
                    window.showErrorMessage("Could not write to file '" + value + "'. " + error);
                });
                stream.once('open', function (fd) {
                    stream.write(text);
                    stream.end();

                    window.showInformationMessage("Diagram successfully written to file '" + value + "'.");
                });
            }
        }
    })

问题是对window.showWarningMessage的调用是非阻塞的,这意味着当对话框(它本身是模态的)在之后打开代码时,如果(can↑)已经执行。这不是一个大问题,因为此时canWritefalse,但是,一旦show WarningMessagethable返回,外部thable(从show InputBox)中不再执行任何代码,即>如果(can↑)没有再次执行(如我所料)。是不可能嵌套2线还是我还做错了什么?

一个有经验的typecript/vscode开发人员如何处理这项任务?

共有1个答案

饶明亮
2023-03-14

show WarningMessage不是你需要的thable,你不能嵌套它。相反,您必须创建自己的Thable方法,这需要一点重构。

主要思想是,您的保存必须返回一个Promise,它将控制show WarningMessage返回(当需要时)

function saveDiagram(text, filename): Promise<string | boolean> {
    return new Promise((resolve, reject) => {
        if (fs.existsSync(filename)) {
            vscode.window.showWarningMessage("The specified file exists already", { modal: true }, ...[ "Overwrite" ]).then((action: string) => {
                if (action === "Overwrite") {
                    resolve(filename);
                } else {
                    resolve(false);
                }
            });
        } else {
            resolve(filename);
        }
    });
}

还可以将写图表提取到磁盘上作为一个新函数,称为后一个函数:

function writeDiagramOnDisk(text, filename) {
    var stream = fs.createWriteStream(filename, { encoding: "utf-8", autoClose: true });
    stream.on("error", function (error: any) {
        vscode.window.showErrorMessage("Could not write to file '" + filename + "'. " + error);
    });
    stream.once('open', function (fd) {
        stream.write(text);
        stream.end();

        vscode.window.showInformationMessage("Diagram successfully written to file '" + filename + "'.");
    });
}

现在,您的扩展代码将采用thable方法,正如您所期望的那样:

vscode.window.showInputBox({
    placeHolder: "<Enter full file name here>",
    prompt: "Enter the name to an html file to save the diagram\n" }
).then((value: string) => {
    if (value) {
        saveDiagram(text, value)
            .then((filename) => {
                if (filename) {
                    writeDiagramOnDisk(text, filename)
                }
            });

    }
})
 类似资料:
  • 问题内容: 我正在某个程序上工作,根据文件的扩展名,我需要做不同的事情。我可以用这个吗? 问题答案: 假设是一个字符串,可以使用: 要不区分大小写,并消除可能很大的else-if链:

  • 当前在VSCode设置中,您可以按以下方式配置保存时的格式: 我想排除一些文件扩展名,例如只格式化JavaScript,但不包括超文本标记语言文件。

  • 问题内容: 我有一个上传脚本,需要检查文件扩展名,然后基于该文件扩展名运行单独的功能。有人知道我应该使用什么代码吗? 问题答案: 是您要寻找的 PHP.net

  • 问题内容: 我必须将数据从Excel文件导入数据库,并执行此操作,我想检查所选文件的扩展名。 这是我的代码: 但是我总是得到: 选择一个Excel文件! 我找不到我的代码有什么问题,请有人帮忙。 问题答案: 以下 应该 要么

  • 问题内容: 我正在使用.NET 2.0,Linq毫无疑问。我想检查文件是否存在于目录中, 而无需了解文件扩展名 。 我只需要完成此逻辑即可。 1.使用搜索模式提供的字符串文件名检查目录中的文件是否存在,而忽略文件的扩展名 2.获取文件(如果存在)并进行数据绑定以提供。如果文件不存在,则开始上载文件。 更新: 和确实解决了其中我检查文件的存在的部分。至于FileInfo对象的性能,这些仅是我对数据绑

  • 我已经创建了一个chrome扩展来学习英语,它可以构建一个包含源代码/翻译等的词典。 现在,我想将这个“文件”(我将/会用字典条目构建一个“文件”)发送到Google Drive,并在我的Android应用程序中使用这个文件。 但我不想将此文件保存在我的个人驱动器帐户中,而是保存在当前用户的驱动器中,即使用chrome扩展名的用户(当然,如果该用户有驱动器帐户)。 在我找到的所有例子中,他们为“我