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 15, 2020
1 parent a99b585 commit d6052d6
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 19 deletions.
6 changes: 6 additions & 0 deletions packages/filesystem/src/browser/file-resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,10 @@ export class FileResourceResolver implements ResourceResolver {
return resource;
}

async resolveWithoutSchemaCheck(uri: URI): Promise<FileResource> {
const resource = new FileResource(uri, this.fileSystem, this.fileSystemWatcher);
await resource.init();
return resource;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import TheiaURI from '@theia/core/lib/common/uri';
import { EditorManager } from '@theia/editor/lib/browser';
import { TextDocumentShowOptions } from '@theia/plugin-ext/lib/common/plugin-api-rpc-model';
import { DocumentsMainImpl } from '@theia/plugin-ext/lib/main/browser/documents-main';
import { createUntitledResource } from '@theia/plugin-ext/lib/main/browser/editor/untitled-resource';
import { createUntitledURI } from '@theia/plugin-ext/lib/main/browser/editor/untitled-resource';
import { fromViewColumn, toDocumentSymbol } from '@theia/plugin-ext/lib/plugin/type-converters';
import { ViewColumn } from '@theia/plugin-ext/lib/plugin/types-impl';
import { WorkspaceCommands } from '@theia/workspace/lib/browser';
Expand Down 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 createUntitledURI())
});
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
86 changes: 75 additions & 11 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,103 @@
* 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 { OpenerService } from '@theia/core/lib/browser';
import { FileResource, FileResourceResolver } 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(FileResourceResolver)
protected readonly fileResourceResolver: FileResourceResolver;

@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.fileResourceResolver);
} 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, fileResourceResolver?: FileResourceResolver) {
const that = this;
resources.set(this.uri.toString(), this);
if (fileResourceResolver) {
fileResourceResolver.resolveWithoutSchemaCheck(uri).then(resolvedFileResource => {
that.fileResource = resolvedFileResource;
});
}
}

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

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.fileResource) {
return this.fileResource.readContents(options);
} else {
return Promise.resolve('');
}
}

async saveContents(content: string, options?: { encoding?: string, overwriteEncoding?: string }): Promise<void> {
if (this.fileResource) {
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 async function createUntitledResource(content?: string, language?: string, uri?: URI, fileResourceResolver?: FileResourceResolver): Promise<UntitledResource> {
let extension;
if (language) {
for (const lang of monaco.languages.getLanguages()) {
if (lang.id === language) {
if (lang.extensions) {
extension = lang.extensions[0];
break;
}
}
}
}
return new UntitledResource(uri ? uri : new URI().withScheme(Schemes.UNTITLED).withPath(`/Untitled-${index++}${extension ? extension : ''}`),
content, fileResourceResolver);
}

export function createUntitledResource(content?: string, language?: string): UntitledResource {
export async function createUntitledURI(language?: string): Promise<URI> {
let extension;
if (language) {
for (const lang of monaco.languages.getLanguages()) {
Expand All @@ -58,5 +122,5 @@ export function createUntitledResource(content?: string, language?: string): Unt
}
}
}
return new UntitledResource(new URI().withScheme(Schemes.UNTITLED).withPath(`/Untitled-${index++}${extension ? extension : ''}`), content);
return new URI().withScheme(Schemes.UNTITLED).withPath(`/Untitled-${index++}${extension ? extension : ''}`);
}
10 changes: 5 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

0 comments on commit d6052d6

Please sign in to comment.