From c29970a7281b2a39d5bacfe29fac3d7f0a3886eb Mon Sep 17 00:00:00 2001 From: Victor Rubezhny Date: Fri, 8 Nov 2019 20:00:30 +0100 Subject: [PATCH] [vscode] No error message if vscode.open command is invoked with resource that doesn't exist #5667 Signed-off-by: Victor Rubezhny --- .../plugin-vscode-commands-contribution.ts | 73 ++++++++++++++++--- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/packages/plugin-ext-vscode/src/browser/plugin-vscode-commands-contribution.ts b/packages/plugin-ext-vscode/src/browser/plugin-vscode-commands-contribution.ts index 6acb4dadce13e..da27f2b77fd23 100644 --- a/packages/plugin-ext-vscode/src/browser/plugin-vscode-commands-contribution.ts +++ b/packages/plugin-ext-vscode/src/browser/plugin-vscode-commands-contribution.ts @@ -48,6 +48,8 @@ import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor'; import { inject, injectable } from 'inversify'; import { Position } from '@theia/plugin-ext/lib/common/plugin-api-rpc'; import URI from 'vscode-uri'; +import { FileSystem, FileStat } from '@theia/filesystem/lib/common'; +import { MessageClient, MessageType } from '@theia/core/lib/common'; export namespace VscodeCommands { export const OPEN: Command = { @@ -89,6 +91,10 @@ export class PluginVscodeCommandsContribution implements CommandContribution { protected readonly quickOpen: PrefixQuickOpenService; @inject(WorkspaceService) protected readonly workspaceService: WorkspaceService; + @inject(FileSystem) + protected readonly fileSystem: FileSystem; + @inject(MessageClient) + protected readonly messages: MessageClient; registerCommands(commands: CommandRegistry): void { commands.registerCommand(VscodeCommands.OPEN, { @@ -97,22 +103,29 @@ export class PluginVscodeCommandsContribution implements CommandContribution { if (!resource) { throw new Error(`${VscodeCommands.OPEN.id} command requires at least URI argument.`); } + if (!URI.isUri(resource)) { throw new Error(`Invalid argument for ${VscodeCommands.OPEN.id} command with URI argument. Found ${resource}`); } - let options: TextDocumentShowOptions | undefined; - if (typeof columnOrOptions === 'number') { - options = { - viewColumn: columnOrOptions - }; - } else if (columnOrOptions) { - options = { - ...columnOrOptions - }; + if (await this.shouldCreateBeforeOpen(new TheiaURI(resource))) { + const uri = new TheiaURI(resource); + const msg = `Unable to open "${uri}":

File not found!`; + this.messages.showMessage({ type: MessageType.Error, text: msg, actions: ['CREATE'] }) + .then(res => { + if (res === 'CREATE') { + this.getOrCreateDirectory(uri.parent).then(parent => { + if (parent) { + this.fileSystem.createFile(resource.toString()).then(async () => { + await this.openEditor(resource, columnOrOptions); + }); + } + }); + } + }); + } else { + await this.openEditor(resource, columnOrOptions); } - const editorOptions = DocumentsMainImpl.toEditorOpenerOptions(this.shell, options); - await open(this.openerService, new TheiaURI(resource), editorOptions); } }); @@ -445,4 +458,42 @@ export class PluginVscodeCommandsContribution implements CommandContribution { } ); } + + protected async shouldCreateBeforeOpen(uri: TheiaURI): Promise { + // Do not try to create a document which scheme is not a file + if (uri.scheme !== 'file') { + return false; + } + const stat = await this.fileSystem.getFileStat(uri.toString()); + if (stat && !stat.isDirectory) { + return false; + } + return true; + } + + protected async openEditor(uri: URI, columnOrOptions?: ViewColumn | TextDocumentShowOptions): Promise { + let options: TextDocumentShowOptions | undefined; + if (typeof columnOrOptions === 'number') { + options = { + viewColumn: columnOrOptions + }; + } else if (columnOrOptions) { + options = { + ...columnOrOptions + }; + } + const editorOptions = DocumentsMainImpl.toEditorOpenerOptions(this.shell, options); + return open(this.openerService, new TheiaURI(uri), editorOptions); + } + + protected async getOrCreateDirectory(uri: TheiaURI): Promise { + const stat = await this.fileSystem.getFileStat(uri.toString()); + if (stat) { + if (stat.isDirectory) { + return stat; + } + return this.getOrCreateDirectory(uri.parent); + } + return this.fileSystem.createFolder(uri.toString()); + } }