Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 如何在vscode扩展名中实现“保存到文件”检查覆盖?_Typescript_Visual Studio Code_Vscode Extensions - Fatal编程技术网

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

Typescript 如何在vscode扩展名中实现“保存到文件”检查覆盖?,typescript,visual-studio-code,vscode-extensions,Typescript,Visual Studio Code,Vscode Extensions,我必须在VisualStudio代码扩展中实现一个非常典型的编程模式:将某些内容保存到文件中,但在执行此操作之前检查目标文件是否存在,如果存在,请询问用户是否可以覆盖它 通常我会打开一个文件保存对话框,要求用户给我一个文件名,这个对话框会进行所有必要的检查,并在必要时得到用户的确认。然而,在vscode中,我们没有一个文件保存对话框。所以我正试图用我们有限的手段来实现这一点。幸运的是,几周前在消息对话框中添加了一个新的选项参数,使它们成为模态。但不知怎么的,我没能把握好时机。这是我的密码:

我必须在VisualStudio代码扩展中实现一个非常典型的编程模式:将某些内容保存到文件中,但在执行此操作之前检查目标文件是否存在,如果存在,请询问用户是否可以覆盖它

通常我会打开一个文件保存对话框,要求用户给我一个文件名,这个对话框会进行所有必要的检查,并在必要时得到用户的确认。然而,在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的调用是非阻塞的,这意味着当已经执行if canWrite之后,对话框本身是模态的,打开代码。这不是一个大问题,因为此时canWrite为false,但是,一旦showWarningMessage thenable返回,则从showInputBox返回的外部thenable中不再执行任何代码,即if canWrite不会像我预期的那样再次执行。是不可能嵌套2个表,还是我做错了什么

经验丰富的typescript/vscode开发人员如何完成此任务?

showWarningMessage无法按您的需要显示,您无法嵌套它。相反,您必须创建自己的Thenable方法,这需要一些重构

其主要思想是,您的储蓄必须返回一个承诺,并且它将在需要时控制showWarningMessage返回

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);
        }
    });
}
现在,您的扩展代码将采用thenable方法,正如您所期望的:

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)
                }
            });

    }
})

你的解决方案很有意义,我将来可能会用到。现在,我只需将我的保存代码移动到一个单独的函数,并直接调用它,或者在我找到一个现有文件并且用户同意覆盖它时调用它。
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)
                }
            });

    }
})