Merge from vscode cfc1ab4c5f816765b91fb7ead3c3427a7c8581a3

This commit is contained in:
ADS Merger
2020-03-11 04:19:23 +00:00
parent 16fab722d5
commit 4c3e48773d
880 changed files with 20441 additions and 11232 deletions

View File

@@ -11,7 +11,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { ContextKeyExpr, ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey';
export const Extensions = {
WorkbenchActions: 'workbench.contributions.actions'
@@ -28,11 +28,11 @@ export interface IWorkbenchActionRegistry {
Registry.add(Extensions.WorkbenchActions, new class implements IWorkbenchActionRegistry {
registerWorkbenchAction(descriptor: SyncActionDescriptor, alias: string, category?: string, when?: ContextKeyExpr): IDisposable {
registerWorkbenchAction(descriptor: SyncActionDescriptor, alias: string, category?: string, when?: ContextKeyExpression): IDisposable {
return this.registerWorkbenchCommandFromAction(descriptor, alias, category, when);
}
private registerWorkbenchCommandFromAction(descriptor: SyncActionDescriptor, alias: string, category?: string, when?: ContextKeyExpr): IDisposable {
private registerWorkbenchCommandFromAction(descriptor: SyncActionDescriptor, alias: string, category?: string, when?: ContextKeyExpression): IDisposable {
const registrations = new DisposableStore();
// command
@@ -98,7 +98,7 @@ Registry.add(Extensions.WorkbenchActions, new class implements IWorkbenchActionR
};
}
private async triggerAndDisposeAction(instantiationService: IInstantiationService, lifecycleService: ILifecycleService, descriptor: SyncActionDescriptor, args: any): Promise<void> {
private async triggerAndDisposeAction(instantiationService: IInstantiationService, lifecycleService: ILifecycleService, descriptor: SyncActionDescriptor, args: unknown): Promise<void> {
// run action when workbench is created
await lifecycleService.when(LifecyclePhase.Ready);
@@ -115,7 +115,7 @@ Registry.add(Extensions.WorkbenchActions, new class implements IWorkbenchActionR
// otherwise run and dispose
try {
const from = args?.from || 'keybinding';
const from = (args as any)?.from || 'keybinding';
await actionInstance.run(undefined, { from });
} finally {
actionInstance.dispose();

View File

@@ -4,8 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Memento, MementoObject } from 'vs/workbench/common/memento';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { Themable } from 'vs/workbench/common/theme';
import { IThemeService, Themable } from 'vs/platform/theme/common/themeService';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
export class Component extends Themable {
@@ -42,4 +41,4 @@ export class Component extends Themable {
protected saveState(): void {
// Subclasses to implement for storing state
}
}
}

View File

@@ -38,15 +38,17 @@ export interface IWorkbenchContributionsRegistry {
}
class WorkbenchContributionsRegistry implements IWorkbenchContributionsRegistry {
private instantiationService: IInstantiationService | undefined;
private lifecycleService: ILifecycleService | undefined;
private readonly toBeInstantiated: Map<LifecyclePhase, IConstructorSignature0<IWorkbenchContribution>[]> = new Map<LifecyclePhase, IConstructorSignature0<IWorkbenchContribution>[]>();
private readonly toBeInstantiated = new Map<LifecyclePhase, IConstructorSignature0<IWorkbenchContribution>[]>();
registerWorkbenchContribution(ctor: IConstructorSignature0<IWorkbenchContribution>, phase: LifecyclePhase = LifecyclePhase.Starting): void {
registerWorkbenchContribution<Services extends BrandedService[]>(ctor: new (...services: Services) => IWorkbenchContribution, phase: LifecyclePhase = LifecyclePhase.Starting): void {
// Instantiate directly if we are already matching the provided phase
if (this.instantiationService && this.lifecycleService && this.lifecycleService.phase >= phase) {
this.instantiationService.createInstance<Services, typeof ctor, IWorkbenchContribution>(ctor);
this.instantiationService.createInstance(ctor);
}
// Otherwise keep contributions by lifecycle phase

View File

@@ -9,22 +9,21 @@ import { assign } from 'vs/base/common/objects';
import { withNullAsUndefined, assertIsDefined } from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
import { IDisposable, Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { IEditor as ICodeEditor, IEditorViewState, ScrollType, IDiffEditor } from 'vs/editor/common/editorCommon';
import { IEditorModel, IEditorOptions, ITextEditorOptions, IBaseResourceInput, IResourceInput, EditorActivation, EditorOpenContext, ITextEditorSelection, TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor';
import { IEditor, IEditorViewState, ScrollType, IDiffEditor } from 'vs/editor/common/editorCommon';
import { IEditorModel, IEditorOptions, ITextEditorOptions, IBaseResourceEditorInput, IResourceEditorInput, EditorActivation, EditorOpenContext, ITextEditorSelection, TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor';
import { IInstantiationService, IConstructorSignature0, ServicesAccessor, BrandedService } from 'vs/platform/instantiation/common/instantiation';
import { RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { Registry } from 'vs/platform/registry/common/platform';
import { ITextModel } from 'vs/editor/common/model';
import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ICompositeControl } from 'vs/workbench/common/composite';
import { ICompositeControl, IComposite } from 'vs/workbench/common/composite';
import { ActionRunner, IAction } from 'vs/base/common/actions';
import { IFileService, FileSystemProviderCapabilities } from 'vs/platform/files/common/files';
import { IPathData } from 'vs/platform/windows/common/windows';
import { coalesce, firstOrDefault } from 'vs/base/common/arrays';
import { ITextFileSaveOptions, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService';
import { IEditorService, IResourceEditorInputType } from 'vs/workbench/services/editor/common/editorService';
import { isEqual, dirname } from 'vs/base/common/resources';
import { IPanel } from 'vs/workbench/common/panel';
import { IRange } from 'vs/editor/common/core/range';
import { createMemoizer } from 'vs/base/common/decorators';
import { ILabelService } from 'vs/platform/label/common/label';
@@ -38,7 +37,7 @@ export const EditorsVisibleContext = new RawContextKey<boolean>('editorIsOpen',
export const EditorPinnedContext = new RawContextKey<boolean>('editorPinned', false);
export const EditorGroupActiveEditorDirtyContext = new RawContextKey<boolean>('groupActiveEditorDirty', false);
export const EditorGroupEditorsCountContext = new RawContextKey<number>('groupEditorsCount', 0);
export const NoEditorsVisibleContext: ContextKeyExpr = EditorsVisibleContext.toNegated();
export const NoEditorsVisibleContext = EditorsVisibleContext.toNegated();
export const TextCompareEditorVisibleContext = new RawContextKey<boolean>('textCompareEditorVisible', false);
export const TextCompareEditorActiveContext = new RawContextKey<boolean>('textCompareEditorActive', false);
export const ActiveEditorGroupEmptyContext = new RawContextKey<boolean>('activeEditorGroupEmpty', false);
@@ -61,22 +60,20 @@ export const TEXT_DIFF_EDITOR_ID = 'workbench.editors.textDiffEditor';
*/
export const BINARY_DIFF_EDITOR_ID = 'workbench.editors.binaryResourceDiffEditor';
export interface IEditor extends IPanel {
/**
* The editor pane is the container for workbench editors.
*/
export interface IEditorPane extends IComposite {
/**
* The assigned input of this editor.
*/
input: IEditorInput | undefined;
/**
* The assigned options of this editor.
*/
options: IEditorOptions | undefined;
readonly input: IEditorInput | undefined;
/**
* The assigned group this editor is showing in.
*/
group: IEditorGroup | undefined;
readonly group: IEditorGroup | undefined;
/**
* The minimum width of this editor.
@@ -104,7 +101,9 @@ export interface IEditor extends IPanel {
readonly onDidSizeConstraintsChange: Event<{ width: number; height: number; } | undefined>;
/**
* Returns the underlying control of this editor.
* Returns the underlying control of this editor. Callers need to cast
* the control to a specific instance as needed, e.g. by using the
* `isCodeEditor` helper method to access the text code editor.
*/
getControl(): IEditorControl | undefined;
@@ -114,12 +113,23 @@ export interface IEditor extends IPanel {
isVisible(): boolean;
}
export interface ITextEditor extends IEditor {
/**
* Overrides `IEditorPane` where `input` and `group` are known to be set.
*/
export interface IVisibleEditorPane extends IEditorPane {
readonly input: IEditorInput;
readonly group: IEditorGroup;
}
/**
* The text editor pane is the container for workbench text editors.
*/
export interface ITextEditorPane extends IEditorPane {
/**
* Returns the underlying text editor widget of this editor.
*/
getControl(): ICodeEditor | undefined;
getControl(): IEditor | undefined;
/**
* Returns the current view state of the text editor if any.
@@ -127,13 +137,16 @@ export interface ITextEditor extends IEditor {
getViewState(): IEditorViewState | undefined;
}
export function isTextEditor(thing: IEditor | undefined): thing is ITextEditor {
const candidate = thing as ITextEditor | undefined;
export function isTextEditorPane(thing: IEditorPane | undefined): thing is ITextEditorPane {
const candidate = thing as ITextEditorPane | undefined;
return typeof candidate?.getViewState === 'function';
}
export interface ITextDiffEditor extends IEditor {
/**
* The text editor pane is the container for workbench text diff editors.
*/
export interface ITextDiffEditorPane extends IEditorPane {
/**
* Returns the underlying text editor widget of this editor.
@@ -141,44 +154,31 @@ export interface ITextDiffEditor extends IEditor {
getControl(): IDiffEditor | undefined;
}
export interface ITextSideBySideEditor extends IEditor {
/**
* Returns the underlying text editor widget of the master side
* of this side-by-side editor.
*/
getMasterEditor(): ITextEditor;
/**
* Returns the underlying text editor widget of the details side
* of this side-by-side editor.
*/
getDetailsEditor(): ITextEditor;
}
/**
* Marker interface for the base editor control
* Marker interface for the control inside an editor pane. Callers
* have to cast the control to work with it, e.g. via methods
* such as `isCodeEditor(control)`.
*/
export interface IEditorControl extends ICompositeControl { }
export interface IFileInputFactory {
export interface IFileEditorInputFactory {
createFileInput(resource: URI, encoding: string | undefined, mode: string | undefined, instantiationService: IInstantiationService): IFileEditorInput;
createFileEditorInput(resource: URI, encoding: string | undefined, mode: string | undefined, instantiationService: IInstantiationService): IFileEditorInput;
isFileInput(obj: unknown): obj is IFileEditorInput;
isFileEditorInput(obj: unknown): obj is IFileEditorInput;
}
export interface IEditorInputFactoryRegistry {
/**
* Registers the file input factory to use for file inputs.
* Registers the file editor input factory to use for file inputs.
*/
registerFileInputFactory(factory: IFileInputFactory): void;
registerFileEditorInputFactory(factory: IFileEditorInputFactory): void;
/**
* Returns the file input factory to use for file inputs.
* Returns the file editor input factory to use for file inputs.
*/
getFileInputFactory(): IFileInputFactory;
getFileEditorInputFactory(): IFileEditorInputFactory;
/**
* Registers a editor input factory for the given editor input to the registry. An editor input factory
@@ -222,7 +222,7 @@ export interface IEditorInputFactory {
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput | undefined;
}
export interface IUntitledTextResourceInput extends IBaseResourceInput {
export interface IUntitledTextResourceEditorInput extends IBaseResourceEditorInput {
/**
* Optional resource. If the resource is not provided a new untitled file is created (e.g. Untitled-1).
@@ -248,7 +248,7 @@ export interface IUntitledTextResourceInput extends IBaseResourceInput {
readonly encoding?: string;
}
export interface IResourceDiffInput extends IBaseResourceInput {
export interface IResourceDiffEditorInput extends IBaseResourceEditorInput {
/**
* The left hand side URI to open inside a diff editor.
@@ -261,19 +261,6 @@ export interface IResourceDiffInput extends IBaseResourceInput {
readonly rightResource: URI;
}
export interface IResourceSideBySideInput extends IBaseResourceInput {
/**
* The right hand side URI to open inside a side by side editor.
*/
readonly masterResource: URI;
/**
* The left hand side URI to open inside a side by side editor.
*/
readonly detailResource: URI;
}
export const enum Verbosity {
SHORT,
MEDIUM,
@@ -346,7 +333,7 @@ export interface IRevertOptions {
}
export interface IMoveResult {
editor: EditorInput | IResourceEditor;
editor: EditorInput | IResourceEditorInputType;
options?: IEditorOptions;
}
@@ -449,7 +436,7 @@ export interface IEditorInput extends IDisposable {
/**
* Reverts this input from the provided group.
*/
revert(group: GroupIdentifier, options?: IRevertOptions): Promise<boolean>;
revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void>;
/**
* Called to determine how to handle a resource that is moved that matches
@@ -557,9 +544,7 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
return this;
}
async revert(group: GroupIdentifier, options?: IRevertOptions): Promise<boolean> {
return true;
}
async revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void> { }
move(group: GroupIdentifier, target: URI): IMoveResult | undefined {
return undefined;
@@ -611,8 +596,20 @@ export abstract class TextResourceEditorInput extends EditorInput {
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()));
this._register(this.labelService.onDidChangeFormatters(e => this.onLabelEvent(e.scheme)));
this._register(this.fileService.onDidChangeFileSystemProviderRegistrations(e => this.onLabelEvent(e.scheme)));
this._register(this.fileService.onDidChangeFileSystemProviderCapabilities(e => this.onLabelEvent(e.scheme)));
}
private onLabelEvent(scheme: string): void {
if (scheme === this.resource.scheme) {
// Clear any cached labels from before
TextResourceEditorInput.MEMOIZER.clear();
// Trigger recompute of label
this._onDidChangeLabel.fire();
}
}
getName(): string {
@@ -687,10 +684,6 @@ export abstract class TextResourceEditorInput extends EditorInput {
return false; // untitled is never readonly
}
if (!this.fileService.canHandleResource(this.resource)) {
return true; // resources without file support are always readonly
}
return this.fileService.hasCapability(this.resource, FileSystemProviderCapabilities.Readonly);
}
@@ -729,14 +722,14 @@ export abstract class TextResourceEditorInput extends EditorInput {
}
if (!isEqual(target, this.resource)) {
return this.editorService.createInput({ resource: target });
return this.editorService.createEditorInput({ resource: target });
}
return this;
}
revert(group: GroupIdentifier, options?: IRevertOptions): Promise<boolean> {
return this.textFileService.revert(this.resource, options);
async revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void> {
await this.textFileService.revert(this.resource, options);
}
}
@@ -876,7 +869,7 @@ export class SideBySideEditorInput extends EditorInput {
return this.master.saveAs(group, options);
}
revert(group: GroupIdentifier, options?: IRevertOptions): Promise<boolean> {
revert(group: GroupIdentifier, options?: IRevertOptions): Promise<void> {
return this.master.revert(group, options);
}
@@ -1143,7 +1136,7 @@ export class TextEditorOptions extends EditorOptions implements ITextEditorOptio
*/
selectionRevealType: TextEditorSelectionRevealType | undefined;
static from(input?: IBaseResourceInput): TextEditorOptions | undefined {
static from(input?: IBaseResourceEditorInput): TextEditorOptions | undefined {
if (!input || !input.options) {
return undefined;
}
@@ -1197,7 +1190,7 @@ export class TextEditorOptions extends EditorOptions implements ITextEditorOptio
/**
* Create a TextEditorOptions inline to be used when the editor is opening.
*/
static fromEditor(editor: ICodeEditor, settings?: IEditorOptions): TextEditorOptions {
static fromEditor(editor: IEditor, settings?: IEditorOptions): TextEditorOptions {
const options = TextEditorOptions.create(settings);
// View state
@@ -1211,7 +1204,7 @@ export class TextEditorOptions extends EditorOptions implements ITextEditorOptio
*
* @return if something was applied
*/
apply(editor: ICodeEditor, scrollType: ScrollType): boolean {
apply(editor: IEditor, scrollType: ScrollType): boolean {
let gotApplied = false;
// First try viewstate
@@ -1380,7 +1373,7 @@ export interface IEditorMemento<T> {
class EditorInputFactoryRegistry implements IEditorInputFactoryRegistry {
private instantiationService: IInstantiationService | undefined;
private fileInputFactory: IFileInputFactory | undefined;
private fileEditorInputFactory: IFileEditorInputFactory | undefined;
private readonly editorInputFactoryConstructors: Map<string, IConstructorSignature0<IEditorInputFactory>> = new Map();
private readonly editorInputFactoryInstances: Map<string, IEditorInputFactory> = new Map();
@@ -1400,12 +1393,12 @@ class EditorInputFactoryRegistry implements IEditorInputFactoryRegistry {
this.editorInputFactoryInstances.set(editorInputId, instance);
}
registerFileInputFactory(factory: IFileInputFactory): void {
this.fileInputFactory = factory;
registerFileEditorInputFactory(factory: IFileEditorInputFactory): void {
this.fileEditorInputFactory = factory;
}
getFileInputFactory(): IFileInputFactory {
return assertIsDefined(this.fileInputFactory);
getFileEditorInputFactory(): IFileEditorInputFactory {
return assertIsDefined(this.fileEditorInputFactory);
}
registerEditorInputFactory(editorInputId: string, ctor: IConstructorSignature0<IEditorInputFactory>): IDisposable {
@@ -1433,7 +1426,7 @@ export const Extensions = {
Registry.add(Extensions.EditorInputFactories, new EditorInputFactoryRegistry());
export async function pathsToEditors(paths: IPathData[] | undefined, fileService: IFileService): Promise<(IResourceInput | IUntitledTextResourceInput)[]> {
export async function pathsToEditors(paths: IPathData[] | undefined, fileService: IFileService): Promise<(IResourceEditorInput | IUntitledTextResourceEditorInput)[]> {
if (!paths || !paths.length) {
return [];
}
@@ -1454,7 +1447,7 @@ export async function pathsToEditors(paths: IPathData[] | undefined, fileService
pinned: true
} : { pinned: true };
let input: IResourceInput | IUntitledTextResourceInput;
let input: IResourceEditorInput | IUntitledTextResourceEditorInput;
if (!exists) {
input = { resource, options, forceUntitled: true };
} else {

View File

@@ -23,18 +23,10 @@ export class DiffEditorModel extends EditorModel {
}
get originalModel(): IEditorModel | null {
if (!this._originalModel) {
return null;
}
return this._originalModel;
}
get modifiedModel(): IEditorModel | null {
if (!this._modifiedModel) {
return null;
}
return this._modifiedModel;
}

View File

@@ -94,7 +94,7 @@ export class ResourceEditorInput extends TextResourceEditorInput implements IMod
ref.dispose();
this.modelReference = undefined;
throw new Error(`Unexpected model for ResourceInput: ${this.resource}`);
throw new Error(`Unexpected model for ResourcEditorInput: ${this.resource}`);
}
this.cachedModel = model;

View File

@@ -87,4 +87,4 @@ class ScopedMemento {
this.storageService.remove(this.id, this.scope);
}
}
}
}

View File

@@ -41,8 +41,26 @@ export interface INotificationsModel {
}
export const enum NotificationChangeType {
/**
* A notification was added.
*/
ADD,
/**
* A notification changed. Check `detail` property
* on the event for additional information.
*/
CHANGE,
/**
* A notification expanded or collapsed.
*/
EXPAND_COLLAPSE,
/**
* A notification was removed.
*/
REMOVE
}
@@ -62,6 +80,12 @@ export interface INotificationChangeEvent {
* The kind of notification change.
*/
kind: NotificationChangeType;
/**
* Additional detail about the item change. Only applies to
* `NotificationChangeType.CHANGE`.
*/
detail?: NotificationViewItemContentChangeKind
}
export const enum StatusMessageChangeType {
@@ -206,26 +230,19 @@ export class NotificationsModel extends Disposable implements INotificationsMode
}
// Item Events
const onItemChangeEvent = () => {
const fireNotificationChangeEvent = (kind: NotificationChangeType, detail?: NotificationViewItemContentChangeKind) => {
const index = this._notifications.indexOf(item);
if (index >= 0) {
this._onDidChangeNotification.fire({ item, index, kind: NotificationChangeType.CHANGE });
this._onDidChangeNotification.fire({ item, index, kind, detail });
}
};
const itemExpansionChangeListener = item.onDidChangeExpansion(() => onItemChangeEvent());
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) {
onItemChangeEvent();
}
});
const itemExpansionChangeListener = item.onDidChangeExpansion(() => fireNotificationChangeEvent(NotificationChangeType.EXPAND_COLLAPSE));
const itemContentChangeListener = item.onDidChangeContent(e => fireNotificationChangeEvent(NotificationChangeType.CHANGE, e.kind));
Event.once(item.onDidClose)(() => {
itemExpansionChangeListener.dispose();
itemLabelChangeListener.dispose();
itemContentChangeListener.dispose();
const index = this._notifications.indexOf(item);
if (index >= 0) {
@@ -272,9 +289,9 @@ export interface INotificationViewItem {
readonly hasProgress: boolean;
readonly onDidChangeExpansion: Event<void>;
readonly onDidClose: Event<void>;
readonly onDidChangeVisibility: Event<boolean>;
readonly onDidChangeLabel: Event<INotificationViewItemLabelChangeEvent>;
readonly onDidChangeContent: Event<INotificationViewItemContentChangeEvent>;
readonly onDidClose: Event<void>;
expand(): void;
collapse(skipEvents?: boolean): void;
@@ -295,15 +312,15 @@ export function isNotificationViewItem(obj: unknown): obj is INotificationViewIt
return obj instanceof NotificationViewItem;
}
export const enum NotificationViewItemLabelKind {
export const enum NotificationViewItemContentChangeKind {
SEVERITY,
MESSAGE,
ACTIONS,
PROGRESS
}
export interface INotificationViewItemLabelChangeEvent {
kind: NotificationViewItemLabelKind;
export interface INotificationViewItemContentChangeEvent {
kind: NotificationViewItemContentChangeKind;
}
export interface INotificationViewItemProgressState {
@@ -420,8 +437,8 @@ export class NotificationViewItem extends Disposable implements INotificationVie
private readonly _onDidClose = this._register(new Emitter<void>());
readonly onDidClose = this._onDidClose.event;
private readonly _onDidChangeLabel = this._register(new Emitter<INotificationViewItemLabelChangeEvent>());
readonly onDidChangeLabel = this._onDidChangeLabel.event;
private readonly _onDidChangeContent = this._register(new Emitter<INotificationViewItemContentChangeEvent>());
readonly onDidChangeContent = this._onDidChangeContent.event;
private readonly _onDidChangeVisibility = this._register(new Emitter<boolean>());
readonly onDidChangeVisibility = this._onDidChangeVisibility.event;
@@ -512,20 +529,16 @@ export class NotificationViewItem extends Disposable implements INotificationVie
}
private setActions(actions: INotificationActions = { primary: [], secondary: [] }): void {
if (!Array.isArray(actions.primary)) {
actions.primary = [];
}
this._actions = {
primary: Array.isArray(actions.primary) ? actions.primary : [],
secondary: Array.isArray(actions.secondary) ? actions.secondary : []
};
if (!Array.isArray(actions.secondary)) {
actions.secondary = [];
}
this._actions = actions;
this._expanded = actions.primary.length > 0;
this._expanded = actions.primary && actions.primary.length > 0;
}
get canCollapse(): boolean {
return !this.hasPrompt;
return !this.hasActions;
}
get expanded(): boolean {
@@ -541,11 +554,11 @@ export class NotificationViewItem extends Disposable implements INotificationVie
return true; // explicitly sticky
}
const hasPrompt = this.hasPrompt;
const hasActions = this.hasActions;
if (
(hasPrompt && this._severity === Severity.Error) || // notification errors with actions are sticky
(!hasPrompt && this._expanded) || // notifications that got expanded are sticky
(this._progress && !this._progress.state.done) // notifications with running progress are sticky
(hasActions && this._severity === Severity.Error) || // notification errors with actions are sticky
(!hasActions && this._expanded) || // notifications that got expanded are sticky
(this._progress && !this._progress.state.done) // notifications with running progress are sticky
) {
return true;
}
@@ -557,7 +570,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie
return !!this._silent;
}
private get hasPrompt(): boolean {
private get hasActions(): boolean {
if (!this._actions) {
return false;
}
@@ -576,7 +589,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._onDidChangeLabel.fire({ kind: NotificationViewItemLabelKind.PROGRESS })));
this._register(this._progress.onDidChange(() => this._onDidChangeContent.fire({ kind: NotificationViewItemContentChangeKind.PROGRESS })));
}
return this._progress;
@@ -596,7 +609,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie
updateSeverity(severity: Severity): void {
this._severity = severity;
this._onDidChangeLabel.fire({ kind: NotificationViewItemLabelKind.SEVERITY });
this._onDidChangeContent.fire({ kind: NotificationViewItemContentChangeKind.SEVERITY });
}
updateMessage(input: NotificationMessage): void {
@@ -606,13 +619,12 @@ export class NotificationViewItem extends Disposable implements INotificationVie
}
this._message = message;
this._onDidChangeLabel.fire({ kind: NotificationViewItemLabelKind.MESSAGE });
this._onDidChangeContent.fire({ kind: NotificationViewItemContentChangeKind.MESSAGE });
}
updateActions(actions?: INotificationActions): void {
this.setActions(actions);
this._onDidChangeLabel.fire({ kind: NotificationViewItemLabelKind.ACTIONS });
this._onDidChangeContent.fire({ kind: NotificationViewItemContentChangeKind.ACTIONS });
}
updateVisibility(visible: boolean): void {

View File

@@ -5,13 +5,12 @@
import * as nls from 'vs/nls';
import { registerColor, editorBackground, contrastBorder, transparent, editorWidgetBackground, textLinkForeground, lighten, darken, focusBorder, activeContrastBorder, editorWidgetForeground, editorErrorForeground, editorWarningForeground, editorInfoForeground } from 'vs/platform/theme/common/colorRegistry';
import { Disposable } from 'vs/base/common/lifecycle';
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
import { IColorTheme } from 'vs/platform/theme/common/themeService';
import { Color } from 'vs/base/common/color';
// < --- Workbench (not customizable) --- >
export function WORKBENCH_BACKGROUND(theme: ITheme): Color {
export function WORKBENCH_BACKGROUND(theme: IColorTheme): Color {
switch (theme.type) {
case 'dark':
return Color.fromHex('#252526');
@@ -461,20 +460,6 @@ export const SIDE_BAR_SECTION_HEADER_BORDER = registerColor('sideBarSectionHeade
}, nls.localize('sideBarSectionHeaderBorder', "Side bar section header border color. The side bar is the container for views like explorer and search."));
// < --- Quick Input -- >
export const QUICK_INPUT_BACKGROUND = registerColor('quickInput.background', {
dark: SIDE_BAR_BACKGROUND,
light: SIDE_BAR_BACKGROUND,
hc: SIDE_BAR_BACKGROUND
}, nls.localize('quickInputBackground', "Quick Input background color. The Quick Input widget is the container for views like the color theme picker."));
export const QUICK_INPUT_FOREGROUND = registerColor('quickInput.foreground', {
dark: SIDE_BAR_FOREGROUND,
light: SIDE_BAR_FOREGROUND,
hc: SIDE_BAR_FOREGROUND
}, nls.localize('quickInputForeground', "Quick Input foreground color. The Quick Input widget is the container for views like the color theme picker."));
// < --- Title Bar --- >
export const TITLE_BAR_ACTIVE_FOREGROUND = registerColor('titleBar.activeForeground', {
@@ -606,41 +591,3 @@ export const WINDOW_INACTIVE_BORDER = registerColor('window.inactiveBorder', {
light: null,
hc: contrastBorder
}, nls.localize('windowInactiveBorder', "The color used for the border of the window when it is inactive. Only supported in the desktop client when using the custom title bar."));
/**
* Base class for all themable workbench components.
*/
export class Themable extends Disposable {
protected theme: ITheme;
constructor(
protected themeService: IThemeService
) {
super();
this.theme = themeService.getTheme();
// Hook up to theme changes
this._register(this.themeService.onThemeChange(theme => this.onThemeChange(theme)));
}
protected onThemeChange(theme: ITheme): void {
this.theme = theme;
this.updateStyles();
}
protected updateStyles(): void {
// Subclasses to override
}
protected getColor(id: string, modify?: (color: Color, theme: ITheme) => Color): string | null {
let color = this.theme.getColor(id);
if (color && modify) {
color = modify(color, this.theme);
}
return color ? color.toString() : null;
}
}

View File

@@ -6,7 +6,7 @@
import { Command } from 'vs/editor/common/modes';
import { UriComponents, URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { RawContextKey, ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey';
import { localize } from 'vs/nls';
import { IViewlet } from 'vs/workbench/common/viewlet';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
@@ -20,6 +20,7 @@ import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { flatten, mergeSort } from 'vs/base/common/arrays';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { SetMap } from 'vs/base/common/collections';
import { IProgressIndicator } from 'vs/platform/progress/common/progress';
export const TEST_VIEW_CONTAINER_ID = 'workbench.view.extension.test';
@@ -178,7 +179,7 @@ export interface IViewDescriptor {
readonly ctorDescriptor: SyncDescriptor<IView>;
readonly when?: ContextKeyExpr;
readonly when?: ContextKeyExpression;
readonly order?: number;
@@ -220,13 +221,13 @@ export enum ViewContentPriority {
export interface IViewContentDescriptor {
readonly content: string;
readonly when?: ContextKeyExpr | 'default';
readonly when?: ContextKeyExpression | 'default';
readonly priority?: ViewContentPriority;
/**
* ordered preconditions for each button in the content
*/
readonly preconditions?: (ContextKeyExpr | undefined)[];
readonly preconditions?: (ContextKeyExpression | undefined)[];
}
export interface IViewsRegistry {
@@ -262,7 +263,8 @@ function compareViewContentDescriptors(a: IViewContentDescriptor, b: IViewConten
return aPriority - bPriority;
}
return a.content < b.content ? -1 : 1;
// No priroity, keep views sorted in the order they got registered
return 0;
}
class ViewsRegistry extends Disposable implements IViewsRegistry {
@@ -401,6 +403,7 @@ export interface IView {
setExpanded(expanded: boolean): boolean;
getProgressIndicator(): IProgressIndicator | undefined;
}
export interface IViewsViewlet extends IViewlet {
@@ -425,6 +428,7 @@ export interface IViewsService {
closeView(id: string): void;
getProgressIndicator(id: string): IProgressIndicator | undefined;
}
/**
@@ -487,6 +491,8 @@ export interface ITreeView extends IDisposable {
readonly onDidChangeTitle: Event<string>;
readonly onDidChangeWelcomeState: Event<void>;
refresh(treeItems?: ITreeItem[]): Promise<void>;
setVisibility(visible: boolean): void;
@@ -505,9 +511,6 @@ export interface ITreeView extends IDisposable {
setFocus(item: ITreeItem): void;
getPrimaryActions(): IAction[];
getSecondaryActions(): IAction[];
}
export interface IRevealOptions {
@@ -573,7 +576,8 @@ export interface ITreeItem {
}
export interface ITreeViewDataProvider {
readonly isTreeEmpty?: boolean;
onDidChangeEmpty?: Event<void>;
getChildren(element?: ITreeItem): Promise<ITreeItem[]>;
}
@@ -601,4 +605,3 @@ export interface IViewPaneContainer {
getView(viewId: string): IView | undefined;
saveState(): void;
}