Skip to content

Commit

Permalink
Fix 'window.showTextDocument' to open resources with 'untitled' schema,
Browse files Browse the repository at this point in the history
Fixes #6565

Signed-off-by: Shimon Ben Yair <shimon.ben.yair@sap.com>
  • Loading branch information
ShimonBenYair committed Jan 2, 2020
1 parent a99b585 commit c216481
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
* and apply actions only to them
*/
commands.registerCommand({ id: 'workbench.action.files.newUntitledFile' }, {
execute: () => open(this.openerService, createUntitledResource().uri)
execute: async () => open(this.openerService, (await createUntitledResource()).uri)
});
commands.registerCommand({ id: 'workbench.action.files.openFile' }, {
execute: () => commands.executeCommand(WorkspaceCommands.OPEN_FILE.id)
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-ext/src/main/browser/documents-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export class DocumentsMainImpl implements DocumentsMain, Disposable {
async $tryCreateDocument(options?: { language?: string; content?: string; }): Promise<UriComponents> {
const language = options && options.language;
const content = options && options.content;
const resource = createUntitledResource(content, language);
const resource = await createUntitledResource(content, language);
return monaco.Uri.parse(resource.uri.toString());
}

Expand Down
79 changes: 66 additions & 13 deletions packages/plugin-ext/src/main/browser/editor/untitled-resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,91 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { ResourceResolver, Resource } from '@theia/core';
import { injectable, inject } from 'inversify';
import { TextDocumentContentChangeEvent } from 'vscode-languageserver-protocol';
import { Resource, ResourceResolver } from '@theia/core';
import URI from '@theia/core/lib/common/uri';
import { injectable } from 'inversify';
import { Schemes } from '../../../common/uri-components';
import { FileSystem } from '@theia/filesystem/lib/common/filesystem';
import { FileSystemWatcher } from '@theia/filesystem/lib/browser/filesystem-watcher';
import { OpenerService } from '@theia/core/lib/browser';
import { FileResource } from '@theia/filesystem/lib/browser';

const resources = new Map<string, UntitledResource>();
let index = 0;

@injectable()
export class UntitledResourceResolver implements ResourceResolver {
resolve(uri: URI): Resource | Promise<Resource> {
if (uri.scheme === Schemes.UNTITLED) {
return resources.get(uri.toString())!;

@inject(FileSystem)
protected readonly fileSystem: FileSystem;

@inject(FileSystemWatcher)
protected readonly fileSystemWatcher: FileSystemWatcher;

@inject(OpenerService)
protected readonly openerService: OpenerService;

async resolve(uri: URI): Promise<UntitledResource> {
if (uri.scheme !== Schemes.UNTITLED) {
throw new Error('The given uri is not untitled file uri: ' + uri);
} else {
const untitledResource = resources.get(uri.toString());
if (!untitledResource) {
return createUntitledResource('', '', uri, this.fileSystem, this.fileSystemWatcher);
} else {
return untitledResource;
}
}
throw new Error(`scheme ${uri.scheme} is not '${Schemes.UNTITLED}'`);
}
}

export class UntitledResource implements Resource {
private fileResource: FileResource;

constructor(public uri: URI, private content?: string) {
constructor(public uri: URI, private content?: string, private fileSystem?: FileSystem, private fileSystemWatcher?: FileSystemWatcher) {
resources.set(this.uri.toString(), this);
}

readContents(options?: { encoding?: string | undefined; } | undefined): Promise<string> {
return Promise.resolve(this.content ? this.content : '');
}

dispose(): void {
resources.delete(this.uri.toString());
}

async readContents(options?: { encoding?: string | undefined; } | undefined): Promise<string> {
if (this.content) {
return Promise.resolve(this.content);
} else if (this.fileSystem && await this.fileSystem.exists(this.uri.toString())) {
try {
const { stat, content } = await this.fileSystem.resolveContent(this.uri.toString(), options);
console.debug('The file : ' + this.uri.toString() + ' stat is :' + stat);
return content;
} catch (e) {
throw e;
}
} else if (this.fileResource) {
return this.fileResource.readContents(options);
} else {
return Promise.resolve('');
}
}

async saveContents(content: string, options?: { encoding?: string, overwriteEncoding?: string }): Promise<void> {
if (this.fileSystem && this.fileSystemWatcher) {
this.fileResource = new FileResource(this.uri, this.fileSystem, this.fileSystemWatcher);
await this.fileResource.init();
this.fileResource.saveContents(content, options);
}
}

async saveContentChanges(changes: TextDocumentContentChangeEvent[], options?: { encoding?: string, overwriteEncoding?: string }): Promise<void> {
if (this.fileResource) {
this.fileResource.saveContentChanges(changes, options);
}
}
}

export function createUntitledResource(content?: string, language?: string): UntitledResource {
export async function createUntitledResource(content?: string, language?: string,
uri?: URI, fileSystem?: FileSystem, fileSystemWatcher?: FileSystemWatcher): Promise<UntitledResource> {
let extension;
if (language) {
for (const lang of monaco.languages.getLanguages()) {
Expand All @@ -58,5 +110,6 @@ export function createUntitledResource(content?: string, language?: string): Unt
}
}
}
return new UntitledResource(new URI().withScheme(Schemes.UNTITLED).withPath(`/Untitled-${index++}${extension ? extension : ''}`), content);
return new UntitledResource(uri ? uri : new URI().withScheme(Schemes.UNTITLED).withPath(`/Untitled-${index++}${extension ? extension : ''}`),
content, fileSystem, fileSystemWatcher);
}
11 changes: 6 additions & 5 deletions packages/plugin-ext/src/plugin/documents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,11 @@ export class DocumentsExtImpl implements DocumentsExt {
protected async fireTextDocumentWillSaveEvent({
document, reason, fireEvent, accept
}: {
document: theia.TextDocument,
reason: theia.TextDocumentSaveReason,
fireEvent: (e: theia.TextDocumentWillSaveEvent) => any,
accept: (operation: SingleEditOperation) => void
}): Promise<void> {
document: theia.TextDocument,
reason: theia.TextDocumentSaveReason,
fireEvent: (e: theia.TextDocumentWillSaveEvent) => any,
accept: (operation: SingleEditOperation) => void
}): Promise<void> {

const promises: PromiseLike<TextEdit[] | any>[] = [];
fireEvent(Object.freeze({
Expand Down Expand Up @@ -221,6 +221,7 @@ export class DocumentsExtImpl implements DocumentsExt {
// return opened document
return document;
} catch (error) {
console.log(error);
return Promise.reject(error);
} finally {
// remove loader from the map
Expand Down

0 comments on commit c216481

Please sign in to comment.