mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-24 18:49:00 +01:00
Implements #16394
This commit is contained in:
@@ -5,10 +5,11 @@
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import Event, { Emitter, once } from 'vs/base/common/event';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import types = require('vs/base/common/types');
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IEditor, ICommonCodeEditor, IEditorViewState, IEditorOptions as ICodeEditorOptions, IModel } from 'vs/editor/common/editorCommon';
|
||||
import { IEditorInput, IEditorModel, IEditorOptions, ITextEditorOptions, IResourceInput, Position } from 'vs/platform/editor/common/editor';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
@@ -358,47 +359,114 @@ export abstract class UntitledEditorInput extends EditorInput implements IEncodi
|
||||
}
|
||||
|
||||
/**
|
||||
* The base class of editor inputs that have an original and modified side.
|
||||
* Side by side editor inputs that have a master and details side.
|
||||
*/
|
||||
export abstract class BaseDiffEditorInput extends EditorInput {
|
||||
private _originalInput: EditorInput;
|
||||
private _modifiedInput: EditorInput;
|
||||
export class SideBySideEditorInput extends EditorInput {
|
||||
|
||||
constructor(originalInput: EditorInput, modifiedInput: EditorInput) {
|
||||
private _toUnbind: IDisposable[];
|
||||
|
||||
constructor(private name: string, private description: string, private _details: EditorInput, private _master: EditorInput, protected forceOpenAsBinary?: boolean) {
|
||||
super();
|
||||
|
||||
this._originalInput = originalInput;
|
||||
this._modifiedInput = modifiedInput;
|
||||
this._toUnbind = [];
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
public get originalInput(): EditorInput {
|
||||
return this._originalInput;
|
||||
get master(): EditorInput {
|
||||
return this._master;
|
||||
}
|
||||
|
||||
public get modifiedInput(): EditorInput {
|
||||
return this._modifiedInput;
|
||||
get details(): EditorInput {
|
||||
return this._details;
|
||||
}
|
||||
|
||||
public isDirty(): boolean {
|
||||
return this._modifiedInput.isDirty();
|
||||
return this.master.isDirty();
|
||||
}
|
||||
|
||||
public confirmSave(): ConfirmResult {
|
||||
return this._modifiedInput.confirmSave();
|
||||
return this.master.confirmSave();
|
||||
}
|
||||
|
||||
public save(): TPromise<boolean> {
|
||||
return this._modifiedInput.save();
|
||||
return this.master.save();
|
||||
}
|
||||
|
||||
public revert(): TPromise<boolean> {
|
||||
return this._modifiedInput.revert();
|
||||
return this.master.revert();
|
||||
}
|
||||
|
||||
public getTelemetryDescriptor(): { [key: string]: any; } {
|
||||
const descriptor = this._modifiedInput.getTelemetryDescriptor();
|
||||
const descriptor = this.master.getTelemetryDescriptor();
|
||||
return objects.assign(descriptor, super.getTelemetryDescriptor());
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
|
||||
// When the details or master input gets disposed, dispose this diff editor input
|
||||
const onceDetailsDisposed = once(this.details.onDispose);
|
||||
this._toUnbind.push(onceDetailsDisposed(() => {
|
||||
if (!this.isDisposed()) {
|
||||
this.dispose();
|
||||
}
|
||||
}));
|
||||
|
||||
const onceMasterDisposed = once(this.master.onDispose);
|
||||
this._toUnbind.push(onceMasterDisposed(() => {
|
||||
if (!this.isDisposed()) {
|
||||
this.dispose();
|
||||
}
|
||||
}));
|
||||
|
||||
// Reemit some events from the master side to the outside
|
||||
this._toUnbind.push(this.master.onDidChangeDirty(() => this._onDidChangeDirty.fire()));
|
||||
this._toUnbind.push(this.master.onDidChangeLabel(() => this._onDidChangeLabel.fire()));
|
||||
}
|
||||
|
||||
public get toUnbind() {
|
||||
return this._toUnbind;
|
||||
}
|
||||
|
||||
public resolve(refresh?: boolean): TPromise<EditorModel> {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
getTypeId(): string {
|
||||
return 'workbench.editorinputs.sidebysideEditorInput';
|
||||
}
|
||||
|
||||
public getName(): string {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public getDescription(): string {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public supportsSplitEditor(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
public matches(otherInput: any): boolean {
|
||||
if (super.matches(otherInput) === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (otherInput) {
|
||||
if (!(otherInput instanceof SideBySideEditorInput)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const otherDiffInput = <SideBySideEditorInput>otherInput;
|
||||
return this.details.matches(otherDiffInput.details) && this.master.matches(otherDiffInput.master);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._toUnbind = dispose(this._toUnbind);
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export interface ITextEditorModel extends IEditorModel {
|
||||
@@ -785,14 +853,14 @@ export function getOutOfWorkspaceEditorResources(editorGroupService: IEditorGrou
|
||||
/**
|
||||
* Returns the object as IFileEditorInput only if it matches the signature.
|
||||
*/
|
||||
export function asFileEditorInput(obj: any, supportDiff?: boolean): IFileEditorInput {
|
||||
export function asFileEditorInput(obj: any, supportSideBySide?: boolean): IFileEditorInput {
|
||||
if (!obj) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check for diff if we are asked to
|
||||
if (supportDiff && obj instanceof BaseDiffEditorInput) {
|
||||
obj = (<BaseDiffEditorInput>obj).modifiedInput;
|
||||
// Check for side by side if we are asked to
|
||||
if (supportSideBySide && obj instanceof SideBySideEditorInput) {
|
||||
obj = (<SideBySideEditorInput>obj).master;
|
||||
}
|
||||
|
||||
const i = <IFileEditorInput>obj;
|
||||
|
||||
@@ -6,77 +6,33 @@
|
||||
|
||||
import nls = require('vs/nls');
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { once } from 'vs/base/common/event';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { getPathLabel, IWorkspaceProvider } from 'vs/base/common/labels';
|
||||
import { EditorModel, EditorInput, BaseDiffEditorInput, TEXT_DIFF_EDITOR_ID, BINARY_DIFF_EDITOR_ID } from 'vs/workbench/common/editor';
|
||||
import { EditorModel, EditorInput, SideBySideEditorInput, TEXT_DIFF_EDITOR_ID, BINARY_DIFF_EDITOR_ID } from 'vs/workbench/common/editor';
|
||||
import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel';
|
||||
import { DiffEditorModel } from 'vs/workbench/common/editor/diffEditorModel';
|
||||
import { TextDiffEditorModel } from 'vs/workbench/common/editor/textDiffEditorModel';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
|
||||
/**
|
||||
* The base editor input for the diff editor. It is made up of two editor inputs, the original version
|
||||
* and the modified version.
|
||||
*/
|
||||
export class DiffEditorInput extends BaseDiffEditorInput {
|
||||
export class DiffEditorInput extends SideBySideEditorInput {
|
||||
|
||||
public static ID = 'workbench.editors.diffEditorInput';
|
||||
|
||||
private _toUnbind: IDisposable[];
|
||||
private name: string;
|
||||
private description: string;
|
||||
private cachedModel: DiffEditorModel;
|
||||
private forceOpenAsBinary: boolean;
|
||||
|
||||
constructor(name: string, description: string, originalInput: EditorInput, modifiedInput: EditorInput, forceOpenAsBinary?: boolean) {
|
||||
super(originalInput, modifiedInput);
|
||||
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.forceOpenAsBinary = forceOpenAsBinary;
|
||||
|
||||
this._toUnbind = [];
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
|
||||
// When the original or modified input gets disposed, dispose this diff editor input
|
||||
const onceOriginalDisposed = once(this.originalInput.onDispose);
|
||||
this._toUnbind.push(onceOriginalDisposed(() => {
|
||||
if (!this.isDisposed()) {
|
||||
this.dispose();
|
||||
}
|
||||
}));
|
||||
|
||||
const onceModifiedDisposed = once(this.modifiedInput.onDispose);
|
||||
this._toUnbind.push(onceModifiedDisposed(() => {
|
||||
if (!this.isDisposed()) {
|
||||
this.dispose();
|
||||
}
|
||||
}));
|
||||
|
||||
// Reemit some events from the modified side to the outside
|
||||
this._toUnbind.push(this.modifiedInput.onDidChangeDirty(() => this._onDidChangeDirty.fire()));
|
||||
this._toUnbind.push(this.modifiedInput.onDidChangeLabel(() => this._onDidChangeLabel.fire()));
|
||||
}
|
||||
|
||||
public get toUnbind() {
|
||||
return this._toUnbind;
|
||||
}
|
||||
|
||||
public getTypeId(): string {
|
||||
return DiffEditorInput.ID;
|
||||
}
|
||||
|
||||
public getName(): string {
|
||||
return this.name;
|
||||
get originalInput(): EditorInput {
|
||||
return this.details;
|
||||
}
|
||||
|
||||
public getDescription(): string {
|
||||
return this.description;
|
||||
get modifiedInput(): EditorInput {
|
||||
return this.master;
|
||||
}
|
||||
|
||||
public resolve(refresh?: boolean): TPromise<EditorModel> {
|
||||
@@ -130,30 +86,7 @@ export class DiffEditorInput extends BaseDiffEditorInput {
|
||||
});
|
||||
}
|
||||
|
||||
public supportsSplitEditor(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
public matches(otherInput: any): boolean {
|
||||
if (super.matches(otherInput) === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (otherInput) {
|
||||
if (!(otherInput instanceof DiffEditorInput)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const otherDiffInput = <DiffEditorInput>otherInput;
|
||||
return this.originalInput.matches(otherDiffInput.originalInput) && this.modifiedInput.matches(otherDiffInput.modifiedInput);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._toUnbind = dispose(this._toUnbind);
|
||||
|
||||
// Free the diff editor model but do not propagate the dispose() call to the two inputs
|
||||
// We never created the two inputs (original and modified) so we can not dispose
|
||||
// them without sideeffects.
|
||||
@@ -161,8 +94,6 @@ export class DiffEditorInput extends BaseDiffEditorInput {
|
||||
this.cachedModel.dispose();
|
||||
this.cachedModel = null;
|
||||
}
|
||||
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
'use strict';
|
||||
|
||||
import Event, { Emitter, once } from 'vs/base/common/event';
|
||||
import { IEditorRegistry, Extensions, EditorInput, getResource, IEditorStacksModel, IEditorGroup, IEditorIdentifier, IGroupEvent, GroupIdentifier, IStacksModelChangeEvent, IWorkbenchEditorConfiguration, EditorOpenPositioning } from 'vs/workbench/common/editor';
|
||||
import { IEditorRegistry, Extensions, EditorInput, getResource, IEditorStacksModel, IEditorGroup, IEditorIdentifier, IGroupEvent, GroupIdentifier, IStacksModelChangeEvent, IWorkbenchEditorConfiguration, EditorOpenPositioning, SideBySideEditorInput } from 'vs/workbench/common/editor';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -16,7 +16,6 @@ import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Registry } from 'vs/platform/platform';
|
||||
import { Position, Direction } from 'vs/platform/editor/common/editor';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
|
||||
export interface GroupEvent extends IGroupEvent {
|
||||
editor: EditorInput;
|
||||
@@ -1135,9 +1134,9 @@ export class EditorStacksModel implements IEditorStacksModel {
|
||||
if (!this.isOpen(editor)) {
|
||||
editor.close();
|
||||
|
||||
// Also take care of diff editor inputs that wrap around 2 editors
|
||||
if (editor instanceof DiffEditorInput) {
|
||||
[editor.originalInput, editor.modifiedInput].forEach(editor => {
|
||||
// Also take care of side by side editor inputs that wrap around 2 editors
|
||||
if (editor instanceof SideBySideEditorInput) {
|
||||
[editor.master, editor.details].forEach(editor => {
|
||||
if (!this.isOpen(editor)) {
|
||||
editor.close();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user