Merge from vscode 4d91d96e5e121b38d33508cdef17868bab255eae

This commit is contained in:
ADS Merger
2020-06-18 04:32:54 +00:00
committed by AzureDataStudio
parent a971aee5bd
commit 5e7071e466
1002 changed files with 24201 additions and 13193 deletions

View File

@@ -22,6 +22,7 @@ import { IPathData } from 'vs/platform/windows/common/windows';
import { coalesce, firstOrDefault } from 'vs/base/common/arrays';
import { IResourceEditorInputType } from 'vs/workbench/services/editor/common/editorService';
import { IRange } from 'vs/editor/common/core/range';
import { IExtUri } from 'vs/base/common/resources';
export const DirtyWorkingCopiesContext = new RawContextKey<boolean>('dirtyWorkingCopies', false);
export const ActiveEditorContext = new RawContextKey<string | null>('activeEditor', null);
@@ -163,13 +164,20 @@ export interface IEditorControl extends ICompositeControl { }
export interface IFileEditorInputFactory {
createFileEditorInput(resource: URI, encoding: string | undefined, mode: string | undefined, instantiationService: IInstantiationService): IFileEditorInput;
/**
* Creates new new editor input capable of showing files.
*/
createFileEditorInput(resource: URI, label: URI | undefined, encoding: string | undefined, mode: string | undefined, instantiationService: IInstantiationService): IFileEditorInput;
/**
* Check if the provided object is a file editor input.
*/
isFileEditorInput(obj: unknown): obj is IFileEditorInput;
}
interface ICustomEditorInputFactory {
createCustomEditorInput(resource: URI, instantiationService: IInstantiationService): Promise<IEditorInput>;
canResolveBackup(editorInput: IEditorInput, backupResource: URI): boolean;
}
export interface IEditorInputFactoryRegistry {
@@ -187,12 +195,12 @@ export interface IEditorInputFactoryRegistry {
/**
* Registers the custom editor input factory to use for custom inputs.
*/
registerCustomEditorInputFactory(factory: ICustomEditorInputFactory): void;
registerCustomEditorInputFactory(scheme: string, factory: ICustomEditorInputFactory): void;
/**
* Returns the custom editor input factory to use for custom inputs.
*/
getCustomEditorInputFactory(): ICustomEditorInputFactory;
getCustomEditorInputFactory(scheme: string): ICustomEditorInputFactory | undefined;
/**
* Registers a editor input factory for the given editor input to the registry. An editor input factory
@@ -227,7 +235,7 @@ export interface IEditorInputFactory {
* Returns a string representation of the provided editor input that contains enough information
* to deserialize back to the original editor input from the deserialize() method.
*/
serialize(editorInput: EditorInput): string | undefined;
serialize(editorInput: IEditorInput): string | undefined;
/**
* Returns an editor input from the provided serialized form of the editor input. This form matches
@@ -403,7 +411,9 @@ export interface IEditorInput extends IDisposable {
getAriaLabel(): string;
/**
* Resolves the input.
* Returns a type of `IEditorModel` that represents the resolved input.
* Subclasses should override to provide a meaningful model or return
* `null` if the editor does not require a model.
*/
resolve(): Promise<IEditorModel | null>;
@@ -458,14 +468,19 @@ export interface IEditorInput extends IDisposable {
revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void>;
/**
* Called to determine how to handle a resource that is moved that matches
* Called to determine how to handle a resource that is renamed that matches
* the editors resource (or is a child of).
*
* Implementors are free to not implement this method to signal no intent
* to participate. If an editor is returned though, it will replace the
* current one with that editor and optional options.
*/
move(group: GroupIdentifier, target: URI): IMoveResult | undefined;
rename(group: GroupIdentifier, target: URI): IMoveResult | undefined;
/**
* Subclasses can set this to false if it does not make sense to split the editor input.
*/
supportsSplitEditor(): boolean;
/**
* Returns if the other object matches this input.
@@ -537,12 +552,6 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
return { typeId: this.getTypeId() };
}
/**
* Returns a type of EditorModel that represents the resolved input. Subclasses should
* override to provide a meaningful model.
*/
abstract resolve(): Promise<IEditorModel | null>;
isReadonly(): boolean {
return true;
}
@@ -559,6 +568,10 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
return false;
}
async resolve(): Promise<IEditorModel | null> {
return null;
}
async save(group: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
return this;
}
@@ -569,13 +582,10 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
async revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void> { }
move(group: GroupIdentifier, target: URI): IMoveResult | undefined {
rename(group: GroupIdentifier, target: URI): IMoveResult | undefined {
return undefined;
}
/**
* Subclasses can set this to false if it does not make sense to split the editor input.
*/
supportsSplitEditor(): boolean {
return true;
}
@@ -644,12 +654,17 @@ export interface IFileEditorInput extends IEditorInput, IEncodingSupport, IModeS
readonly resource: URI;
/**
* Sets the preferred encoding to use for this input.
* Sets the preferred label to use for this file input.
*/
setLabel(label: URI): void;
/**
* Sets the preferred encoding to use for this file input.
*/
setPreferredEncoding(encoding: string): void;
/**
* Sets the preferred language mode to use for this input.
* Sets the preferred language mode to use for this file input.
*/
setPreferredMode(mode: string): void;
@@ -659,7 +674,7 @@ export interface IFileEditorInput extends IEditorInput, IEncodingSupport, IModeS
setForceOpenAsBinary(): void;
/**
* Figure out if the input has been resolved or not.
* Figure out if the file input has been resolved or not.
*/
isResolved(): boolean;
}
@@ -682,6 +697,28 @@ export class SideBySideEditorInput extends EditorInput {
this.registerListeners();
}
private registerListeners(): void {
// When the details or master input gets disposed, dispose this diff editor input
const onceDetailsDisposed = Event.once(this.details.onDispose);
this._register(onceDetailsDisposed(() => {
if (!this.isDisposed()) {
this.dispose();
}
}));
const onceMasterDisposed = Event.once(this.master.onDispose);
this._register(onceMasterDisposed(() => {
if (!this.isDisposed()) {
this.dispose();
}
}));
// Reemit some events from the master side to the outside
this._register(this.master.onDidChangeDirty(() => this._onDidChangeDirty.fire()));
this._register(this.master.onDidChangeLabel(() => this._onDidChangeLabel.fire()));
}
get resource(): URI | undefined {
return undefined;
}
@@ -744,32 +781,6 @@ export class SideBySideEditorInput extends EditorInput {
return Object.assign(descriptor, super.getTelemetryDescriptor());
}
private registerListeners(): void {
// When the details or master input gets disposed, dispose this diff editor input
const onceDetailsDisposed = Event.once(this.details.onDispose);
this._register(onceDetailsDisposed(() => {
if (!this.isDisposed()) {
this.dispose();
}
}));
const onceMasterDisposed = Event.once(this.master.onDispose);
this._register(onceMasterDisposed(() => {
if (!this.isDisposed()) {
this.dispose();
}
}));
// Reemit some events from the master side to the outside
this._register(this.master.onDidChangeDirty(() => this._onDidChangeDirty.fire()));
this._register(this.master.onDidChangeLabel(() => this._onDidChangeLabel.fire()));
}
async resolve(): Promise<EditorModel | null> {
return null;
}
matches(otherInput: unknown): boolean {
if (super.matches(otherInput) === true) {
return true;
@@ -919,9 +930,12 @@ export class EditorOptions implements IEditorOptions {
ignoreError: boolean | undefined;
/**
* Does not use editor overrides while opening the editor.
* Allows to override the editor that should be used to display the input:
* - `undefined`: let the editor decide for itself
* - `false`: disable overrides
* - `string`: specific override by id
*/
ignoreOverrides: boolean | undefined;
override?: false | string;
/**
* A optional hint to signal in which context the editor opens.
@@ -979,8 +993,8 @@ export class EditorOptions implements IEditorOptions {
this.index = options.index;
}
if (typeof options.ignoreOverrides === 'boolean') {
this.ignoreOverrides = options.ignoreOverrides;
if (typeof options.override === 'string' || options.override === false) {
this.override = options.override;
}
if (typeof options.context === 'number') {
@@ -1012,7 +1026,7 @@ export class TextEditorOptions extends EditorOptions implements ITextEditorOptio
selectionRevealType: TextEditorSelectionRevealType | undefined;
static from(input?: IBaseResourceEditorInput): TextEditorOptions | undefined {
if (!input || !input.options) {
if (!input?.options) {
return undefined;
}
@@ -1187,7 +1201,7 @@ interface IEditorPartConfiguration {
}
export interface IEditorPartOptions extends IEditorPartConfiguration {
iconTheme?: string;
hasIcons?: boolean;
}
export interface IEditorPartOptionsChangeEvent {
@@ -1206,10 +1220,10 @@ export interface IResourceOptions {
filterByScheme?: string | string[];
}
export function toResource(editor: IEditorInput | undefined): URI | undefined;
export function toResource(editor: IEditorInput | undefined, options: IResourceOptions & { supportSideBySide?: SideBySideEditor.MASTER | SideBySideEditor.DETAILS }): URI | undefined;
export function toResource(editor: IEditorInput | undefined, options: IResourceOptions & { supportSideBySide: SideBySideEditor.BOTH }): URI | { master?: URI, detail?: URI } | undefined;
export function toResource(editor: IEditorInput | undefined, options?: IResourceOptions): URI | { master?: URI, detail?: URI } | undefined {
export function toResource(editor: IEditorInput | undefined | null): URI | undefined;
export function toResource(editor: IEditorInput | undefined | null, options: IResourceOptions & { supportSideBySide?: SideBySideEditor.MASTER | SideBySideEditor.DETAILS }): URI | undefined;
export function toResource(editor: IEditorInput | undefined | null, options: IResourceOptions & { supportSideBySide: SideBySideEditor.BOTH }): URI | { master?: URI, detail?: URI } | undefined;
export function toResource(editor: IEditorInput | undefined | null, options?: IResourceOptions): URI | { master?: URI, detail?: URI } | undefined {
if (!editor) {
return undefined;
}
@@ -1259,13 +1273,13 @@ export interface IEditorMemento<T> {
clearEditorState(resource: URI, group?: IEditorGroup): void;
clearEditorState(editor: EditorInput, group?: IEditorGroup): void;
moveEditorState(source: URI, target: URI): void;
moveEditorState(source: URI, target: URI, comparer: IExtUri): void;
}
class EditorInputFactoryRegistry implements IEditorInputFactoryRegistry {
private instantiationService: IInstantiationService | undefined;
private fileEditorInputFactory: IFileEditorInputFactory | undefined;
private customEditorInputFactory: ICustomEditorInputFactory | undefined;
private customEditorInputFactoryInstances: Map<string, ICustomEditorInputFactory> = new Map();
private readonly editorInputFactoryConstructors: Map<string, IConstructorSignature0<IEditorInputFactory>> = new Map();
private readonly editorInputFactoryInstances: Map<string, IEditorInputFactory> = new Map();
@@ -1293,12 +1307,12 @@ class EditorInputFactoryRegistry implements IEditorInputFactoryRegistry {
return assertIsDefined(this.fileEditorInputFactory);
}
registerCustomEditorInputFactory(factory: ICustomEditorInputFactory): void {
this.customEditorInputFactory = factory;
registerCustomEditorInputFactory(scheme: string, factory: ICustomEditorInputFactory): void {
this.customEditorInputFactoryInstances.set(scheme, factory);
}
getCustomEditorInputFactory(): ICustomEditorInputFactory {
return assertIsDefined(this.customEditorInputFactory);
getCustomEditorInputFactory(scheme: string): ICustomEditorInputFactory | undefined {
return this.customEditorInputFactoryInstances.get(scheme);
}
registerEditorInputFactory(editorInputId: string, ctor: IConstructorSignature0<IEditorInputFactory>): IDisposable {
@@ -1347,8 +1361,12 @@ export async function pathsToEditors(paths: IPathData[] | undefined, fileService
startLineNumber: path.lineNumber,
startColumn: path.columnNumber || 1
},
pinned: true
} : { pinned: true };
pinned: true,
override: path.overrideId
} : {
pinned: true,
override: path.overrideId
};
let input: IResourceEditorInput | IUntitledTextResourceEditorInput;
if (!exists) {
@@ -1375,3 +1393,23 @@ export const enum EditorsOrder {
*/
SEQUENTIAL
}
export function computeEditorAriaLabel(input: IEditorInput, index: number | undefined, group: IEditorGroup | undefined, groupCount: number): string {
let ariaLabel = input.getAriaLabel();
if (group && !group.isPinned(input)) {
ariaLabel = localize('preview', "{0}, preview", ariaLabel);
}
if (group && group.isSticky(index ?? input)) {
ariaLabel = localize('pinned', "{0}, pinned", ariaLabel);
}
// Apply group information to help identify in
// which group we are (only if more than one group
// is actually opened)
if (group && groupCount > 1) {
ariaLabel = `${ariaLabel}, ${group.ariaLabel}`;
}
return ariaLabel;
}

View File

@@ -690,14 +690,14 @@ export class EditorGroup extends Disposable {
return [this.editors[index], index];
}
contains(candidate: EditorInput, searchInSideBySideEditors?: boolean): boolean {
contains(candidate: EditorInput, options?: { supportSideBySide?: boolean, strictEquals?: boolean }): boolean {
for (const editor of this.editors) {
if (this.matches(editor, candidate)) {
if (this.matches(editor, candidate, options?.strictEquals)) {
return true;
}
if (searchInSideBySideEditors && editor instanceof SideBySideEditorInput) {
if (this.matches(editor.master, candidate) || this.matches(editor.details, candidate)) {
if (options?.supportSideBySide && editor instanceof SideBySideEditorInput) {
if (this.matches(editor.master, candidate, options?.strictEquals) || this.matches(editor.details, candidate, options?.strictEquals)) {
return true;
}
}
@@ -706,11 +706,15 @@ export class EditorGroup extends Disposable {
return false;
}
private matches(editor: IEditorInput | null, candidate: IEditorInput | null): boolean {
private matches(editor: IEditorInput | null, candidate: IEditorInput | null, strictEquals?: boolean): boolean {
if (!editor || !candidate) {
return false;
}
if (strictEquals) {
return editor === candidate;
}
return editor.matches(candidate);
}

View File

@@ -28,9 +28,9 @@ export class ResourceEditorInput extends AbstractTextResourceEditorInput impleme
private modelReference: Promise<IReference<ITextEditorModel>> | undefined = undefined;
constructor(
resource: URI,
private name: string | undefined,
private description: string | undefined,
resource: URI,
private preferredMode: string | undefined,
@ITextModelService private readonly textModelResolverService: ITextModelService,
@ITextFileService textFileService: ITextFileService,
@@ -40,7 +40,7 @@ export class ResourceEditorInput extends AbstractTextResourceEditorInput impleme
@ILabelService labelService: ILabelService,
@IFilesConfigurationService filesConfigurationService: IFilesConfigurationService
) {
super(resource, editorService, editorGroupService, textFileService, labelService, fileService, filesConfigurationService);
super(resource, undefined, editorService, editorGroupService, textFileService, labelService, fileService, filesConfigurationService);
}
getTypeId(): string {

View File

@@ -41,7 +41,7 @@ export class BaseTextEditorModel extends EditorModel implements ITextEditorModel
// We need the resource to point to an existing model
const model = this.modelService.getModel(textEditorModelHandle);
if (!model) {
throw new Error(`Document with resource ${textEditorModelHandle.toString()} does not exist`);
throw new Error(`Document with resource ${textEditorModelHandle.toString(true)} does not exist`);
}
this.textEditorModelHandle = textEditorModelHandle;

View File

@@ -13,7 +13,7 @@ import { ILabelService } from 'vs/platform/label/common/label';
import { IFilesConfigurationService, AutoSaveMode } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { createMemoizer } from 'vs/base/common/decorators';
import { Schemas } from 'vs/base/common/network';
import { dirname, isEqual } from 'vs/base/common/resources';
import { dirname, extUri } from 'vs/base/common/resources';
/**
* The base class for all editor inputs that open in text editors.
@@ -22,8 +22,11 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput {
private static readonly MEMOIZER = createMemoizer();
private label: URI;
constructor(
public readonly resource: URI,
preferredLabel: URI | undefined,
@IEditorService protected readonly editorService: IEditorService,
@IEditorGroupsService protected readonly editorGroupService: IEditorGroupsService,
@ITextFileService protected readonly textFileService: ITextFileService,
@@ -33,6 +36,8 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput {
) {
super();
this.label = preferredLabel || resource;
this.registerListeners();
}
@@ -45,23 +50,39 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput {
}
private onLabelEvent(scheme: string): void {
if (scheme === this.resource.scheme) {
// Clear any cached labels from before
AbstractTextResourceEditorInput.MEMOIZER.clear();
// Trigger recompute of label
this._onDidChangeLabel.fire();
if (scheme === this.label.scheme) {
this.updateLabel();
}
}
private updateLabel(): void {
// Clear any cached labels from before
AbstractTextResourceEditorInput.MEMOIZER.clear();
// Trigger recompute of label
this._onDidChangeLabel.fire();
}
setLabel(label: URI): void {
if (!extUri.isEqual(label, this.label)) {
this.label = label;
this.updateLabel();
}
}
getLabel(): URI {
return this.label;
}
getName(): string {
return this.basename;
}
@AbstractTextResourceEditorInput.MEMOIZER
private get basename(): string {
return this.labelService.getUriBasenameLabel(this.resource);
return this.labelService.getUriBasenameLabel(this.label);
}
getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string | undefined {
@@ -78,17 +99,17 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput {
@AbstractTextResourceEditorInput.MEMOIZER
private get shortDescription(): string {
return this.labelService.getUriBasenameLabel(dirname(this.resource));
return this.labelService.getUriBasenameLabel(dirname(this.label));
}
@AbstractTextResourceEditorInput.MEMOIZER
private get mediumDescription(): string {
return this.labelService.getUriLabel(dirname(this.resource), { relative: true });
return this.labelService.getUriLabel(dirname(this.label), { relative: true });
}
@AbstractTextResourceEditorInput.MEMOIZER
private get longDescription(): string {
return this.labelService.getUriLabel(dirname(this.resource));
return this.labelService.getUriLabel(dirname(this.label));
}
@AbstractTextResourceEditorInput.MEMOIZER
@@ -98,12 +119,12 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput {
@AbstractTextResourceEditorInput.MEMOIZER
private get mediumTitle(): string {
return this.labelService.getUriLabel(this.resource, { relative: true });
return this.labelService.getUriLabel(this.label, { relative: true });
}
@AbstractTextResourceEditorInput.MEMOIZER
private get longTitle(): string {
return this.labelService.getUriLabel(this.resource);
return this.labelService.getUriLabel(this.label);
}
getTitle(verbosity: Verbosity): string {
@@ -164,11 +185,7 @@ export abstract class AbstractTextResourceEditorInput extends EditorInput {
return undefined; // save cancelled
}
if (!isEqual(target, this.resource)) {
return this.editorService.createEditorInput({ resource: target });
}
return this;
return this.editorService.createEditorInput({ resource: target });
}
async revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void> {

View File

@@ -318,13 +318,13 @@ export const PANEL_SECTION_HEADER_BORDER = registerColor('panelSectionHeader.bor
dark: contrastBorder,
light: contrastBorder,
hc: contrastBorder
}, nls.localize('panelSectionHeaderBorder', "Panel section header border color. Panels are shown below the editor area and contain views like output and integrated terminal."));
}, nls.localize('panelSectionHeaderBorder', "Panel section header border color used when multiple views are stacked vertically in the panel. Panels are shown below the editor area and contain views like output and integrated terminal."));
export const PANEL_SECTION_BORDER = registerColor('panelSection.border', {
dark: PANEL_BORDER,
light: PANEL_BORDER,
hc: PANEL_BORDER
}, nls.localize('panelSectionBorder', "Panel section border color. Panels are shown below the editor area and contain views like output and integrated terminal."));
}, nls.localize('panelSectionBorder', "Panel section border color used when multiple views are stacked horizontally in the panel. Panels are shown below the editor area and contain views like output and integrated terminal."));
// < --- Status --- >

View File

@@ -60,7 +60,9 @@ export interface IViewContainerDescriptor {
readonly rejectAddedViews?: boolean;
order?: number;
readonly order?: number;
requestedIndex?: number;
}
export interface IViewContainersRegistry {
@@ -473,7 +475,7 @@ export interface IView {
export const IViewsService = createDecorator<IViewsService>('viewsService');
export interface IViewsService {
_serviceBrand: undefined;
readonly _serviceBrand: undefined;
// View Container APIs
readonly onDidChangeViewContainerVisibility: Event<{ id: string, visible: boolean, location: ViewContainerLocation }>;
@@ -501,7 +503,7 @@ export const IViewDescriptorService = createDecorator<IViewDescriptorService>('v
export interface IViewDescriptorService {
_serviceBrand: undefined;
readonly _serviceBrand: undefined;
// ViewContainers
readonly viewContainers: ReadonlyArray<ViewContainer>;
@@ -515,7 +517,7 @@ export interface IViewDescriptorService {
getViewContainerModel(viewContainer: ViewContainer): IViewContainerModel;
readonly onDidChangeContainerLocation: Event<{ viewContainer: ViewContainer, from: ViewContainerLocation, to: ViewContainerLocation }>;
moveViewContainerToLocation(viewContainer: ViewContainer, location: ViewContainerLocation, order?: number): void;
moveViewContainerToLocation(viewContainer: ViewContainer, location: ViewContainerLocation, requestedIndex?: number): void;
// Views
getViewDescriptorById(id: string): IViewDescriptor | null;