Merge from vscode 9bc92b48d945144abb405b9e8df05e18accb9148

This commit is contained in:
ADS Merger
2020-02-19 03:11:35 +00:00
parent 98584d32a7
commit 1e308639e5
253 changed files with 6414 additions and 2296 deletions

View File

@@ -363,9 +363,13 @@ export interface IEditorInput extends IDisposable {
readonly onDidChangeLabel: Event<void>;
/**
* Returns the associated resource of this input.
* Returns the optional associated resource of this input.
*
* This resource should be unique for all editors of the same
* kind and is often used to identify the editor input among
* others.
*/
getResource(): URI | undefined;
readonly resource: URI | undefined;
/**
* Unique type identifier for this inpput.
@@ -470,11 +474,9 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
private disposed: boolean = false;
abstract getTypeId(): string;
abstract get resource(): URI | undefined;
getResource(): URI | undefined {
return undefined;
}
abstract getTypeId(): string;
getName(): string {
return `Editor ${this.getTypeId()}`;
@@ -574,7 +576,7 @@ export abstract class TextResourceEditorInput extends EditorInput {
private static readonly MEMOIZER = createMemoizer();
constructor(
protected readonly resource: URI,
public readonly resource: URI,
@IEditorService protected readonly editorService: IEditorService,
@IEditorGroupsService protected readonly editorGroupService: IEditorGroupsService,
@ITextFileService protected readonly textFileService: ITextFileService,
@@ -584,15 +586,16 @@ export abstract class TextResourceEditorInput extends EditorInput {
) {
super();
this.registerListeners();
}
protected registerListeners(): void {
// Clear label memoizer on certain events that have impact
this._register(this.labelService.onDidChangeFormatters(() => TextResourceEditorInput.MEMOIZER.clear()));
this._register(this.fileService.onDidChangeFileSystemProviderRegistrations(() => TextResourceEditorInput.MEMOIZER.clear()));
}
getResource(): URI {
return this.resource;
}
getName(): string {
return this.basename;
}
@@ -669,9 +672,7 @@ export abstract class TextResourceEditorInput extends EditorInput {
return true; // resources without file support are always readonly
}
const model = this.textFileService.files.get(this.resource);
return model?.isReadonly() || this.fileService.hasCapability(this.resource, FileSystemProviderCapabilities.Readonly);
return this.fileService.hasCapability(this.resource, FileSystemProviderCapabilities.Readonly);
}
isSaving(): boolean {
@@ -763,7 +764,7 @@ export interface IFileEditorInput extends IEditorInput, IEncodingSupport, IModeS
/**
* Gets the resource this editor is about.
*/
getResource(): URI;
readonly resource: URI;
/**
* Sets the preferred encoding to use for this input.
@@ -799,6 +800,10 @@ export class SideBySideEditorInput extends EditorInput {
this.registerListeners();
}
get resource(): URI | undefined {
return undefined;
}
get master(): EditorInput {
return this._master;
}
@@ -1312,7 +1317,7 @@ export function toResource(editor: IEditorInput | undefined, options?: IResource
editor = options.supportSideBySide === SideBySideEditor.MASTER ? editor.master : editor.details;
}
const resource = editor.getResource();
const resource = editor.resource;
if (!resource || !options || !options.filterByScheme) {
return resource;
}

View File

@@ -141,7 +141,7 @@ export class BaseTextEditorModel extends EditorModel implements ITextEditorModel
/**
* 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 {
updateTextEditorModel(newValue?: ITextBufferFactory, preferredMode?: string): void {
if (!this.isResolved()) {
return;
}

View File

@@ -10,34 +10,34 @@ import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'
import { isPromiseCanceledError } from 'vs/base/common/errors';
import { Action } from 'vs/base/common/actions';
import { isErrorWithActions } from 'vs/base/common/errorsWithActions';
import { startsWith } from 'vs/base/common/strings';
import { localize } from 'vs/nls';
import { find, equals } from 'vs/base/common/arrays';
import { parseLinkedText, LinkedText } from 'vs/base/common/linkedText';
export interface INotificationsModel {
//
// Notifications as Toasts/Center
//
//#region Notifications as Toasts/Center
readonly notifications: INotificationViewItem[];
readonly onDidNotificationChange: Event<INotificationChangeEvent>;
readonly onDidFilterChange: Event<NotificationsFilter>;
readonly onDidChangeNotification: Event<INotificationChangeEvent>;
readonly onDidChangeFilter: Event<NotificationsFilter>;
addNotification(notification: INotification): INotificationHandle;
setFilter(filter: NotificationsFilter): void;
//
// Notifications as Status
//
//#endregion
//#region Notifications as Status
readonly statusMessage: IStatusMessageViewItem | undefined;
readonly onDidStatusMessageChange: Event<IStatusMessageChangeEvent>;
readonly onDidChangeStatusMessage: Event<IStatusMessageChangeEvent>;
showStatusMessage(message: NotificationMessage, options?: IStatusMessageOptions): IDisposable;
//#endregion
}
export const enum NotificationChangeType {
@@ -87,19 +87,22 @@ export interface IStatusMessageChangeEvent {
kind: StatusMessageChangeType;
}
export class NotificationHandle implements INotificationHandle {
export class NotificationHandle extends Disposable implements INotificationHandle {
private readonly _onDidClose: Emitter<void> = new Emitter();
readonly onDidClose: Event<void> = this._onDidClose.event;
private readonly _onDidClose = this._register(new Emitter<void>());
readonly onDidClose = this._onDidClose.event;
constructor(private readonly item: INotificationViewItem, private readonly onClose: (item: INotificationViewItem) => void) {
super();
constructor(private readonly item: INotificationViewItem, private readonly closeItem: (item: INotificationViewItem) => void) {
this.registerListeners();
}
private registerListeners(): void {
Event.once(this.item.onDidClose)(() => {
this._onDidClose.fire();
this._onDidClose.dispose();
this.dispose();
});
}
@@ -120,8 +123,9 @@ export class NotificationHandle implements INotificationHandle {
}
close(): void {
this.closeItem(this.item);
this._onDidClose.dispose();
this.onClose(this.item);
this.dispose();
}
}
@@ -129,14 +133,14 @@ export class NotificationsModel extends Disposable implements INotificationsMode
private static readonly NO_OP_NOTIFICATION = new NoOpNotification();
private readonly _onDidNotificationChange = this._register(new Emitter<INotificationChangeEvent>());
readonly onDidNotificationChange: Event<INotificationChangeEvent> = this._onDidNotificationChange.event;
private readonly _onDidChangeNotification = this._register(new Emitter<INotificationChangeEvent>());
readonly onDidChangeNotification = this._onDidChangeNotification.event;
private readonly _onDidStatusMessageChange = this._register(new Emitter<IStatusMessageChangeEvent>());
readonly onDidStatusMessageChange: Event<IStatusMessageChangeEvent> = this._onDidStatusMessageChange.event;
private readonly _onDidChangeStatusMessage = this._register(new Emitter<IStatusMessageChangeEvent>());
readonly onDidChangeStatusMessage = this._onDidChangeStatusMessage.event;
private readonly _onDidFilterChange = this._register(new Emitter<NotificationsFilter>());
readonly onDidFilterChange: Event<NotificationsFilter> = this._onDidFilterChange.event;
private readonly _onDidChangeFilter = this._register(new Emitter<NotificationsFilter>());
readonly onDidChangeFilter = this._onDidChangeFilter.event;
private readonly _notifications: INotificationViewItem[] = [];
get notifications(): INotificationViewItem[] { return this._notifications; }
@@ -149,7 +153,7 @@ export class NotificationsModel extends Disposable implements INotificationsMode
setFilter(filter: NotificationsFilter): void {
this.filter = filter;
this._onDidFilterChange.fire(filter);
this._onDidChangeFilter.fire(filter);
}
addNotification(notification: INotification): INotificationHandle {
@@ -168,13 +172,13 @@ export class NotificationsModel extends Disposable implements INotificationsMode
this._notifications.splice(0, 0, item);
// Events
this._onDidNotificationChange.fire({ item, index: 0, kind: NotificationChangeType.ADD });
this._onDidChangeNotification.fire({ item, index: 0, kind: NotificationChangeType.ADD });
// Wrap into handle
return new NotificationHandle(item, item => this.closeItem(item));
return new NotificationHandle(item, item => this.onClose(item));
}
private closeItem(item: INotificationViewItem): void {
private onClose(item: INotificationViewItem): void {
const liveItem = this.findNotification(item);
if (liveItem && liveItem !== item) {
liveItem.close(); // item could have been replaced with another one, make sure to close the live item
@@ -197,13 +201,13 @@ export class NotificationsModel extends Disposable implements INotificationsMode
const onItemChangeEvent = () => {
const index = this._notifications.indexOf(item);
if (index >= 0) {
this._onDidNotificationChange.fire({ item, index, kind: NotificationChangeType.CHANGE });
this._onDidChangeNotification.fire({ item, index, kind: NotificationChangeType.CHANGE });
}
};
const itemExpansionChangeListener = item.onDidExpansionChange(() => onItemChangeEvent());
const itemExpansionChangeListener = item.onDidChangeExpansion(() => onItemChangeEvent());
const itemLabelChangeListener = item.onDidLabelChange(e => {
const itemLabelChangeListener = item.onDidChangeLabel(e => {
// a label change in the area of actions or the message is a change that potentially has an impact
// on the size of the notification and as such we emit a change event so that viewers can redraw
if (e.kind === NotificationViewItemLabelKind.ACTIONS || e.kind === NotificationViewItemLabelKind.MESSAGE) {
@@ -218,7 +222,7 @@ export class NotificationsModel extends Disposable implements INotificationsMode
const index = this._notifications.indexOf(item);
if (index >= 0) {
this._notifications.splice(index, 1);
this._onDidNotificationChange.fire({ item, index, kind: NotificationChangeType.REMOVE });
this._onDidChangeNotification.fire({ item, index, kind: NotificationChangeType.REMOVE });
}
});
@@ -233,14 +237,14 @@ export class NotificationsModel extends Disposable implements INotificationsMode
// Remember as current status message and fire events
this._statusMessage = item;
this._onDidStatusMessageChange.fire({ kind: StatusMessageChangeType.ADD, item });
this._onDidChangeStatusMessage.fire({ kind: StatusMessageChangeType.ADD, item });
return toDisposable(() => {
// Only reset status message if the item is still the one we had remembered
if (this._statusMessage === item) {
this._statusMessage = undefined;
this._onDidStatusMessageChange.fire({ kind: StatusMessageChangeType.REMOVE, item });
this._onDidChangeStatusMessage.fire({ kind: StatusMessageChangeType.REMOVE, item });
}
});
}
@@ -258,9 +262,9 @@ export interface INotificationViewItem {
readonly expanded: boolean;
readonly canCollapse: boolean;
readonly onDidExpansionChange: Event<void>;
readonly onDidChangeExpansion: Event<void>;
readonly onDidClose: Event<void>;
readonly onDidLabelChange: Event<INotificationViewItemLabelChangeEvent>;
readonly onDidChangeLabel: Event<INotificationViewItemLabelChangeEvent>;
expand(): void;
collapse(skipEvents?: boolean): void;
@@ -309,8 +313,8 @@ export interface INotificationViewItemProgress extends INotificationProgress {
export class NotificationViewItemProgress extends Disposable implements INotificationViewItemProgress {
private readonly _state: INotificationViewItemProgressState;
private readonly _onDidChange: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChange: Event<void> = this._onDidChange.event;
private readonly _onDidChange = this._register(new Emitter<void>());
readonly onDidChange = this._onDidChange.event;
constructor() {
super();
@@ -388,31 +392,26 @@ export interface IMessageLink {
export interface INotificationMessage {
raw: string;
original: NotificationMessage;
value: string;
links: IMessageLink[];
linkedText: LinkedText;
}
export class NotificationViewItem extends Disposable implements INotificationViewItem {
private static readonly MAX_MESSAGE_LENGTH = 1000;
// Example link: "Some message with [link text](http://link.href)."
// RegEx: [, anything not ], ], (, http://|https://|command:, no whitespace)
private static readonly LINK_REGEX = /\[([^\]]+)\]\(((?:https?:\/\/|command:)[^\)\s]+)(?: "([^"]+)")?\)/gi;
private _expanded: boolean | undefined;
private _actions: INotificationActions | undefined;
private _progress: NotificationViewItemProgress | undefined;
private readonly _onDidExpansionChange: Emitter<void> = this._register(new Emitter<void>());
readonly onDidExpansionChange: Event<void> = this._onDidExpansionChange.event;
private readonly _onDidChangeExpansion = this._register(new Emitter<void>());
readonly onDidChangeExpansion = this._onDidChangeExpansion.event;
private readonly _onDidClose: Emitter<void> = this._register(new Emitter<void>());
readonly onDidClose: Event<void> = this._onDidClose.event;
private readonly _onDidClose = this._register(new Emitter<void>());
readonly onDidClose = this._onDidClose.event;
private readonly _onDidLabelChange: Emitter<INotificationViewItemLabelChangeEvent> = this._register(new Emitter<INotificationViewItemLabelChangeEvent>());
readonly onDidLabelChange: Event<INotificationViewItemLabelChangeEvent> = this._onDidLabelChange.event;
private readonly _onDidChangeLabel = this._register(new Emitter<INotificationViewItemLabelChangeEvent>());
readonly onDidChangeLabel = this._onDidChangeLabel.event;
static create(notification: INotification, filter: NotificationsFilter = NotificationsFilter.OFF): INotificationViewItem | undefined {
if (!notification || !notification.message || isPromiseCanceledError(notification.message)) {
@@ -464,23 +463,9 @@ export class NotificationViewItem extends Disposable implements INotificationVie
message = message.replace(/(\r\n|\n|\r)/gm, ' ').trim();
// Parse Links
const links: IMessageLink[] = [];
message.replace(NotificationViewItem.LINK_REGEX, (matchString: string, name: string, href: string, title: string, offset: number) => {
let massagedTitle: string;
if (title && title.length > 0) {
massagedTitle = title;
} else if (startsWith(href, 'command:')) {
massagedTitle = localize('executeCommand', "Click to execute command '{0}'", href.substr('command:'.length));
} else {
massagedTitle = href;
}
const linkedText = parseLinkedText(message);
links.push({ name, href, title: massagedTitle, offset, length: matchString.length });
return matchString;
});
return { raw, value: message, links, original: input };
return { raw, linkedText, original: input };
}
private constructor(
@@ -561,7 +546,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie
get progress(): INotificationViewItemProgress {
if (!this._progress) {
this._progress = this._register(new NotificationViewItemProgress());
this._register(this._progress.onDidChange(() => this._onDidLabelChange.fire({ kind: NotificationViewItemLabelKind.PROGRESS })));
this._register(this._progress.onDidChange(() => this._onDidChangeLabel.fire({ kind: NotificationViewItemLabelKind.PROGRESS })));
}
return this._progress;
@@ -581,7 +566,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie
updateSeverity(severity: Severity): void {
this._severity = severity;
this._onDidLabelChange.fire({ kind: NotificationViewItemLabelKind.SEVERITY });
this._onDidChangeLabel.fire({ kind: NotificationViewItemLabelKind.SEVERITY });
}
updateMessage(input: NotificationMessage): void {
@@ -591,13 +576,13 @@ export class NotificationViewItem extends Disposable implements INotificationVie
}
this._message = message;
this._onDidLabelChange.fire({ kind: NotificationViewItemLabelKind.MESSAGE });
this._onDidChangeLabel.fire({ kind: NotificationViewItemLabelKind.MESSAGE });
}
updateActions(actions?: INotificationActions): void {
this.setActions(actions);
this._onDidLabelChange.fire({ kind: NotificationViewItemLabelKind.ACTIONS });
this._onDidChangeLabel.fire({ kind: NotificationViewItemLabelKind.ACTIONS });
}
expand(): void {
@@ -606,7 +591,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie
}
this._expanded = true;
this._onDidExpansionChange.fire();
this._onDidChangeExpansion.fire();
}
collapse(skipEvents?: boolean): void {
@@ -617,7 +602,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie
this._expanded = false;
if (!skipEvents) {
this._onDidExpansionChange.fire();
this._onDidChangeExpansion.fire();
}
}
@@ -644,7 +629,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie
return false;
}
if (this._message.value !== other.message.value) {
if (this._message.raw !== other.message.raw) {
return false;
}
@@ -656,8 +641,8 @@ export class NotificationViewItem extends Disposable implements INotificationVie
export class ChoiceAction extends Action {
private readonly _onDidRun = new Emitter<void>();
readonly onDidRun: Event<void> = this._onDidRun.event;
private readonly _onDidRun = this._register(new Emitter<void>());
readonly onDidRun = this._onDidRun.event;
private readonly _keepOpen: boolean;
@@ -679,12 +664,6 @@ export class ChoiceAction extends Action {
get keepOpen(): boolean {
return this._keepOpen;
}
dispose(): void {
super.dispose();
this._onDidRun.dispose();
}
}
class StatusMessageViewItem {

View File

@@ -5,7 +5,7 @@
import { URI } from 'vs/base/common/uri';
import * as objects from 'vs/base/common/objects';
import { Event, Emitter } from 'vs/base/common/event';
import { Emitter } from 'vs/base/common/event';
import { basename, extname, relativePath } from 'vs/base/common/resources';
import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IModeService } from 'vs/editor/common/services/modeService';
@@ -106,8 +106,8 @@ export class ResourceGlobMatcher extends Disposable {
private static readonly NO_ROOT: string | null = null;
private readonly _onExpressionChange: Emitter<void> = this._register(new Emitter<void>());
readonly onExpressionChange: Event<void> = this._onExpressionChange.event;
private readonly _onExpressionChange = this._register(new Emitter<void>());
readonly onExpressionChange = this._onExpressionChange.event;
private readonly mapRootToParsedExpression: Map<string | null, ParsedExpression> = new Map<string, ParsedExpression>();
private readonly mapRootToExpressionConfig: Map<string | null, IExpression> = new Map<string, IExpression>();

View File

@@ -213,6 +213,7 @@ export interface IViewDescriptorCollection extends IDisposable {
export interface IViewContentDescriptor {
readonly content: string;
readonly when?: ContextKeyExpr | 'default';
}
export interface IViewsRegistry {
@@ -235,9 +236,13 @@ export interface IViewsRegistry {
getViewContainer(id: string): ViewContainer | null;
readonly onDidChangeEmptyViewContent: Event<string>;
registerEmptyViewContent(id: string, viewContent: IViewContentDescriptor): IDisposable;
getEmptyViewContent(id: string): IViewContentDescriptor[];
readonly onDidChangeViewWelcomeContent: Event<string>;
registerViewWelcomeContent(id: string, viewContent: IViewContentDescriptor): IDisposable;
getViewWelcomeContent(id: string): IViewContentDescriptor[];
}
function compareViewContentDescriptors(a: IViewContentDescriptor, b: IViewContentDescriptor): number {
return a.content < b.content ? -1 : 1;
}
class ViewsRegistry extends Disposable implements IViewsRegistry {
@@ -251,12 +256,12 @@ class ViewsRegistry extends Disposable implements IViewsRegistry {
private readonly _onDidChangeContainer: Emitter<{ views: IViewDescriptor[], from: ViewContainer, to: ViewContainer }> = this._register(new Emitter<{ views: IViewDescriptor[], from: ViewContainer, to: ViewContainer }>());
readonly onDidChangeContainer: Event<{ views: IViewDescriptor[], from: ViewContainer, to: ViewContainer }> = this._onDidChangeContainer.event;
private readonly _onDidChangeEmptyViewContent: Emitter<string> = this._register(new Emitter<string>());
readonly onDidChangeEmptyViewContent: Event<string> = this._onDidChangeEmptyViewContent.event;
private readonly _onDidChangeViewWelcomeContent: Emitter<string> = this._register(new Emitter<string>());
readonly onDidChangeViewWelcomeContent: Event<string> = this._onDidChangeViewWelcomeContent.event;
private _viewContainers: ViewContainer[] = [];
private _views: Map<ViewContainer, IViewDescriptor[]> = new Map<ViewContainer, IViewDescriptor[]>();
private _emptyViewContents = new SetMap<string, IViewContentDescriptor>();
private _viewWelcomeContents = new SetMap<string, IViewContentDescriptor>();
registerViews(views: IViewDescriptor[], viewContainer: ViewContainer): void {
this.addViews(views, viewContainer);
@@ -306,19 +311,20 @@ class ViewsRegistry extends Disposable implements IViewsRegistry {
return null;
}
registerEmptyViewContent(id: string, viewContent: IViewContentDescriptor): IDisposable {
this._emptyViewContents.add(id, viewContent);
this._onDidChangeEmptyViewContent.fire(id);
registerViewWelcomeContent(id: string, viewContent: IViewContentDescriptor): IDisposable {
this._viewWelcomeContents.add(id, viewContent);
this._onDidChangeViewWelcomeContent.fire(id);
return toDisposable(() => {
this._emptyViewContents.delete(id, viewContent);
this._onDidChangeEmptyViewContent.fire(id);
this._viewWelcomeContents.delete(id, viewContent);
this._onDidChangeViewWelcomeContent.fire(id);
});
}
getEmptyViewContent(id: string): IViewContentDescriptor[] {
getViewWelcomeContent(id: string): IViewContentDescriptor[] {
const result: IViewContentDescriptor[] = [];
this._emptyViewContents.forEach(id, descriptor => result.push(descriptor));
result.sort(compareViewContentDescriptors);
this._viewWelcomeContents.forEach(id, descriptor => result.push(descriptor));
return result;
}
@@ -330,8 +336,8 @@ class ViewsRegistry extends Disposable implements IViewsRegistry {
this._viewContainers.push(viewContainer);
}
for (const viewDescriptor of viewDescriptors) {
if (views.some(v => v.id === viewDescriptor.id)) {
throw new Error(localize('duplicateId', "A view with id '{0}' is already registered in the container '{1}'", viewDescriptor.id, viewContainer.id));
if (this.getView(viewDescriptor.id) !== null) {
throw new Error(localize('duplicateId', "A view with id '{0}' is already registered", viewDescriptor.id));
}
views.push(viewDescriptor);
}