Revert "Merge from vscode ada4bddb8edc69eea6ebaaa0e88c5f903cbd43d8 (#5529)" (#5553)

This reverts commit 5d44b6a6a7.
This commit is contained in:
Anthony Dresser
2019-05-20 17:07:32 -07:00
committed by GitHub
parent 1315b8e42a
commit c9a4f8f664
325 changed files with 3332 additions and 4501 deletions

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IAction, IActionViewItem } from 'vs/base/common/actions';
import { IAction, IActionItem } from 'vs/base/common/actions';
export interface IComposite {
@@ -35,7 +35,7 @@ export interface IComposite {
/**
* Returns the action item for a specific action.
*/
getActionViewItem(action: IAction): IActionViewItem | undefined;
getActionItem(action: IAction): IActionItem | undefined;
/**
* Returns the underlying control of this composite.

View File

@@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { isMacintosh, isLinux, isWindows } from 'vs/base/common/platform';
export const IsMacContext = new RawContextKey<boolean>('isMac', isMacintosh);
export const IsLinuxContext = new RawContextKey<boolean>('isLinux', isLinux);
export const IsWindowsContext = new RawContextKey<boolean>('isWindows', isWindows);
export const RemoteAuthorityContext = new RawContextKey<string>('remoteAuthority', '');
export const HasMacNativeTabsContext = new RawContextKey<boolean>('hasMacNativeTabs', false);
export const SupportsWorkspacesContext = new RawContextKey<boolean>('supportsWorkspaces', true);
export const IsDevelopmentContext = new RawContextKey<boolean>('isDevelopment', false);
export const WorkbenchStateContext = new RawContextKey<string>('workbenchState', undefined);
export const WorkspaceFolderCountContext = new RawContextKey<number>('workspaceFolderCount', 0);
export const RemoteFileDialogContext = new RawContextKey<boolean>('remoteFileDialogVisible', false);

View File

@@ -5,7 +5,7 @@
import { Event, Emitter } from 'vs/base/common/event';
import { assign } from 'vs/base/common/objects';
import { isUndefinedOrNull } from 'vs/base/common/types';
import { isUndefinedOrNull, withUndefinedAsNull } from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { IEditor as ICodeEditor, IEditorViewState, ScrollType, IDiffEditor } from 'vs/editor/common/editorCommon';
@@ -144,7 +144,7 @@ export interface IEditorControl extends ICompositeControl { }
export interface IFileInputFactory {
createFileInput(resource: URI, encoding: string | undefined, mode: string | undefined, instantiationService: IInstantiationService): IFileEditorInput;
createFileInput(resource: URI, encoding: string | undefined, instantiationService: IInstantiationService): IFileEditorInput;
isFileInput(obj: any): obj is IFileEditorInput;
}
@@ -209,7 +209,7 @@ export interface IUntitledResourceInput extends IBaseResourceInput {
/**
* Optional language of the untitled resource.
*/
mode?: string;
language?: string;
/**
* Optional contents of the untitled resource.
@@ -516,35 +516,19 @@ export interface IEncodingSupport {
setEncoding(encoding: string, mode: EncodingMode): void;
}
export interface IModeSupport {
/**
* Sets the language mode of the input.
*/
setMode(mode: string): void;
}
/**
* This is a tagging interface to declare an editor input being capable of dealing with files. It is only used in the editor registry
* to register this kind of input to the platform.
*/
export interface IFileEditorInput extends IEditorInput, IEncodingSupport, IModeSupport {
export interface IFileEditorInput extends IEditorInput, IEncodingSupport {
/**
* Gets the resource this editor is about.
*/
getResource(): URI;
/**
* Sets the preferred encoding to use for this input.
* Sets the preferred encodingt to use for this input.
*/
setPreferredEncoding(encoding: string): void;
/**
* Sets the preferred language mode to use for this input.
*/
setPreferredMode(mode: string): void;
/**
* Forces this file input to open as binary instead of text.
*/
@@ -593,7 +577,7 @@ export class SideBySideEditorInput extends EditorInput {
return this.master.revert();
}
getTelemetryDescriptor(): { [key: string]: unknown } {
getTelemetryDescriptor(): object {
const descriptor = this.master.getTelemetryDescriptor();
return assign(descriptor, super.getTelemetryDescriptor());
@@ -647,7 +631,8 @@ export class SideBySideEditorInput extends EditorInput {
return false;
}
return this.details.matches(otherInput.details) && this.master.matches(otherInput.master);
const otherDiffInput = <SideBySideEditorInput>otherInput;
return this.details.matches(otherDiffInput.details) && this.master.matches(otherDiffInput.master);
}
return false;
@@ -1013,9 +998,9 @@ export interface IResourceOptions {
filterByScheme?: string | string[];
}
export function toResource(editor: IEditorInput | undefined, options?: IResourceOptions): URI | undefined {
export function toResource(editor: IEditorInput | null | undefined, options?: IResourceOptions): URI | null {
if (!editor) {
return undefined;
return null;
}
if (options && options.supportSideBySide && editor instanceof SideBySideEditorInput) {
@@ -1024,7 +1009,7 @@ export function toResource(editor: IEditorInput | undefined, options?: IResource
const resource = editor.getResource();
if (!resource || !options || !options.filterByScheme) {
return resource;
return withUndefinedAsNull(resource);
}
if (Array.isArray(options.filterByScheme) && options.filterByScheme.some(scheme => resource.scheme === scheme)) {
@@ -1035,7 +1020,7 @@ export function toResource(editor: IEditorInput | undefined, options?: IResource
return resource;
}
return undefined;
return null;
}
export const enum CloseDirection {

View File

@@ -68,9 +68,11 @@ export class DataUriEditorInput extends EditorInput {
return true;
}
// Compare by resource
if (otherInput instanceof DataUriEditorInput) {
return otherInput.resource.toString() === this.resource.toString();
const otherDataUriEditorInput = <DataUriEditorInput>otherInput;
// Compare by resource
return otherDataUriEditorInput.resource.toString() === this.resource.toString();
}
return false;

View File

@@ -67,7 +67,7 @@ export class DiffEditorInput extends SideBySideEditorInput {
// If both are text models, return textdiffeditor model
if (modifiedEditorModel instanceof BaseTextEditorModel && originalEditorModel instanceof BaseTextEditorModel) {
return new TextDiffEditorModel(originalEditorModel, modifiedEditorModel);
return new TextDiffEditorModel(<BaseTextEditorModel>originalEditorModel, <BaseTextEditorModel>modifiedEditorModel);
}
// Otherwise return normal diff model

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { EditorInput, ITextEditorModel, IModeSupport } from 'vs/workbench/common/editor';
import { EditorInput, ITextEditorModel } from 'vs/workbench/common/editor';
import { URI } from 'vs/base/common/uri';
import { IReference } from 'vs/base/common/lifecycle';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
@@ -13,18 +13,16 @@ import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorMo
* A read-only text editor input whos contents are made of the provided resource that points to an existing
* code editor model.
*/
export class ResourceEditorInput extends EditorInput implements IModeSupport {
export class ResourceEditorInput extends EditorInput {
static readonly ID: string = 'workbench.editors.resourceEditorInput';
private cachedModel: ResourceEditorModel | null;
private modelReference: Promise<IReference<ITextEditorModel>> | null;
constructor(
private name: string,
private description: string | null,
private readonly resource: URI,
private preferredMode: string | undefined,
@ITextModelService private readonly textModelResolverService: ITextModelService
) {
super();
@@ -64,18 +62,6 @@ export class ResourceEditorInput extends EditorInput implements IModeSupport {
}
}
setMode(mode: string): void {
this.setPreferredMode(mode);
if (this.cachedModel) {
this.cachedModel.setMode(mode);
}
}
setPreferredMode(mode: string): void {
this.preferredMode = mode;
}
resolve(): Promise<ITextEditorModel> {
if (!this.modelReference) {
this.modelReference = this.textModelResolverService.createModelReference(this.resource);
@@ -84,7 +70,6 @@ export class ResourceEditorInput extends EditorInput implements IModeSupport {
return this.modelReference.then(ref => {
const model = ref.object;
// Ensure the resolved model is of expected type
if (!(model instanceof ResourceEditorModel)) {
ref.dispose();
this.modelReference = null;
@@ -92,13 +77,6 @@ export class ResourceEditorInput extends EditorInput implements IModeSupport {
return Promise.reject(new Error(`Unexpected model for ResourceInput: ${this.resource}`));
}
this.cachedModel = model;
// Set mode if we have a preferred mode configured
if (this.preferredMode) {
model.setMode(this.preferredMode);
}
return model;
});
}
@@ -108,9 +86,11 @@ export class ResourceEditorInput extends EditorInput implements IModeSupport {
return true;
}
// Compare by properties
if (otherInput instanceof ResourceEditorInput) {
return otherInput.resource.toString() === this.resource.toString();
let otherResourceEditorInput = <ResourceEditorInput>otherInput;
// Compare by properties
return otherResourceEditorInput.resource.toString() === this.resource.toString();
}
return false;
@@ -122,8 +102,6 @@ export class ResourceEditorInput extends EditorInput implements IModeSupport {
this.modelReference = null;
}
this.cachedModel = null;
super.dispose();
}
}

View File

@@ -19,18 +19,12 @@ export class ResourceEditorModel extends BaseTextEditorModel {
@IModelService modelService: IModelService
) {
super(modelService, modeService, resource);
// TODO@Joao: force this class to dispose the underlying model
this.createdEditorModel = true;
}
isReadonly(): boolean {
return true;
}
dispose(): void {
// TODO@Joao: force this class to dispose the underlying model
if (this.textEditorModelHandle) {
this.modelService.destroyModel(this.textEditorModelHandle);
}
super.dispose();
}
}

View File

@@ -4,21 +4,21 @@
*--------------------------------------------------------------------------------------------*/
import { ITextModel, ITextBufferFactory, ITextSnapshot } from 'vs/editor/common/model';
import { EditorModel, IModeSupport } from 'vs/workbench/common/editor';
import { EditorModel } from 'vs/workbench/common/editor';
import { URI } from 'vs/base/common/uri';
import { ITextEditorModel, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService';
import { IModeService, ILanguageSelection } from 'vs/editor/common/services/modeService';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IDisposable } from 'vs/base/common/lifecycle';
import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry';
/**
* The base text editor model leverages the code editor model. This class is only intended to be subclassed and not instantiated.
*/
export abstract class BaseTextEditorModel extends EditorModel implements ITextEditorModel, IModeSupport {
protected textEditorModelHandle: URI | null;
private createdEditorModel: boolean;
export abstract class BaseTextEditorModel extends EditorModel implements ITextEditorModel {
protected createdEditorModel: boolean;
private textEditorModelHandle: URI | null;
private modelDisposeListener: IDisposable | null;
constructor(
@@ -64,25 +64,12 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd
abstract isReadonly(): boolean;
setMode(mode: string): void {
if (!this.isResolved()) {
return;
}
if (!mode || mode === this.textEditorModel.getModeId()) {
return;
}
this.modelService.setMode(this.textEditorModel, this.modeService.create(mode));
}
/**
* Creates the text editor model with the provided value, optional preferred mode
* (can be comma separated for multiple values) and optional resource URL.
* Creates the text editor model with the provided value, modeId (can be comma separated for multiple values) and optional resource URL.
*/
protected createTextEditorModel(value: ITextBufferFactory, resource: URI | undefined, preferredMode?: string): EditorModel {
protected createTextEditorModel(value: ITextBufferFactory, resource: URI | undefined, modeId?: string): EditorModel {
const firstLineText = this.getFirstLineText(value);
const languageSelection = this.getOrCreateMode(resource, this.modeService, preferredMode, firstLineText);
const languageSelection = this.getOrCreateMode(this.modeService, modeId, firstLineText);
return this.doCreateTextEditorModel(value, languageSelection, resource);
}
@@ -96,7 +83,8 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd
// Make sure we clean up when this model gets disposed
this.registerModelDisposeListener(model);
} else {
this.updateTextEditorModel(value, languageSelection.languageIdentifier.language);
this.modelService.updateModel(model, value);
this.modelService.setMode(model, languageSelection);
}
this.textEditorModelHandle = model.uri;
@@ -122,42 +110,28 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd
*
* @param firstLineText optional first line of the text buffer to set the mode on. This can be used to guess a mode from content.
*/
protected getOrCreateMode(resource: URI | undefined, modeService: IModeService, preferredMode: string | undefined, firstLineText?: string): ILanguageSelection {
// lookup mode via resource path if the provided mode is unspecific
if (!preferredMode || preferredMode === PLAINTEXT_MODE_ID) {
return modeService.createByFilepathOrFirstLine(resource ? resource.path : null, firstLineText);
}
// otherwise take the preferred mode for granted
return modeService.create(preferredMode);
protected getOrCreateMode(modeService: IModeService, modeId: string | undefined, firstLineText?: string): ILanguageSelection {
return modeService.create(modeId);
}
/**
* Updates the text editor model with the provided value. If the value is the same as the model has, this is a no-op.
*/
protected updateTextEditorModel(newValue: ITextBufferFactory, preferredMode?: string): void {
if (!this.isResolved()) {
protected updateTextEditorModel(newValue: ITextBufferFactory): void {
if (!this.textEditorModel) {
return;
}
// contents
this.modelService.updateModel(this.textEditorModel, newValue);
// mode (only if specific and changed)
if (preferredMode && preferredMode !== PLAINTEXT_MODE_ID && this.textEditorModel.getModeId() !== preferredMode) {
this.modelService.setMode(this.textEditorModel, this.modeService.create(preferredMode));
}
}
createSnapshot(this: IResolvedTextEditorModel): ITextSnapshot;
createSnapshot(this: ITextEditorModel): ITextSnapshot | null;
createSnapshot(): ITextSnapshot | null {
if (!this.textEditorModel) {
return null;
const model = this.textEditorModel;
if (model) {
return model.createSnapshot(true /* Preserve BOM */);
}
return this.textEditorModel.createSnapshot(true /* preserve BOM */);
return null;
}
isResolved(): this is IResolvedTextEditorModel {

View File

@@ -9,7 +9,7 @@ import { memoize } from 'vs/base/common/decorators';
import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry';
import { basename } from 'vs/base/common/path';
import { basenameOrAuthority, dirname } from 'vs/base/common/resources';
import { EditorInput, IEncodingSupport, EncodingMode, ConfirmResult, Verbosity, IModeSupport } from 'vs/workbench/common/editor';
import { EditorInput, IEncodingSupport, EncodingMode, ConfirmResult, Verbosity } from 'vs/workbench/common/editor';
import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { Event, Emitter } from 'vs/base/common/event';
@@ -20,12 +20,12 @@ import { IResolvedTextEditorModel } from 'vs/editor/common/services/resolverServ
/**
* An editor input to be used for untitled text buffers.
*/
export class UntitledEditorInput extends EditorInput implements IEncodingSupport, IModeSupport {
export class UntitledEditorInput extends EditorInput implements IEncodingSupport {
static readonly ID: string = 'workbench.editors.untitledEditorInput';
private cachedModel: UntitledEditorModel | null;
private modelResolve: Promise<UntitledEditorModel & IResolvedTextEditorModel> | null;
private cachedModel: UntitledEditorModel;
private modelResolve?: Promise<UntitledEditorModel & IResolvedTextEditorModel>;
private readonly _onDidModelChangeContent: Emitter<void> = this._register(new Emitter<void>());
get onDidModelChangeContent(): Event<void> { return this._onDidModelChangeContent.event; }
@@ -36,7 +36,7 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
constructor(
private readonly resource: URI,
private readonly _hasAssociatedFilePath: boolean,
private preferredMode: string,
private readonly modeId: string,
private readonly initialValue: string,
private preferredEncoding: string,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@@ -58,6 +58,14 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
return this.resource;
}
getModeId(): string | null {
if (this.cachedModel) {
return this.cachedModel.getModeId();
}
return this.modeId;
}
getName(): string {
return this.hasAssociatedFilePath ? basenameOrAuthority(this.resource) : this.resource.path;
}
@@ -165,9 +173,9 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
suggestFileName(): string {
if (!this.hasAssociatedFilePath) {
if (this.cachedModel) {
const mode = this.cachedModel.getMode();
if (mode !== PLAINTEXT_MODE_ID) { // do not suggest when the mode ID is simple plain text
return suggestFilename(mode, this.getName());
const modeId = this.cachedModel.getModeId();
if (modeId !== PLAINTEXT_MODE_ID) { // do not suggest when the mode ID is simple plain text
return suggestFilename(modeId, this.getName());
}
}
}
@@ -191,22 +199,6 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
}
}
setMode(mode: string): void {
this.preferredMode = mode;
if (this.cachedModel) {
this.cachedModel.setMode(mode);
}
}
getMode(): string | undefined {
if (this.cachedModel) {
return this.cachedModel.getMode();
}
return this.preferredMode;
}
resolve(): Promise<UntitledEditorModel & IResolvedTextEditorModel> {
// Join a model resolve if we have had one before
@@ -222,7 +214,7 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
}
private createModel(): UntitledEditorModel {
const model = this._register(this.instantiationService.createInstance(UntitledEditorModel, this.preferredMode, this.resource, this.hasAssociatedFilePath, this.initialValue, this.preferredEncoding));
const model = this._register(this.instantiationService.createInstance(UntitledEditorModel, this.modeId, this.resource, this.hasAssociatedFilePath, this.initialValue, this.preferredEncoding));
// re-emit some events from the model
this._register(model.onDidChangeContent(() => this._onDidModelChangeContent.fire()));
@@ -237,17 +229,18 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
return true;
}
// Otherwise compare by properties
if (otherInput instanceof UntitledEditorInput) {
return otherInput.resource.toString() === this.resource.toString();
const otherUntitledEditorInput = <UntitledEditorInput>otherInput;
// Otherwise compare by properties
return otherUntitledEditorInput.resource.toString() === this.resource.toString();
}
return false;
}
dispose(): void {
this.cachedModel = null;
this.modelResolve = null;
this.modelResolve = undefined;
super.dispose();
}

View File

@@ -6,8 +6,9 @@
import { IEncodingSupport } from 'vs/workbench/common/editor';
import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel';
import { URI } from 'vs/base/common/uri';
import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry';
import { CONTENT_CHANGE_EVENT_BUFFER_DELAY } from 'vs/platform/files/common/files';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IModeService, ILanguageSelection } from 'vs/editor/common/services/modeService';
import { IModelService } from 'vs/editor/common/services/modelService';
import { Event, Emitter } from 'vs/base/common/event';
import { RunOnceScheduler } from 'vs/base/common/async';
@@ -36,7 +37,7 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
private configuredEncoding: string;
constructor(
private readonly preferredMode: string,
private readonly modeId: string,
private readonly resource: URI,
private _hasAssociatedFilePath: boolean,
private readonly initialValue: string,
@@ -57,6 +58,14 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
return this._hasAssociatedFilePath;
}
protected getOrCreateMode(modeService: IModeService, modeId: string, firstLineText?: string): ILanguageSelection {
if (!modeId || modeId === PLAINTEXT_MODE_ID) {
return modeService.createByFilepathOrFirstLine(this.resource.fsPath, firstLineText); // lookup mode via resource path if the provided modeId is unspecific
}
return super.getOrCreateMode(modeService, modeId, firstLineText);
}
private registerListeners(): void {
// Config Changes
@@ -79,12 +88,12 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
return this.versionId;
}
getMode(): string | undefined {
getModeId(): string | null {
if (this.textEditorModel) {
return this.textEditorModel.getModeId();
return this.textEditorModel.getLanguageIdentifier().language;
}
return this.preferredMode;
return this.modeId;
}
getEncoding(): string {
@@ -127,44 +136,36 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin
this.contentChangeEventScheduler.schedule();
}
backup(): Promise<void> {
if (this.isResolved()) {
return this.backupFileService.backupResource(this.resource, this.createSnapshot(), this.versionId);
}
return Promise.resolve();
}
load(): Promise<UntitledEditorModel & IResolvedTextEditorModel> {
// Check for backups first
return this.backupFileService.loadBackupResource(this.resource).then(backupResource => {
return this.backupFileService.loadBackupResource(this.resource).then((backupResource) => {
if (backupResource) {
return this.backupFileService.resolveBackupContent(backupResource);
}
return Promise.resolve(undefined);
}).then(backup => {
const hasBackup = !!backup;
return undefined;
}).then(backupTextBufferFactory => {
const hasBackup = !!backupTextBufferFactory;
// untitled associated to file path are dirty right away as well as untitled with content
this.setDirty(this._hasAssociatedFilePath || hasBackup || !!this.initialValue);
this.setDirty(this._hasAssociatedFilePath || hasBackup);
let untitledContents: ITextBufferFactory;
if (backup) {
untitledContents = backup.value;
if (backupTextBufferFactory) {
untitledContents = backupTextBufferFactory;
} else {
untitledContents = createTextBufferFactory(this.initialValue || '');
}
// Create text editor model if not yet done
if (!this.textEditorModel) {
this.createTextEditorModel(untitledContents, this.resource, this.preferredMode);
this.createTextEditorModel(untitledContents, this.resource, this.modeId);
}
// Otherwise update
else {
this.updateTextEditorModel(untitledContents, this.preferredMode);
this.updateTextEditorModel(untitledContents);
}
// Encoding