mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 13:00:58 +00:00
hacking my way around
This commit is contained in:
parent
c62644ed13
commit
689dcf546f
|
@ -33,6 +33,7 @@
|
|||
"https-proxy-agent": "0.3.6",
|
||||
"iconv-lite": "0.4.15",
|
||||
"jschardet": "^1.5.1",
|
||||
"jsftp": "^2.0.0",
|
||||
"keytar": "^4.0.3",
|
||||
"minimist": "1.2.0",
|
||||
"native-keymap": "1.2.5",
|
||||
|
@ -132,4 +133,4 @@
|
|||
"windows-mutex": "^0.2.0",
|
||||
"fsevents": "0.3.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,12 +135,14 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape {
|
|||
const emitter = new Emitter<URI>();
|
||||
const provider = {
|
||||
onDidChange: emitter.event,
|
||||
resolve: (resource: URI) => {
|
||||
read: (resource: URI) => {
|
||||
return this._proxy.$resolveFile(handle, resource);
|
||||
},
|
||||
update: (resource: URI, value: string) => {
|
||||
write: (resource: URI, value: string) => {
|
||||
return this._proxy.$storeFile(handle, resource, value);
|
||||
}
|
||||
},
|
||||
stat: () => null,
|
||||
readdir: () => null
|
||||
};
|
||||
const searchProvider = {
|
||||
search: (query: ISearchQuery) => {
|
||||
|
|
|
@ -1370,7 +1370,8 @@ export abstract class BaseSaveOneFileAction extends BaseSaveFileAction {
|
|||
if (this.resource) {
|
||||
source = this.resource;
|
||||
} else {
|
||||
source = toResource(this.editorService.getActiveEditorInput(), { supportSideBySide: true, filter: ['file', 'untitled'] });
|
||||
// source = toResource(this.editorService.getActiveEditorInput(), { supportSideBySide: true, filter: ['file', 'untitled'] });
|
||||
source = toResource(this.editorService.getActiveEditorInput(), { supportSideBySide: true });
|
||||
}
|
||||
|
||||
if (source) {
|
||||
|
|
|
@ -778,7 +778,7 @@ export class ExplorerView extends CollapsibleView {
|
|||
// Subsequent refresh: Merge stat into our local model and refresh tree
|
||||
modelStats.forEach((modelStat, index) => FileStat.mergeLocalWithDisk(modelStat, this.model.roots[index]));
|
||||
|
||||
const input = this.contextService.hasFolderWorkspace() ? this.model.roots[0] : this.model;
|
||||
const input = /* this.contextService.hasFolderWorkspace() ? this.model.roots[0] : */ this.model;
|
||||
if (input === this.explorerViewer.getInput()) {
|
||||
return this.explorerViewer.refresh();
|
||||
}
|
||||
|
|
|
@ -25,7 +25,10 @@ export class Model {
|
|||
private _roots: FileStat[];
|
||||
|
||||
constructor( @IWorkspaceContextService private contextService: IWorkspaceContextService) {
|
||||
const setRoots = () => this._roots = this.contextService.getWorkspace().roots.map(uri => new FileStat(uri, undefined));
|
||||
const setRoots = () => {
|
||||
this._roots = this.contextService.getWorkspace().roots.map(uri => new FileStat(uri, undefined));
|
||||
this._roots.push(new FileStat(URI.parse('ftp://waws-prod-db3-029.ftp.azurewebsites.windows.net/'), undefined));
|
||||
};
|
||||
this.contextService.onDidChangeWorkspaceRoots(() => setRoots());
|
||||
setRoots();
|
||||
}
|
||||
|
@ -262,7 +265,8 @@ export class FileStat implements IFileStat {
|
|||
}
|
||||
|
||||
private updateResource(recursive: boolean): void {
|
||||
this.resource = URI.file(paths.join(this.parent.resource.fsPath, this.name));
|
||||
this.resource = this.parent.resource.with({ path: paths.join(this.parent.resource.path, this.name) });
|
||||
// this.resource = URI.file(paths.join(this.parent.resource.fsPath, this.name));
|
||||
|
||||
if (recursive) {
|
||||
if (this.isDirectory && this.hasChildren && this.children) {
|
||||
|
@ -423,4 +427,4 @@ export class OpenEditor {
|
|||
public getResource(): URI {
|
||||
return toResource(this.editor, { supportSideBySide: true, filter: ['file', 'untitled'] });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -273,7 +273,7 @@ export class WorkbenchEditorService implements IWorkbenchEditorService {
|
|||
}
|
||||
|
||||
let input: ICachedEditorInput;
|
||||
if (resource.scheme === network.Schemas.file) {
|
||||
if (resource.scheme === network.Schemas.file || resource.scheme === 'ftp') {
|
||||
input = this.fileInputFactory.createFileInput(resource, encoding, instantiationService);
|
||||
} else {
|
||||
input = instantiationService.createInstance(ResourceEditorInput, label, description, resource);
|
||||
|
@ -359,4 +359,4 @@ export class DelegatingWorkbenchEditorService extends WorkbenchEditorService {
|
|||
return super.doCloseEditor(position, input);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import Event from 'vs/base/common/event';
|
||||
import * as JSFtp from 'jsftp';
|
||||
import { ninvoke } from 'vs/base/common/async';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Readable } from 'stream';
|
||||
import { join } from 'path';
|
||||
import { IStat } from 'vs/workbench/services/files/electron-browser/remoteFileService';
|
||||
|
||||
export class FtpFileSystemProvider {
|
||||
|
||||
private _connection: JSFtp;
|
||||
|
||||
onDidChange = Event.None;
|
||||
|
||||
constructor() {
|
||||
this._connection = new JSFtp({
|
||||
host: 'waws-prod-db3-029.ftp.azurewebsites.windows.net',
|
||||
user: 'performanto-slack-updater\\riejo-test',
|
||||
pass: 'Z0llikon'
|
||||
});
|
||||
this._connection.keepAlive(1000 * 5);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
//
|
||||
}
|
||||
|
||||
stat(resource: URI): TPromise<IStat> {
|
||||
|
||||
return ninvoke<JSFtp.Entry[]>(this._connection, this._connection.ls, resource.path).then(entries => {
|
||||
|
||||
if (entries.length === 1) {
|
||||
// stat one file
|
||||
const [entry] = entries;
|
||||
return {
|
||||
resource,
|
||||
mtime: entry.time,
|
||||
size: entry.size,
|
||||
isDirectory: false
|
||||
};
|
||||
}
|
||||
|
||||
// stat directory
|
||||
return <IStat>{
|
||||
resource,
|
||||
isDirectory: true,
|
||||
mtime: 0,
|
||||
size: 0
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
readdir(resource: URI): TPromise<IStat[]> {
|
||||
return ninvoke<JSFtp.Entry[]>(this._connection, this._connection.ls, resource.path).then(ret => {
|
||||
const promises: TPromise<IStat>[] = [];
|
||||
for (let entry of ret) {
|
||||
promises.push(this.stat(resource.with({ path: join(resource.path, entry.name) })));
|
||||
}
|
||||
return TPromise.join(promises);
|
||||
});
|
||||
}
|
||||
|
||||
write(resource: URI, content: string): TPromise<void> {
|
||||
return ninvoke(this._connection, this._connection.put, Buffer.from(content, 'utf8'), resource.path);
|
||||
}
|
||||
|
||||
read(resource: URI): TPromise<string> {
|
||||
return ninvoke<Readable>(this._connection, this._connection.get, resource.path).then(stream => {
|
||||
return new TPromise<string>((resolve, reject) => {
|
||||
let str = '';
|
||||
stream.on('data', function (d) {
|
||||
str += d.toString();
|
||||
});
|
||||
stream.on('close', function (hadErr) {
|
||||
if (hadErr) {
|
||||
reject(hadErr);
|
||||
} else {
|
||||
resolve(str);
|
||||
}
|
||||
});
|
||||
stream.resume();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
42
src/vs/workbench/services/files/electron-browser/jsftp.d.ts
vendored
Normal file
42
src/vs/workbench/services/files/electron-browser/jsftp.d.ts
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
|
||||
import { Readable } from 'stream';
|
||||
|
||||
declare namespace JSFtp {
|
||||
|
||||
|
||||
interface JSFtpOptions {
|
||||
host: string;
|
||||
port?: number | 21;
|
||||
user?: string | 'anonymous';
|
||||
pass?: string | '@anonymous';
|
||||
}
|
||||
|
||||
interface Callback<T> {
|
||||
(err: any, result: T): void;
|
||||
}
|
||||
|
||||
|
||||
interface Entry {
|
||||
name: string;
|
||||
size: number;
|
||||
time: number;
|
||||
type: 0 | 1;
|
||||
}
|
||||
}
|
||||
|
||||
interface JSFtp {
|
||||
keepAlive(wait?: number): void;
|
||||
ls(path: string, callback: JSFtp.Callback<JSFtp.Entry[]>): void;
|
||||
put(buffer: Buffer, path: string, callback: JSFtp.Callback<void>): void;
|
||||
get(path: string, callback: JSFtp.Callback<Readable>): void;
|
||||
raw<T = any>(command: string, args: any[], callback: JSFtp.Callback<T>): void
|
||||
}
|
||||
|
||||
interface JSFtpConstructor {
|
||||
new(options: JSFtp.JSFtpOptions): JSFtp;
|
||||
}
|
||||
|
||||
declare const JSFtp: JSFtpConstructor;
|
||||
|
||||
export = JSFtp;
|
|
@ -6,23 +6,128 @@
|
|||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { FileService } from 'vs/workbench/services/files/electron-browser/fileService';
|
||||
import { IContent, IStreamContent, IFileStat, IResolveContentOptions, IUpdateContentOptions, FileChangesEvent, FileChangeType } from 'vs/platform/files/common/files';
|
||||
import { IContent, IStreamContent, IFileStat, IResolveContentOptions, IUpdateContentOptions, FileChangesEvent, FileChangeType, IResolveFileOptions, IResolveFileResult } from 'vs/platform/files/common/files';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import Event from 'vs/base/common/event';
|
||||
import { EventEmitter } from 'events';
|
||||
import { basename } from 'path';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import * as Ftp from './ftpFileSystemProvider';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
|
||||
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { IMessageService } from 'vs/platform/message/common/message';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { groupBy, isFalsyOrEmpty } from 'vs/base/common/arrays';
|
||||
import { compare } from 'vs/base/common/strings';
|
||||
|
||||
|
||||
export interface IStat {
|
||||
resource: URI;
|
||||
mtime: number;
|
||||
size: number;
|
||||
isDirectory: boolean;
|
||||
}
|
||||
|
||||
function toIFileStat(provider: IRemoteFileSystemProvider, stat: IStat, recurse: boolean): TPromise<IFileStat> {
|
||||
const ret: IFileStat = {
|
||||
isDirectory: false,
|
||||
hasChildren: false,
|
||||
resource: stat.resource,
|
||||
name: basename(stat.resource.path),
|
||||
mtime: stat.mtime,
|
||||
size: stat.size,
|
||||
etag: stat.mtime.toString(3) + stat.size.toString(7),
|
||||
};
|
||||
|
||||
if (!stat.isDirectory) {
|
||||
// done
|
||||
return TPromise.as(ret);
|
||||
|
||||
} else {
|
||||
// dir -> resolve
|
||||
return provider.readdir(stat.resource).then(items => {
|
||||
ret.isDirectory = true;
|
||||
ret.hasChildren = items.length > 0;
|
||||
|
||||
if (recurse) {
|
||||
// resolve children if requested
|
||||
return TPromise.join(items.map(item => toIFileStat(provider, item, false))).then(children => {
|
||||
ret.children = children;
|
||||
return ret;
|
||||
});
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export interface IRemoteFileSystemProvider {
|
||||
onDidChange: Event<URI>;
|
||||
resolve(resource: URI): TPromise<string>;
|
||||
update(resource: URI, content: string): TPromise<any>;
|
||||
onDidChange?: Event<URI>;
|
||||
stat(resource: URI): TPromise<IStat>;
|
||||
readdir(resource: URI): TPromise<IStat[]>;
|
||||
write(resource: URI, content: string): TPromise<void>;
|
||||
read(resource: URI): TPromise<string>;
|
||||
}
|
||||
|
||||
export class RemoteFileService extends FileService {
|
||||
|
||||
// public existsFile(resource: URI): TPromise<boolean, any> {
|
||||
// throw new Error("Method not implemented.");
|
||||
// }
|
||||
// public moveFile(source: URI, target: URI, overwrite?: boolean): TPromise<IFileStat, any> {
|
||||
// throw new Error("Method not implemented.");
|
||||
// }
|
||||
// public copyFile(source: URI, target: URI, overwrite?: boolean): TPromise<IFileStat, any> {
|
||||
// throw new Error("Method not implemented.");
|
||||
// }
|
||||
// public createFile(resource: URI, content?: string): TPromise<IFileStat, any> {
|
||||
// throw new Error("Method not implemented.");
|
||||
// }
|
||||
// public createFolder(resource: URI): TPromise<IFileStat, any> {
|
||||
// throw new Error("Method not implemented.");
|
||||
// }
|
||||
// public touchFile(resource: URI): TPromise<IFileStat, any> {
|
||||
// throw new Error("Method not implemented.");
|
||||
// }
|
||||
// public rename(resource: URI, newName: string): TPromise<IFileStat, any> {
|
||||
// throw new Error("Method not implemented.");
|
||||
// }
|
||||
// public del(resource: URI, useTrash?: boolean): TPromise<void, any> {
|
||||
// throw new Error("Method not implemented.");
|
||||
// }
|
||||
|
||||
|
||||
private readonly _provider = new Map<string, IRemoteFileSystemProvider>();
|
||||
|
||||
constructor(
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IWorkspaceContextService contextService: IWorkspaceContextService,
|
||||
@IWorkbenchEditorService editorService: IWorkbenchEditorService,
|
||||
@IEnvironmentService environmentService: IEnvironmentService,
|
||||
@IEditorGroupService editorGroupService: IEditorGroupService,
|
||||
@ILifecycleService lifecycleService: ILifecycleService,
|
||||
@IMessageService messageService: IMessageService,
|
||||
@IStorageService storageService: IStorageService
|
||||
) {
|
||||
super(
|
||||
configurationService,
|
||||
contextService,
|
||||
editorService,
|
||||
environmentService,
|
||||
editorGroupService,
|
||||
lifecycleService,
|
||||
messageService,
|
||||
storageService,
|
||||
);
|
||||
this.registerProvider('ftp', new Ftp.FtpFileSystemProvider());
|
||||
}
|
||||
|
||||
registerProvider(authority: string, provider: IRemoteFileSystemProvider): IDisposable {
|
||||
if (this._provider.has(authority)) {
|
||||
throw new Error();
|
||||
|
@ -41,59 +146,96 @@ export class RemoteFileService extends FileService {
|
|||
};
|
||||
}
|
||||
|
||||
resolveFile(resource: URI, options?: IResolveFileOptions): TPromise<IFileStat, any> {
|
||||
const provider = this._provider.get(resource.scheme);
|
||||
if (provider) {
|
||||
return this._doResolveFiles(provider, [{ resource, options }]).then(data => {
|
||||
if (isFalsyOrEmpty(data)) {
|
||||
throw new Error('NotFound');
|
||||
}
|
||||
return data[0].stat;
|
||||
});
|
||||
}
|
||||
return super.resolveFile(resource, options);
|
||||
}
|
||||
|
||||
resolveFiles(toResolve: { resource: URI; options?: IResolveFileOptions; }[]): TPromise<IResolveFileResult[], any> {
|
||||
const groups = groupBy(toResolve, (a, b) => compare(a.resource.scheme, b.resource.scheme));
|
||||
const promises: TPromise<IResolveFileResult[], any>[] = [];
|
||||
|
||||
for (const group of groups) {
|
||||
const provider = this._provider.get(group[0].resource.scheme);
|
||||
if (!provider) {
|
||||
promises.push(super.resolveFiles(group));
|
||||
} else {
|
||||
promises.push(this._doResolveFiles(provider, group));
|
||||
}
|
||||
}
|
||||
|
||||
return TPromise.join(promises).then(data => {
|
||||
return [].concat(...data);
|
||||
});
|
||||
}
|
||||
|
||||
private _doResolveFiles(provider: IRemoteFileSystemProvider, toResolve: { resource: URI; options?: IResolveFileOptions; }[]): TPromise<IResolveFileResult[], any> {
|
||||
let result: IResolveFileResult[] = [];
|
||||
let promises: TPromise<any>[] = [];
|
||||
for (const item of toResolve) {
|
||||
promises.push(provider.stat(item.resource)
|
||||
.then(stat => toIFileStat(provider, stat, true))
|
||||
.then(stat => result.push({ stat, success: true })));
|
||||
}
|
||||
return TPromise.join(promises).then(() => result);
|
||||
}
|
||||
|
||||
// --- resolve
|
||||
|
||||
resolveContent(resource: URI, options?: IResolveContentOptions): TPromise<IContent> {
|
||||
if (this._provider.has(resource.authority)) {
|
||||
return this._doResolveContent(resource);
|
||||
const provider = this._provider.get(resource.scheme);
|
||||
if (provider) {
|
||||
return this._doResolveContent(provider, resource);
|
||||
}
|
||||
|
||||
return super.resolveContent(resource, options);
|
||||
}
|
||||
|
||||
resolveStreamContent(resource: URI, options?: IResolveContentOptions): TPromise<IStreamContent> {
|
||||
if (this._provider.has(resource.authority)) {
|
||||
return this._doResolveContent(resource).then(RemoteFileService._asStreamContent);
|
||||
|
||||
const provider = this._provider.get(resource.scheme);
|
||||
if (provider) {
|
||||
return this._doResolveContent(provider, resource).then(RemoteFileService._asStreamContent);
|
||||
}
|
||||
|
||||
return super.resolveStreamContent(resource, options);
|
||||
}
|
||||
|
||||
private async _doResolveContent(resource: URI): TPromise<IContent> {
|
||||
private _doResolveContent(provider: IRemoteFileSystemProvider, resource: URI): TPromise<IContent> {
|
||||
|
||||
const stat = RemoteFileService._createFakeStat(resource);
|
||||
const value = await this._provider.get(resource.authority).resolve(resource);
|
||||
return <any>{ ...stat, value };
|
||||
return provider.stat(resource).then(stat => {
|
||||
return provider.read(resource).then(value => {
|
||||
return <any>{
|
||||
...stat,
|
||||
value,
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// --- saving
|
||||
|
||||
updateContent(resource: URI, value: string, options?: IUpdateContentOptions): TPromise<IFileStat> {
|
||||
if (this._provider.has(resource.authority)) {
|
||||
return this._doUpdateContent(resource, value).then(RemoteFileService._createFakeStat);
|
||||
const provider = this._provider.get(resource.scheme);
|
||||
if (provider) {
|
||||
return this._doUpdateContent(provider, resource, value);
|
||||
}
|
||||
|
||||
return super.updateContent(resource, value, options);
|
||||
}
|
||||
|
||||
private async _doUpdateContent(resource: URI, content: string): TPromise<URI> {
|
||||
await this._provider.get(resource.authority).update(resource, content);
|
||||
return resource;
|
||||
}
|
||||
|
||||
// --- util
|
||||
|
||||
private static _createFakeStat(resource: URI): IFileStat {
|
||||
|
||||
return <IFileStat>{
|
||||
resource,
|
||||
name: basename(resource.path),
|
||||
encoding: 'utf8',
|
||||
mtime: Date.now(),
|
||||
etag: Date.now().toString(16),
|
||||
isDirectory: false,
|
||||
hasChildren: false
|
||||
};
|
||||
private async _doUpdateContent(provider: IRemoteFileSystemProvider, resource: URI, content: string): TPromise<IFileStat> {
|
||||
await provider.write(resource, content);
|
||||
const stat = await provider.stat(resource);
|
||||
const fileStat = await toIFileStat(provider, stat, false);
|
||||
return fileStat;
|
||||
}
|
||||
|
||||
private static _asStreamContent(content: IContent): IStreamContent {
|
||||
|
|
|
@ -12,7 +12,7 @@ import { onUnexpectedError } from 'vs/base/common/errors';
|
|||
import { guessMimeTypes } from 'vs/base/common/mime';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import * as assert from 'vs/base/common/assert';
|
||||
// import * as assert from 'vs/base/common/assert';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import paths = require('vs/base/common/paths');
|
||||
import diagnostics = require('vs/base/common/diagnostics');
|
||||
|
@ -90,7 +90,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
|
|||
) {
|
||||
super(modelService, modeService);
|
||||
|
||||
assert.ok(resource.scheme === 'file', 'TextFileEditorModel can only handle file:// resources.');
|
||||
// assert.ok(resource.scheme === 'file', 'TextFileEditorModel can only handle file:// resources.');
|
||||
|
||||
this.resource = resource;
|
||||
this.toDispose = [];
|
||||
|
|
|
@ -407,10 +407,13 @@ export abstract class TextFileService implements ITextFileService {
|
|||
const filesToSave: URI[] = [];
|
||||
const untitledToSave: URI[] = [];
|
||||
toSave.forEach(s => {
|
||||
if (s.scheme === Schemas.file) {
|
||||
filesToSave.push(s);
|
||||
} else if ((Array.isArray(arg1) || arg1 === true /* includeUntitled */) && s.scheme === UNTITLED_SCHEMA) {
|
||||
// if (s.scheme === Schemas.file) {
|
||||
// filesToSave.push(s);
|
||||
// } else
|
||||
if ((Array.isArray(arg1) || arg1 === true /* includeUntitled */) && s.scheme === UNTITLED_SCHEMA) {
|
||||
untitledToSave.push(s);
|
||||
} else {
|
||||
filesToSave.push(s);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -712,4 +715,4 @@ export abstract class TextFileService implements ITextFileService {
|
|||
// Clear all caches
|
||||
this._models.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,10 @@ class ResourceModelCollection extends ReferenceCollection<TPromise<ITextEditorMo
|
|||
if (resource.scheme === network.Schemas.file) {
|
||||
return this.textFileService.models.loadOrCreate(resource);
|
||||
}
|
||||
|
||||
const result = this.textFileService.models.get(resource);
|
||||
if (result) {
|
||||
return TPromise.as(result);
|
||||
}
|
||||
return this.resolveTextModelContent(key).then(() => this.instantiationService.createInstance(ResourceEditorModel, resource));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue