Merge from vscode 731f9c25632dbbf01ee3a7892ad9d2791fe0260c

This commit is contained in:
ADS Merger
2020-07-24 05:27:34 +00:00
parent eccf3cf5fe
commit d965d4aef3
145 changed files with 3072 additions and 1550 deletions

View File

@@ -32,9 +32,9 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag
import { Color } from 'vs/base/common/color';
import { TreeMouseEventTarget, ITreeNode } from 'vs/base/browser/ui/tree/tree';
import { URI } from 'vs/base/common/uri';
import { MenuId, IMenuService, MenuItemAction } from 'vs/platform/actions/common/actions';
import { MenuId, IMenuService } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { createAndFillInActionBarActions, MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
const enum State {
Loading = 'loading',
@@ -94,7 +94,7 @@ export class CallHierarchyTreePeekWidget extends peekView.PeekViewWidget {
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
) {
super(editor, { showFrame: true, showArrow: true, isResizeable: true, isAccessible: true });
super(editor, { showFrame: true, showArrow: true, isResizeable: true, isAccessible: true }, _instantiationService);
this.create();
this._peekViewService.addExclusiveWidget(editor, this);
this._applyTheme(themeService.getColorTheme());
@@ -142,8 +142,8 @@ export class CallHierarchyTreePeekWidget extends peekView.PeekViewWidget {
protected _getActionBarOptions(): IActionBarOptions {
return {
orientation: ActionsOrientation.HORIZONTAL,
actionViewItemProvider: action => action instanceof MenuItemAction ? this._instantiationService.createInstance(MenuEntryActionViewItem, action) : undefined
...super._getActionBarOptions(),
orientation: ActionsOrientation.HORIZONTAL
};
}

View File

@@ -6,8 +6,8 @@
import * as nls from 'vs/nls';
import * as dom from 'vs/base/browser/dom';
import * as modes from 'vs/editor/common/modes';
import { ActionsOrientation, ActionViewItem, ActionBar, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action, IActionRunner, IAction } from 'vs/base/common/actions';
import { ActionsOrientation, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action, IActionRunner, IAction, Separator } from 'vs/base/common/actions';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { ITextModel } from 'vs/editor/common/model';
@@ -23,17 +23,17 @@ import { Emitter, Event } from 'vs/base/common/event';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdown';
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
import { ToggleReactionsAction, ReactionAction, ReactionActionViewItem } from './reactionsAction';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { ICommentThreadWidget } from 'vs/workbench/contrib/comments/common/commentThreadWidget';
import { MenuItemAction, SubmenuItemAction, IMenu } from 'vs/platform/actions/common/actions';
import { ContextAwareMenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { MenuEntryActionViewItem, SubmenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { CommentFormActions } from 'vs/workbench/contrib/comments/browser/commentFormActions';
import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from 'vs/base/browser/ui/mouseCursor/mouseCursor';
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
import { DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdownActionViewItem';
export class CommentNode extends Disposable {
private _domNode: HTMLElement;
@@ -79,7 +79,6 @@ export class CommentNode extends Disposable {
@ICommentService private commentService: ICommentService,
@IModelService private modelService: IModelService,
@IModeService private modeService: IModeService,
@IKeybindingService private keybindingService: IKeybindingService,
@INotificationService private notificationService: INotificationService,
@IContextMenuService private contextMenuService: IContextMenuService,
@IContextKeyService contextKeyService: IContextKeyService
@@ -154,13 +153,12 @@ export class CommentNode extends Disposable {
action,
(<ToggleReactionsAction>action).menuActions,
this.contextMenuService,
action => {
return this.actionViewItemProvider(action as Action);
},
this.actionRunner!,
undefined,
'toolbar-toggle-pickReactions codicon codicon-reactions',
() => { return AnchorAlignment.RIGHT; }
{
actionViewItemProvider: action => this.actionViewItemProvider(action as Action),
actionRunner: this.actionRunner,
classNames: ['toolbar-toggle-pickReactions', 'codicon', 'codicon-reactions'],
anchorAlignmentProvider: () => AnchorAlignment.RIGHT
}
);
}
return this.actionViewItemProvider(action as Action);
@@ -221,8 +219,9 @@ export class CommentNode extends Disposable {
let item = new ReactionActionViewItem(action);
return item;
} else if (action instanceof MenuItemAction) {
let item = new ContextAwareMenuEntryActionViewItem(action, this.keybindingService, this.notificationService, this.contextMenuService);
return item;
return this.instantiationService.createInstance(MenuEntryActionViewItem, action);
} else if (action instanceof SubmenuItemAction) {
return this.instantiationService.createInstance(SubmenuEntryActionViewItem, action);
} else {
let item = new ActionViewItem({}, action, options);
return item;
@@ -259,16 +258,17 @@ export class CommentNode extends Disposable {
toggleReactionAction,
(<ToggleReactionsAction>toggleReactionAction).menuActions,
this.contextMenuService,
action => {
if (action.id === ToggleReactionsAction.ID) {
return toggleReactionActionViewItem;
}
return this.actionViewItemProvider(action as Action);
},
this.actionRunner!,
undefined,
'toolbar-toggle-pickReactions',
() => { return AnchorAlignment.RIGHT; }
{
actionViewItemProvider: action => {
if (action.id === ToggleReactionsAction.ID) {
return toggleReactionActionViewItem;
}
return this.actionViewItemProvider(action as Action);
},
actionRunner: this.actionRunner,
classNames: 'toolbar-toggle-pickReactions',
anchorAlignmentProvider: () => AnchorAlignment.RIGHT
}
);
return toggleReactionAction;
@@ -283,13 +283,12 @@ export class CommentNode extends Disposable {
action,
(<ToggleReactionsAction>action).menuActions,
this.contextMenuService,
action => {
return this.actionViewItemProvider(action as Action);
},
this.actionRunner!,
undefined,
'toolbar-toggle-pickReactions',
() => { return AnchorAlignment.RIGHT; }
{
actionViewItemProvider: action => this.actionViewItemProvider(action as Action),
actionRunner: this.actionRunner,
classNames: 'toolbar-toggle-pickReactions',
anchorAlignmentProvider: () => AnchorAlignment.RIGHT
}
);
}
return this.actionViewItemProvider(action as Action);

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as dom from 'vs/base/browser/dom';
import { ActionBar, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action, IAction } from 'vs/base/common/actions';
import * as arrays from 'vs/base/common/arrays';
import { Color } from 'vs/base/common/color';
@@ -26,13 +26,10 @@ import { MarkdownRenderer } from 'vs/editor/contrib/markdown/markdownRenderer';
import { peekViewBorder } from 'vs/editor/contrib/peekView/peekView';
import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/zoneWidget';
import * as nls from 'vs/nls';
import { ContextAwareMenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { MenuEntryActionViewItem, SubmenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenu, MenuItemAction, SubmenuItemAction } from 'vs/platform/actions/common/actions';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { contrastBorder, editorForeground, focusBorder, inputValidationErrorBackground, inputValidationErrorBorder, inputValidationErrorForeground, textBlockQuoteBackground, textBlockQuoteBorder, textLinkActiveForeground, textLinkForeground, transparent } from 'vs/platform/theme/common/colorRegistry';
import { IColorTheme, IThemeService } from 'vs/platform/theme/common/themeService';
@@ -49,6 +46,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from 'vs/base/browser/ui/mouseCursor/mouseCursor';
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
export const COMMENTEDITOR_DECORATION_KEY = 'commenteditordecoration';
const COLLAPSE_ACTION_CLASS = 'expand-review-action codicon-chevron-up';
@@ -109,15 +107,12 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
private _owner: string,
private _commentThread: modes.CommentThread,
private _pendingComment: string | null,
@IInstantiationService instantiationService: IInstantiationService,
@IInstantiationService private instantiationService: IInstantiationService,
@IModeService private modeService: IModeService,
@IModelService private modelService: IModelService,
@IThemeService private themeService: IThemeService,
@ICommentService private commentService: ICommentService,
@IOpenerService private openerService: IOpenerService,
@IKeybindingService private keybindingService: IKeybindingService,
@INotificationService private notificationService: INotificationService,
@IContextMenuService private contextMenuService: IContextMenuService,
@IContextKeyService contextKeyService: IContextKeyService
) {
super(editor, { keepEditorSelection: true });
@@ -239,11 +234,11 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
this._actionbarWidget = new ActionBar(actionsContainer, {
actionViewItemProvider: (action: IAction) => {
if (action instanceof MenuItemAction) {
let item = new ContextAwareMenuEntryActionViewItem(action, this.keybindingService, this.notificationService, this.contextMenuService);
return item;
return this.instantiationService.createInstance(MenuEntryActionViewItem, action);
} else if (action instanceof SubmenuItemAction) {
return this.instantiationService.createInstance(SubmenuEntryActionViewItem, action);
} else {
let item = new ActionViewItem({}, action, { label: false, icon: true });
return item;
return new ActionViewItem({}, action, { label: false, icon: true });
}
}
});

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ContextSubMenu } from 'vs/base/browser/contextmenu';
import { $ } from 'vs/base/browser/dom';
import { Action, IAction } from 'vs/base/common/actions';
import { coalesce, findFirstInSorted } from 'vs/base/common/arrays';
@@ -547,8 +546,8 @@ export class CommentController implements IEditorContribution {
return picks;
}
private getContextMenuActions(commentInfos: { ownerId: string, extensionId: string | undefined, label: string | undefined, commentingRangesInfo: modes.CommentingRanges }[], lineNumber: number): (IAction | ContextSubMenu)[] {
const actions: (IAction | ContextSubMenu)[] = [];
private getContextMenuActions(commentInfos: { ownerId: string, extensionId: string | undefined, label: string | undefined, commentingRangesInfo: modes.CommentingRanges }[], lineNumber: number): IAction[] {
const actions: IAction[] = [];
commentInfos.forEach(commentInfo => {
const { ownerId, extensionId, label } = commentInfo;

View File

@@ -5,9 +5,9 @@
import * as nls from 'vs/nls';
import * as dom from 'vs/base/browser/dom';
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action, IAction } from 'vs/base/common/actions';
import { URI, UriComponents } from 'vs/base/common/uri';
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
export class ToggleReactionsAction extends Action {
static readonly ID = 'toolbar.toggle.pickReactions';

View File

@@ -8,7 +8,7 @@ import * as env from 'vs/base/common/platform';
import * as dom from 'vs/base/browser/dom';
import { URI } from 'vs/base/common/uri';
import severity from 'vs/base/common/severity';
import { IAction, Action } from 'vs/base/common/actions';
import { IAction, Action, SubmenuAction } from 'vs/base/common/actions';
import { Range } from 'vs/editor/common/core/range';
import { ICodeEditor, IEditorMouseEvent, MouseTargetType, IContentWidget, IActiveCodeEditor, IContentWidgetPosition, ContentWidgetPositionPreference } from 'vs/editor/browser/editorBrowser';
import { IModelDecorationOptions, IModelDeltaDecoration, TrackedRangeStickiness, ITextModel, OverviewRulerLane, IModelDecorationOverviewRulerOptions } from 'vs/editor/common/model';
@@ -18,7 +18,6 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { RemoveBreakpointAction } from 'vs/workbench/contrib/debug/browser/debugActions';
import { IDebugService, IBreakpoint, CONTEXT_BREAKPOINT_WIDGET_VISIBLE, BreakpointWidgetContext, IBreakpointEditorContribution, IBreakpointUpdateData, IDebugConfiguration, State, IDebugSession } from 'vs/workbench/contrib/debug/common/debug';
import { IMarginData } from 'vs/editor/browser/controller/mouseTarget';
import { ContextSubMenu } from 'vs/base/browser/contextmenu';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { BreakpointWidget } from 'vs/workbench/contrib/debug/browser/breakpointWidget';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
@@ -288,8 +287,8 @@ export class BreakpointEditorContribution implements IBreakpointEditorContributi
}));
}
private getContextMenuActions(breakpoints: ReadonlyArray<IBreakpoint>, uri: URI, lineNumber: number, column?: number): Array<IAction | ContextSubMenu> {
const actions: Array<IAction | ContextSubMenu> = [];
private getContextMenuActions(breakpoints: ReadonlyArray<IBreakpoint>, uri: URI, lineNumber: number, column?: number): IAction[] {
const actions: IAction[] = [];
if (breakpoints.length === 1) {
const breakpointType = breakpoints[0].logMessage ? nls.localize('logPoint', "Logpoint") : nls.localize('breakpoint', "Breakpoint");
actions.push(new RemoveBreakpointAction(RemoveBreakpointAction.ID, nls.localize('removeBreakpoint', "Remove {0}", breakpointType), this.debugService));
@@ -310,7 +309,7 @@ export class BreakpointEditorContribution implements IBreakpointEditorContributi
));
} else if (breakpoints.length > 1) {
const sorted = breakpoints.slice().sort((first, second) => (first.column && second.column) ? first.column - second.column : 1);
actions.push(new ContextSubMenu(nls.localize('removeBreakpoints', "Remove Breakpoints"), sorted.map(bp => new Action(
actions.push(new SubmenuAction('debug.removeBreakpoints', nls.localize('removeBreakpoints', "Remove Breakpoints"), sorted.map(bp => new Action(
'removeInlineBreakpoint',
bp.column ? nls.localize('removeInlineBreakpointOnColumn', "Remove Inline Breakpoint on Column {0}", bp.column) : nls.localize('removeLineBreakpoint', "Remove Line Breakpoint"),
undefined,
@@ -318,7 +317,7 @@ export class BreakpointEditorContribution implements IBreakpointEditorContributi
() => this.debugService.removeBreakpoints(bp.getId())
))));
actions.push(new ContextSubMenu(nls.localize('editBreakpoints', "Edit Breakpoints"), sorted.map(bp =>
actions.push(new SubmenuAction('debug.editBReakpoints', nls.localize('editBreakpoints', "Edit Breakpoints"), sorted.map(bp =>
new Action('editBreakpoint',
bp.column ? nls.localize('editInlineBreakpointOnColumn', "Edit Inline Breakpoint on Column {0}", bp.column) : nls.localize('editLineBrekapoint', "Edit Line Breakpoint"),
undefined,
@@ -327,7 +326,7 @@ export class BreakpointEditorContribution implements IBreakpointEditorContributi
)
)));
actions.push(new ContextSubMenu(nls.localize('enableDisableBreakpoints', "Enable/Disable Breakpoints"), sorted.map(bp => new Action(
actions.push(new SubmenuAction('debug.enableDisableBreakpoints', nls.localize('enableDisableBreakpoints', "Enable/Disable Breakpoints"), sorted.map(bp => new Action(
bp.enabled ? 'disableColumnBreakpoint' : 'enableColumnBreakpoint',
bp.enabled ? (bp.column ? nls.localize('disableInlineColumnBreakpoint', "Disable Inline Breakpoint on Column {0}", bp.column) : nls.localize('disableBreakpointOnLine', "Disable Line Breakpoint"))
: (bp.column ? nls.localize('enableBreakpoints', "Enable Inline Breakpoint on Column {0}", bp.column) : nls.localize('enableBreakpointOnLine', "Enable Line Breakpoint")),
@@ -548,7 +547,7 @@ class InlineBreakpointWidget implements IContentWidget, IDisposable {
private readonly breakpoint: IBreakpoint | undefined,
private readonly debugService: IDebugService,
private readonly contextMenuService: IContextMenuService,
private readonly getContextMenuActions: () => ReadonlyArray<IAction | ContextSubMenu>
private readonly getContextMenuActions: () => IAction[]
) {
this.range = this.editor.getModel().getDecorationRange(decorationId);
this.toDispose.push(this.editor.onDidChangeModelDecorations(() => {

View File

@@ -6,7 +6,7 @@
import * as nls from 'vs/nls';
import * as resources from 'vs/base/common/resources';
import * as dom from 'vs/base/browser/dom';
import { IAction, Action } from 'vs/base/common/actions';
import { IAction, Action, Separator } from 'vs/base/common/actions';
import { IDebugService, IBreakpoint, CONTEXT_BREAKPOINTS_FOCUSED, State, DEBUG_SCHEME, IFunctionBreakpoint, IExceptionBreakpoint, IEnablement, BREAKPOINT_EDITOR_CONTRIBUTION_ID, IBreakpointEditorContribution, IDebugModel, IDataBreakpoint } from 'vs/workbench/contrib/debug/common/debug';
import { ExceptionBreakpoint, FunctionBreakpoint, Breakpoint, DataBreakpoint } from 'vs/workbench/contrib/debug/common/debugModel';
import { AddFunctionBreakpointAction, ToggleBreakpointsActivatedAction, RemoveAllBreakpointsAction, RemoveBreakpointAction, EnableAllBreakpointsAction, DisableAllBreakpointsAction, ReapplyBreakpointsAction } from 'vs/workbench/contrib/debug/browser/debugActions';
@@ -16,7 +16,6 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { Constants } from 'vs/base/common/uint';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { IListVirtualDelegate, IListContextMenuEvent, IListRenderer } from 'vs/base/browser/ui/list/list';
import { IEditorPane } from 'vs/workbench/common/editor';
import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';

View File

@@ -11,7 +11,7 @@ import { IDebugService, State, IStackFrame, IDebugSession, IThread, CONTEXT_CALL
import { Thread, StackFrame, ThreadAndSessionIds } from 'vs/workbench/contrib/debug/common/debugModel';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { MenuId, IMenu, IMenuService, MenuItemAction } from 'vs/platform/actions/common/actions';
import { MenuId, IMenu, IMenuService, MenuItemAction, SubmenuItemAction } from 'vs/platform/actions/common/actions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { renderViewTree } from 'vs/workbench/contrib/debug/browser/baseDebugView';
import { IAction, Action } from 'vs/base/common/actions';
@@ -21,7 +21,7 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/c
import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';
import { ILabelService } from 'vs/platform/label/common/label';
import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
import { createAndFillInContextMenuActions, createAndFillInActionBarActions, MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { createAndFillInContextMenuActions, createAndFillInActionBarActions, MenuEntryActionViewItem, SubmenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { ITreeNode, ITreeContextMenuEvent, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
import { WorkbenchCompressibleAsyncDataTree } from 'vs/platform/list/browser/listService';
@@ -489,10 +489,7 @@ class SessionsRenderer implements ICompressibleTreeRenderer<IDebugSession, Fuzzy
constructor(
private menu: IMenu,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IDebugService private readonly debugService: IDebugService,
@IKeybindingService private readonly keybindingService: IKeybindingService,
@INotificationService private readonly notificationService: INotificationService,
@IContextMenuService private readonly contextMenuService: IContextMenuService
@IDebugService private readonly debugService: IDebugService
) { }
get templateId(): string {
@@ -509,8 +506,9 @@ class SessionsRenderer implements ICompressibleTreeRenderer<IDebugSession, Fuzzy
const actionBar = new ActionBar(session, {
actionViewItemProvider: action => {
if (action instanceof MenuItemAction) {
// We need the MenuEntryActionViewItem so the icon would get rendered
return new MenuEntryActionViewItem(action, this.keybindingService, this.notificationService, this.contextMenuService);
return this.instantiationService.createInstance(MenuEntryActionViewItem, action);
} else if (action instanceof SubmenuItemAction) {
return this.instantiationService.createInstance(SubmenuEntryActionViewItem, action);
}
return undefined;

View File

@@ -4,12 +4,11 @@
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { IAction, IActionRunner } from 'vs/base/common/actions';
import { IAction, IActionRunner, IActionViewItem } from 'vs/base/common/actions';
import { KeyCode } from 'vs/base/common/keyCodes';
import * as dom from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { SelectBox, ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox';
import { SelectActionViewItem, IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IDebugService, IDebugSession, IDebugConfiguration, IConfig, ILaunch } from 'vs/workbench/contrib/debug/common/debug';
@@ -20,6 +19,7 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ADD_CONFIGURATION_ID } from 'vs/workbench/contrib/debug/browser/debugCommands';
import { SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
const $ = dom.$;

View File

@@ -9,8 +9,8 @@ import * as browser from 'vs/base/browser/browser';
import * as dom from 'vs/base/browser/dom';
import * as arrays from 'vs/base/common/arrays';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { IAction, IRunEvent, WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from 'vs/base/common/actions';
import { ActionBar, ActionsOrientation, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { IAction, IRunEvent, WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification, Separator } from 'vs/base/common/actions';
import { ActionBar, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IDebugConfiguration, IDebugService, State } from 'vs/workbench/contrib/debug/common/debug';
@@ -21,13 +21,12 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { registerThemingParticipant, IThemeService, Themable } from 'vs/platform/theme/common/themeService';
import { registerColor, contrastBorder, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
import { localize } from 'vs/nls';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { RunOnceScheduler } from 'vs/base/common/async';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { createAndFillInActionBarActions, MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenu, IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { createAndFillInActionBarActions, MenuEntryActionViewItem, SubmenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenu, IMenuService, MenuId, MenuItemAction, SubmenuItemAction } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { FocusSessionAction } from 'vs/workbench/contrib/debug/browser/debugActions';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
@@ -57,7 +56,6 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution {
@IStorageService private readonly storageService: IStorageService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IThemeService themeService: IThemeService,
@IKeybindingService private readonly keybindingService: IKeybindingService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IMenuService menuService: IMenuService,
@IContextMenuService contextMenuService: IContextMenuService,
@@ -80,9 +78,10 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution {
actionViewItemProvider: (action: IAction) => {
if (action.id === FocusSessionAction.ID) {
return this.instantiationService.createInstance(FocusSessionActionViewItem, action);
}
if (action instanceof MenuItemAction) {
return new MenuEntryActionViewItem(action, this.keybindingService, this.notificationService, contextMenuService);
} else if (action instanceof MenuItemAction) {
return this.instantiationService.createInstance(MenuEntryActionViewItem, action);
} else if (action instanceof SubmenuItemAction) {
return this.instantiationService.createInstance(SubmenuEntryActionViewItem, action);
}
return undefined;

View File

@@ -5,9 +5,8 @@
import 'vs/css!./media/debugViewlet';
import * as nls from 'vs/nls';
import { IAction } from 'vs/base/common/actions';
import { IAction, IActionViewItem } from 'vs/base/common/actions';
import * as DOM from 'vs/base/browser/dom';
import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IDebugService, VIEWLET_ID, State, BREAKPOINTS_VIEW_ID, IDebugConfiguration, CONTEXT_DEBUG_UX, CONTEXT_DEBUG_UX_KEY, REPL_VIEW_ID } from 'vs/workbench/contrib/debug/common/debug';
import { StartAction, ConfigureAction, SelectAndStartAction, FocusSessionAction } from 'vs/workbench/contrib/debug/browser/debugActions';
import { StartDebugActionViewItem, FocusSessionActionViewItem } from 'vs/workbench/contrib/debug/browser/debugActionViewItems';
@@ -24,12 +23,10 @@ import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/la
import { memoize } from 'vs/base/common/decorators';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { DebugToolBar } from 'vs/workbench/contrib/debug/browser/debugToolBar';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ViewPane, ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';
import { IMenu, MenuId, IMenuService, MenuItemAction } from 'vs/platform/actions/common/actions';
import { IMenu, MenuId, IMenuService, MenuItemAction, SubmenuItemAction } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { MenuEntryActionViewItem, SubmenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IViewDescriptorService, IViewsService } from 'vs/workbench/common/views';
import { WelcomeView } from 'vs/workbench/contrib/debug/browser/welcomeView';
import { ToggleViewAction } from 'vs/workbench/browser/actions/layoutActions';
@@ -55,11 +52,9 @@ export class DebugViewPaneContainer extends ViewPaneContainer {
@IContextMenuService contextMenuService: IContextMenuService,
@IExtensionService extensionService: IExtensionService,
@IConfigurationService configurationService: IConfigurationService,
@IKeybindingService private readonly keybindingService: IKeybindingService,
@IContextViewService private readonly contextViewService: IContextViewService,
@IMenuService private readonly menuService: IMenuService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@INotificationService private readonly notificationService: INotificationService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService
) {
super(VIEWLET_ID, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService);
@@ -165,7 +160,9 @@ export class DebugViewPaneContainer extends ViewPaneContainer {
return new FocusSessionActionViewItem(action, this.debugService, this.themeService, this.contextViewService, this.configurationService);
}
if (action instanceof MenuItemAction) {
return new MenuEntryActionViewItem(action, this.keybindingService, this.notificationService, this.contextMenuService);
return this.instantiationService.createInstance(MenuEntryActionViewItem, action);
} else if (action instanceof SubmenuItemAction) {
return this.instantiationService.createInstance(SubmenuEntryActionViewItem, action);
}
return undefined;

View File

@@ -38,7 +38,7 @@
cursor: grabbing;
}
.monaco-workbench .debug-toolbar .monaco-action-bar .action-item > .action-label {
.monaco-workbench .debug-toolbar .monaco-action-bar .action-item .action-label {
width: 32px;
height: 32px;
margin-right: 0;

View File

@@ -5,7 +5,7 @@
import 'vs/css!./media/repl';
import { URI as uri } from 'vs/base/common/uri';
import { IAction, IActionViewItem, Action } from 'vs/base/common/actions';
import { IAction, IActionViewItem, Action, Separator } from 'vs/base/common/actions';
import * as dom from 'vs/base/browser/dom';
import * as aria from 'vs/base/browser/ui/aria/aria';
import { CancellationToken } from 'vs/base/common/cancellation';
@@ -41,7 +41,6 @@ import { first } from 'vs/base/common/arrays';
import { ITreeNode, ITreeContextMenuEvent, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { removeAnsiEscapeCodes } from 'vs/base/common/strings';
import { WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService';
@@ -440,7 +439,7 @@ export class Repl extends ViewPane implements IHistoryNavigationWidget {
return this.instantiationService.createInstance(SelectReplActionViewItem, this.selectReplAction);
}
return undefined;
return super.getActionViewItem(action);
}
getActions(): IAction[] {

View File

@@ -13,9 +13,8 @@ import { Variable, Scope, ErrorScope, StackFrame } from 'vs/workbench/contrib/de
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { renderViewTree, renderVariable, IInputBoxOptions, AbstractExpressionsRenderer, IExpressionTemplateData } from 'vs/workbench/contrib/debug/browser/baseDebugView';
import { IAction, Action } from 'vs/base/common/actions';
import { IAction, Action, Separator } from 'vs/base/common/actions';
import { CopyValueAction } from 'vs/workbench/contrib/debug/browser/debugActions';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';
import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';

View File

@@ -14,8 +14,7 @@ import { AddWatchExpressionAction, RemoveAllWatchExpressionsAction, CopyValueAct
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IAction, Action } from 'vs/base/common/actions';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { IAction, Action, Separator } from 'vs/base/common/actions';
import { renderExpressionValue, renderViewTree, IInputBoxOptions, AbstractExpressionsRenderer, IExpressionTemplateData } from 'vs/workbench/contrib/debug/browser/baseDebugView';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';

View File

@@ -5,12 +5,11 @@
import 'vs/css!./media/extensionActions';
import { localize } from 'vs/nls';
import { IAction, Action } from 'vs/base/common/actions';
import { IAction, Action, Separator, SubmenuAction } from 'vs/base/common/actions';
import { Delayer } from 'vs/base/common/async';
import * as DOM from 'vs/base/browser/dom';
import { Event } from 'vs/base/common/event';
import * as json from 'vs/base/common/json';
import { ActionViewItem, Separator, IActionViewItemOptions } from 'vs/base/browser/ui/actionbar/actionbar';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { dispose, Disposable } from 'vs/base/common/lifecycle';
import { IExtension, ExtensionState, IExtensionsWorkbenchService, VIEWLET_ID, IExtensionsViewPaneContainer, AutoUpdateConfigurationKey, IExtensionContainer, EXTENSIONS_CONFIG, TOGGLE_IGNORE_EXTENSION_ACTION_ID } from 'vs/workbench/contrib/extensions/common/extensions';
@@ -61,6 +60,7 @@ import { IFileDialogService, IDialogService } from 'vs/platform/dialogs/common/d
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
import { Codicon } from 'vs/base/common/codicons';
import { IViewsService } from 'vs/workbench/common/views';
import { IActionViewItemOptions, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; // {{SQL CARBON EDIT}}
import product from 'vs/platform/product/common/product';
@@ -729,7 +729,7 @@ export class DropDownMenuActionViewItem extends ExtensionActionViewItem {
}
}
export function getContextMenuActions(menuService: IMenuService, contextKeyService: IContextKeyService, instantiationService: IInstantiationService, extension: IExtension | undefined | null): ExtensionAction[][] {
export function getContextMenuActions(menuService: IMenuService, contextKeyService: IContextKeyService, instantiationService: IInstantiationService, extension: IExtension | undefined | null): IAction[][] {
const scopedContextKeyService = contextKeyService.createScoped();
if (extension) {
scopedContextKeyService.createKey<string>('extension', extension.identifier.id);
@@ -740,9 +740,14 @@ export function getContextMenuActions(menuService: IMenuService, contextKeyServi
}
}
const groups: ExtensionAction[][] = [];
const groups: IAction[][] = [];
const menu = menuService.createMenu(MenuId.ExtensionContext, scopedContextKeyService);
menu.getActions({ shouldForwardArgs: true }).forEach(([, actions]) => groups.push(actions.map(action => instantiationService.createInstance(MenuItemExtensionAction, action))));
menu.getActions({ shouldForwardArgs: true }).forEach(([, actions]) => groups.push(actions.map(action => {
if (action instanceof SubmenuAction) {
return action;
}
return instantiationService.createInstance(MenuItemExtensionAction, action);
})));
menu.dispose();
return groups;
@@ -771,7 +776,7 @@ export class ManageExtensionAction extends ExtensionDropDownAction {
}
async getActionGroups(runningExtensions: IExtensionDescription[]): Promise<IAction[][]> {
const groups: ExtensionAction[][] = [];
const groups: IAction[][] = [];
if (this.extension) {
const actions = await Promise.all([
SetColorThemeAction.create(this.workbenchThemeService, this.instantiationService, this.extension),
@@ -802,7 +807,11 @@ export class ManageExtensionAction extends ExtensionDropDownAction {
getContextMenuActions(this.menuService, this.contextKeyService, this.instantiationService, this.extension).forEach(actions => groups.push(actions));
groups.forEach(group => group.forEach(extensionAction => extensionAction.extension = this.extension));
groups.forEach(group => group.forEach(extensionAction => {
if (extensionAction instanceof ExtensionAction) {
extensionAction.extension = this.extension;
}
}));
return groups;
}
@@ -1769,7 +1778,28 @@ export class ShowPopularExtensionsAction extends Action {
return this.viewletService.openViewlet(VIEWLET_ID, true)
.then(viewlet => viewlet?.getViewPaneContainer() as IExtensionsViewPaneContainer)
.then(viewlet => {
viewlet.search('@sort:installs ');
viewlet.search('@popular ');
viewlet.focus();
});
}
}
export class PredefinedExtensionFilterAction extends Action {
constructor(
id: string,
label: string,
private readonly filter: string,
@IViewletService private readonly viewletService: IViewletService
) {
super(id, label, undefined, true);
}
run(): Promise<void> {
return this.viewletService.openViewlet(VIEWLET_ID, true)
.then(viewlet => viewlet?.getViewPaneContainer() as IExtensionsViewPaneContainer)
.then(viewlet => {
viewlet.search(`${this.filter} `);
viewlet.focus();
});
}

View File

@@ -10,8 +10,7 @@ import { isPromiseCanceledError } from 'vs/base/common/errors';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { Event as EventOf, Emitter } from 'vs/base/common/event';
import { IAction, Action } from 'vs/base/common/actions';
import { Separator, IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IAction, Action, Separator, SubmenuAction } from 'vs/base/common/actions';
import { IViewlet } from 'vs/workbench/common/viewlet';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { append, $, addClass, toggleClass, Dimension, hide, show } from 'vs/base/browser/dom';
@@ -20,11 +19,12 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IExtensionsWorkbenchService, IExtensionsViewPaneContainer, VIEWLET_ID, AutoUpdateConfigurationKey, CloseExtensionDetailsOnViewChangeKey } from '../common/extensions';
import {
ShowRecommendedExtensionsAction, /*ShowPopularExtensionsAction,*/
ClearExtensionsInputAction, ChangeSortAction, UpdateAllAction, CheckForUpdatesAction, DisableAllAction, EnableAllAction,
EnableAutoUpdateAction, DisableAutoUpdateAction, ShowBuiltInExtensionsAction, InstallVSIXAction, SearchCategoryAction, /*RecentlyPublishedExtensionsAction, */ShowInstalledExtensionsAction, ShowOutdatedExtensionsAction, ShowDisabledExtensionsAction, ShowEnabledExtensionsAction
EnableAutoUpdateAction, DisableAutoUpdateAction, ShowBuiltInExtensionsAction, InstallVSIXAction, SearchCategoryAction,
/*RecentlyPublishedExtensionsAction, */ShowInstalledExtensionsAction, ShowOutdatedExtensionsAction, ShowDisabledExtensionsAction,
ShowEnabledExtensionsAction, PredefinedExtensionFilterAction
} from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionManagementService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput';
import { ExtensionsListView, EnabledExtensionsView, DisabledExtensionsView, RecommendedExtensionsView, WorkspaceRecommendedExtensionsView, BuiltInFeatureExtensionsView, BuiltInThemesExtensionsView, BuiltInProgrammingLanguageExtensionsView, ServerExtensionsView, DefaultRecommendedExtensionsView, OutdatedExtensionsView, InstalledExtensionsView, SearchBuiltInExtensionsView } from 'vs/workbench/contrib/extensions/browser/extensionsViews';
@@ -59,8 +59,6 @@ import { IPreferencesService } from 'vs/workbench/services/preferences/common/pr
import { DragAndDropObserver } from 'vs/workbench/browser/dnd';
import { URI } from 'vs/base/common/uri';
import { SIDE_BAR_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme';
import { ContextSubMenu } from 'vs/base/browser/contextmenu';
import { DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdown';
const NonEmptyWorkspaceContext = new RawContextKey<boolean>('nonEmptyWorkspace', false);
const DefaultViewsContext = new RawContextKey<boolean>('defaultExtensionViews', true);
@@ -347,6 +345,7 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE
@IInstantiationService instantiationService: IInstantiationService,
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService,
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
@INotificationService private readonly notificationService: INotificationService,
@IViewletService private readonly viewletService: IViewletService,
@IThemeService themeService: IThemeService,
@@ -497,41 +496,43 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE
}
getActions(): IAction[] {
const filterActions: IAction[] = [];
// Local extensions filters
filterActions.push(...[
this.instantiationService.createInstance(ShowBuiltInExtensionsAction, ShowBuiltInExtensionsAction.ID, localize('builtin filter', "Built-in")),
this.instantiationService.createInstance(ShowInstalledExtensionsAction, ShowInstalledExtensionsAction.ID, localize('installed filter', "Installed")),
this.instantiationService.createInstance(ShowEnabledExtensionsAction, ShowEnabledExtensionsAction.ID, localize('enabled filter', "Enabled")),
this.instantiationService.createInstance(ShowDisabledExtensionsAction, ShowDisabledExtensionsAction.ID, localize('disabled filter', "Disabled")),
this.instantiationService.createInstance(ShowOutdatedExtensionsAction, ShowOutdatedExtensionsAction.ID, localize('outdated filter', "Outdated")),
]);
if (this.extensionGalleryService.isEnabled()) {
filterActions.splice(0, 0, ...[
// this.instantiationService.createInstance(PredefinedExtensionFilterAction, 'extensions.filter.featured', localize('featured filter', "Featured"), '@featured'), // {{SQL CARBON EDIT}}
// this.instantiationService.createInstance(PredefinedExtensionFilterAction, 'extensions.filter.popular', localize('most popular filter', "Most Popular"), '@popular'), // {{SQL CARBON EDIT}}
this.instantiationService.createInstance(PredefinedExtensionFilterAction, 'extensions.filter.recommended', localize('most popular recommended', "Recommended"), '@recommended'),
// this.instantiationService.createInstance(RecentlyPublishedExtensionsAction, RecentlyPublishedExtensionsAction.ID, localize('recently published filter', "Recently Published")), // {{SQL CARBON EDIT}}
new SubmenuAction('workbench.extensions.action.filterExtensionsByCategory', localize('filter by category', "Category"), EXTENSION_CATEGORIES.map(category => this.instantiationService.createInstance(SearchCategoryAction, `extensions.actions.searchByCategory.${category}`, category, category))),
new Separator(),
]);
filterActions.push(...[
new Separator(),
new SubmenuAction('workbench.extensions.action.sortBy', localize('sorty by', "Sort By"), [
// this.instantiationService.createInstance(ChangeSortAction, 'extensions.sort.install', localize('sort by installs', "Install Count"), this.onSearchChange, 'installs'), // {{SQL CARBON EDIT}}
// this.instantiationService.createInstance(ChangeSortAction, 'extensions.sort.rating', localize('sort by rating', "Rating"), this.onSearchChange, 'rating'), // {{SQL CARBON EDIT}}
this.instantiationService.createInstance(ChangeSortAction, 'extensions.sort.name', localize('sort by name', "Name"), this.onSearchChange, 'name'),
this.instantiationService.createInstance(ChangeSortAction, 'extensions.sort.publishedDate', localize('sort by date', "Published Date"), this.onSearchChange, 'publishedDate'),
]),
]);
}
return [
new Action('workbench.extensions.action.filterExtensions', localize('filterExtensions', "Filter Extensions..."), 'codicon-filter', true),
new SubmenuAction('workbench.extensions.action.filterExtensions', localize('filterExtensions', "Filter Extensions..."), filterActions, 'codicon-filter'),
this.instantiationService.createInstance(ClearExtensionsInputAction, ClearExtensionsInputAction.ID, ClearExtensionsInputAction.LABEL, this.onSearchChange, this.searchBox ? this.searchBox.getValue() : ''),
];
}
getActionViewItem(action: IAction): IActionViewItem | undefined {
if (action.id === 'workbench.extensions.action.filterExtensions') {
return new DropdownMenuActionViewItem(action,
[
// this.instantiationService.createInstance(ShowPopularExtensionsAction, ShowPopularExtensionsAction.ID, localize('most popular filter', "Most Popular")), // {{SQL CARBON EDIT}}
// this.instantiationService.createInstance(RecentlyPublishedExtensionsAction, RecentlyPublishedExtensionsAction.ID, localize('recently published filter', "Recently Published")), // {{SQL CARBON EDIT}}
this.instantiationService.createInstance(ShowRecommendedExtensionsAction, ShowRecommendedExtensionsAction.ID, localize('recomended filter', "Recommended")),
new ContextSubMenu(localize('filter by category', "Category"), EXTENSION_CATEGORIES.map(category => this.instantiationService.createInstance(SearchCategoryAction, `extensions.actions.searchByCategory.${category}`, category, category))),
new Separator(),
this.instantiationService.createInstance(ShowBuiltInExtensionsAction, ShowBuiltInExtensionsAction.ID, localize('builtin filter', "Built-in")),
this.instantiationService.createInstance(ShowInstalledExtensionsAction, ShowInstalledExtensionsAction.ID, localize('installed filter', "Installed")),
this.instantiationService.createInstance(ShowEnabledExtensionsAction, ShowEnabledExtensionsAction.ID, localize('enabled filter', "Enabled")),
this.instantiationService.createInstance(ShowDisabledExtensionsAction, ShowDisabledExtensionsAction.ID, localize('disabled filter', "Disabled")),
this.instantiationService.createInstance(ShowOutdatedExtensionsAction, ShowOutdatedExtensionsAction.ID, localize('outdated filter', "Outdated")),
new Separator(),
new ContextSubMenu(localize('sorty by', "Sort By"), [
// this.instantiationService.createInstance(ChangeSortAction, 'extensions.sort.install', localize('sort by installs', "Install Count"), this.onSearchChange, 'installs'), // {{SQL CARBON EDIT}}
// this.instantiationService.createInstance(ChangeSortAction, 'extensions.sort.rating', localize('sort by rating', "Rating"), this.onSearchChange, 'rating'), // {{SQL CARBON EDIT}}
this.instantiationService.createInstance(ChangeSortAction, 'extensions.sort.name', localize('sort by name', "Name"), this.onSearchChange, 'name'),
this.instantiationService.createInstance(ChangeSortAction, 'extensions.sort.publishedDate', localize('sort by date', "Published Date"), this.onSearchChange, 'publishedDate'),
]),
],
this.contextMenuService, undefined, undefined, undefined, 'codicon-filter', undefined, true);
}
return super.getActionViewItem(action);
}
getSecondaryActions(): IAction[] {
const actions: IAction[] = [];
@@ -541,11 +542,13 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE
} else {
actions.push(this.instantiationService.createInstance(UpdateAllAction, UpdateAllAction.ID, UpdateAllAction.LABEL), this.instantiationService.createInstance(EnableAutoUpdateAction, EnableAutoUpdateAction.ID, EnableAutoUpdateAction.LABEL));
}
actions.push(this.instantiationService.createInstance(InstallVSIXAction, InstallVSIXAction.ID, InstallVSIXAction.LABEL));
actions.push(new Separator());
actions.push(this.instantiationService.createInstance(DisableAllAction, DisableAllAction.ID, DisableAllAction.LABEL));
actions.push(this.instantiationService.createInstance(EnableAllAction, EnableAllAction.ID, EnableAllAction.LABEL));
actions.push(this.instantiationService.createInstance(DisableAllAction, DisableAllAction.ID, DisableAllAction.LABEL));
actions.push(new Separator());
actions.push(this.instantiationService.createInstance(InstallVSIXAction, InstallVSIXAction.ID, InstallVSIXAction.LABEL));
return actions;
}
@@ -565,7 +568,14 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE
}
private normalizedQuery(): string {
return this.searchBox ? this.searchBox.getValue().replace(/@category/g, 'category').replace(/@tag:/g, 'tag:').replace(/@ext:/g, 'ext:') : '';
return this.searchBox
? this.searchBox.getValue()
.replace(/@category/g, 'category')
.replace(/@tag:/g, 'tag:')
.replace(/@ext:/g, 'ext:')
.replace(/@featured/g, 'featured')
.replace(/@popular/g, '@sort:installs')
: '';
}
saveState(): void {

View File

@@ -25,8 +25,7 @@ import { attachBadgeStyler } from 'vs/platform/theme/common/styler';
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { InstallWorkspaceRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction, ManageExtensionAction, InstallLocalExtensionsInRemoteAction, getContextMenuActions } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { InstallWorkspaceRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction, ManageExtensionAction, InstallLocalExtensionsInRemoteAction, getContextMenuActions, ExtensionAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
import { WorkbenchPagedList, ListResourceNavigator } from 'vs/platform/list/browser/listService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
@@ -38,7 +37,7 @@ import { alert } from 'vs/base/browser/ui/aria/aria';
import { IListContextMenuEvent } from 'vs/base/browser/ui/list/list';
import { createErrorWithActions } from 'vs/base/common/errorsWithActions';
import { CancellationToken } from 'vs/base/common/cancellation';
import { IAction, Action } from 'vs/base/common/actions';
import { IAction, Action, Separator } from 'vs/base/common/actions';
import { ExtensionType, ExtensionIdentifier, IExtensionDescription, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
import { IProductService } from 'vs/platform/product/common/productService';
@@ -248,7 +247,11 @@ export class ExtensionsListView extends ViewPane {
});
} else if (e.element) {
const groups = getContextMenuActions(this.menuService, this.contextKeyService.createScoped(), this.instantiationService, e.element);
groups.forEach(group => group.forEach(extensionAction => extensionAction.extension = e.element!));
groups.forEach(group => group.forEach(extensionAction => {
if (extensionAction instanceof ExtensionAction) {
extensionAction.extension = e.element!;
}
}));
let actions: IAction[] = [];
for (const menuActions of groups) {
actions = [...actions, ...menuActions, new Separator()];

View File

@@ -40,6 +40,7 @@ import { IProductService } from 'vs/platform/product/common/productService';
import { asDomUri } from 'vs/base/browser/dom';
import { getIgnoredExtensions } from 'vs/platform/userDataSync/common/extensionsMerge';
import { isWeb } from 'vs/base/common/platform';
import { getExtensionKind } from 'vs/workbench/services/extensions/common/extensionsUtil';
import { isEngineValid } from 'vs/platform/extensions/common/extensionValidator'; // {{SQL CARBON EDIT}}
import { IOpenerService } from 'vs/platform/opener/common/opener'; // {{SQL CARBON EDIT}}
@@ -686,14 +687,79 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
if (extensions.length === 1) {
return extensions[0];
}
const enabledExtensions = extensions.filter(e => e.local && this.extensionEnablementService.isEnabled(e.local));
if (enabledExtensions.length === 0) {
return extensions[0];
}
if (enabledExtensions.length === 1) {
return enabledExtensions[0];
}
return enabledExtensions.find(e => e.server === this.extensionManagementServerService.remoteExtensionManagementServer) || enabledExtensions[0];
const extensionsToChoose = enabledExtensions.length ? enabledExtensions : extensions;
let extension = extensionsToChoose.find(extension => {
for (const extensionKind of getExtensionKind(extension.local!.manifest, this.productService, this.configurationService)) {
switch (extensionKind) {
case 'ui':
/* UI extension is chosen only if it is installed locally */
if (extension.server === this.extensionManagementServerService.localExtensionManagementServer) {
return true;
}
return false;
case 'workspace':
/* Choose remote workspace extension if exists */
if (extension.server === this.extensionManagementServerService.remoteExtensionManagementServer) {
return true;
}
return false;
case 'web':
/* Choose web extension if exists */
if (extension.server === this.extensionManagementServerService.webExtensionManagementServer) {
return true;
}
return false;
}
}
return false;
});
if (!extension && this.extensionManagementServerService.localExtensionManagementServer) {
extension = extensionsToChoose.find(extension => {
for (const extensionKind of getExtensionKind(extension.local!.manifest, this.productService, this.configurationService)) {
switch (extensionKind) {
case 'workspace':
/* Choose local workspace extension if exists */
if (extension.server === this.extensionManagementServerService.localExtensionManagementServer) {
return true;
}
return false;
case 'web':
/* Choose local web extension if exists */
if (extension.server === this.extensionManagementServerService.localExtensionManagementServer) {
return true;
}
return false;
}
}
return false;
});
}
if (!extension && this.extensionManagementServerService.remoteExtensionManagementServer) {
extension = extensionsToChoose.find(extension => {
for (const extensionKind of getExtensionKind(extension.local!.manifest, this.productService, this.configurationService)) {
switch (extensionKind) {
case 'web':
/* Choose remote web extension if exists */
if (extension.server === this.extensionManagementServerService.remoteExtensionManagementServer) {
return true;
}
return false;
}
}
return false;
});
}
return extension || extensions[0];
}
private fromGallery(gallery: IGalleryExtension, maliciousExtensionSet: Set<string>): IExtension {

View File

@@ -7,7 +7,7 @@ import 'vs/css!./media/runtimeExtensionsEditor';
import * as nls from 'vs/nls';
import * as os from 'os';
import { IProductService } from 'vs/platform/product/common/productService';
import { Action, IAction } from 'vs/base/common/actions';
import { Action, IAction, Separator } from 'vs/base/common/actions';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation';
@@ -18,7 +18,7 @@ import { IExtensionService, IExtensionsStatus, IExtensionHostProfile } from 'vs/
import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list';
import { WorkbenchList } from 'vs/platform/list/browser/listService';
import { append, $, addClass, toggleClass, Dimension, clearNode } from 'vs/base/browser/dom';
import { ActionBar, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { RunOnceScheduler } from 'vs/base/common/async';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
@@ -164,16 +164,17 @@ export class RuntimeExtensionsEditor extends BaseEditor {
this._register(this._extensionService.onDidChangeExtensionsStatus(() => this._updateSoon.schedule()));
}
private _updateExtensions(): void {
this._elements = this._resolveExtensions();
private async _updateExtensions(): Promise<void> {
this._elements = await this._resolveExtensions();
if (this._list) {
this._list.splice(0, this._list.length, this._elements);
}
}
private _resolveExtensions(): IRuntimeExtension[] {
private async _resolveExtensions(): Promise<IRuntimeExtension[]> {
let marketplaceMap: { [id: string]: IExtension; } = Object.create(null);
for (let extension of this._extensionsWorkbenchService.local) {
const marketPlaceExtensions = await this._extensionsWorkbenchService.queryLocal();
for (let extension of marketPlaceExtensions) {
marketplaceMap[ExtensionIdentifier.toKey(extension.identifier.id)] = extension;
}
@@ -328,7 +329,7 @@ export class RuntimeExtensionsEditor extends BaseEditor {
} else {
data.icon.style.visibility = 'inherit';
}
data.name.textContent = element.marketplaceInfo ? element.marketplaceInfo.displayName : element.description.displayName || '';
data.name.textContent = element.marketplaceInfo.displayName;
data.version.textContent = element.description.version;
const activationTimes = element.status.activationTimes!;
@@ -462,11 +463,10 @@ export class RuntimeExtensionsEditor extends BaseEditor {
actions.push(new ReportExtensionIssueAction(e.element, this._openerService, this._clipboardService, this._productService));
actions.push(new Separator());
if (e.element.marketplaceInfo) {
actions.push(new Action('runtimeExtensionsEditor.action.disableWorkspace', nls.localize('disable workspace', "Disable (Workspace)"), undefined, true, () => this._extensionsWorkbenchService.setEnablement(e.element!.marketplaceInfo, EnablementState.DisabledWorkspace)));
actions.push(new Action('runtimeExtensionsEditor.action.disable', nls.localize('disable', "Disable"), undefined, true, () => this._extensionsWorkbenchService.setEnablement(e.element!.marketplaceInfo, EnablementState.DisabledGlobally)));
actions.push(new Separator());
}
actions.push(new Action('runtimeExtensionsEditor.action.disableWorkspace', nls.localize('disable workspace', "Disable (Workspace)"), undefined, true, () => this._extensionsWorkbenchService.setEnablement(e.element!.marketplaceInfo, EnablementState.DisabledWorkspace)));
actions.push(new Action('runtimeExtensionsEditor.action.disable', nls.localize('disable', "Disable"), undefined, true, () => this._extensionsWorkbenchService.setEnablement(e.element!.marketplaceInfo, EnablementState.DisabledGlobally)));
actions.push(new Separator());
const state = this._extensionHostProfileService.state;
if (state === ProfileSessionState.Running) {
actions.push(this._instantiationService.createInstance(StopExtensionHostProfileAction, StopExtensionHostProfileAction.ID, StopExtensionHostProfileAction.LABEL));

View File

@@ -14,7 +14,7 @@ import {
IExtensionManagementService, IExtensionGalleryService, ILocalExtension, IGalleryExtension,
DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IGalleryExtensionAssets, IExtensionIdentifier, InstallOperation, IExtensionTipsService, IGalleryMetadata
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionRecommendationsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IWorkbenchExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionRecommendationsService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test';
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
@@ -34,7 +34,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
import { NativeURLService } from 'vs/platform/url/common/urlService';
import { URI } from 'vs/base/common/uri';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ExtensionType } from 'vs/platform/extensions/common/extensions';
import { ExtensionType, IExtension, ExtensionKind } from 'vs/platform/extensions/common/extensions';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl';
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
@@ -46,6 +46,8 @@ import { TestLifecycleService } from 'vs/workbench/test/browser/workbenchTestSer
import { IExperimentService } from 'vs/workbench/contrib/experiments/common/experimentService';
import { TestExperimentService } from 'vs/workbench/contrib/experiments/test/electron-browser/experimentService.test';
import { ExtensionTipsService } from 'vs/platform/extensionManagement/node/extensionTipsService';
import { Schemas } from 'vs/base/common/network';
import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
suite('ExtensionsWorkbenchServiceTest', () => {
@@ -981,6 +983,384 @@ suite('ExtensionsWorkbenchServiceTest', () => {
assert.equal(actual[0].enablementState, EnablementState.DisabledWorkspace);
});
test('test user extension is preferred when the same extension exists as system and user extension', async () => {
testObject = await aWorkbenchService();
const userExtension = aLocalExtension('pub.a');
const systemExtension = aLocalExtension('pub.a', {}, { type: ExtensionType.System });
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [systemExtension, userExtension]);
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, userExtension);
});
test('test user extension is disabled when the same extension exists as system and user extension and system extension is disabled', async () => {
testObject = await aWorkbenchService();
const systemExtension = aLocalExtension('pub.a', {}, { type: ExtensionType.System });
await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([systemExtension], EnablementState.DisabledGlobally);
const userExtension = aLocalExtension('pub.a');
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [systemExtension, userExtension]);
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, userExtension);
assert.equal(actual[0].enablementState, EnablementState.DisabledGlobally);
});
test('Test local ui extension is chosen if it exists only in local server', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['ui'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test local workspace extension is chosen if it exists only in local server', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['workspace'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test local web extension is chosen if it exists only in local server', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['web'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test local ui,workspace extension is chosen if it exists only in local server', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['ui', 'workspace'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test local workspace,ui extension is chosen if it exists only in local server', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['workspace', 'ui'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test local ui,workspace,web extension is chosen if it exists only in local server', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['ui', 'workspace', 'web'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test local ui,web,workspace extension is chosen if it exists only in local server', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['ui', 'web', 'workspace'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test local web,ui,workspace extension is chosen if it exists only in local server', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['web', 'ui', 'workspace'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test local web,workspace,ui extension is chosen if it exists only in local server', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['web', 'workspace', 'ui'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test local workspace,web,ui extension is chosen if it exists only in local server', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['workspace', 'web', 'ui'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test local workspace,ui,web extension is chosen if it exists only in local server', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['workspace', 'ui', 'web'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test local UI extension is chosen if it exists in both servers', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['ui'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const remoteExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([remoteExtension]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test local ui,workspace extension is chosen if it exists in both servers', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['ui', 'workspace'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const remoteExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([remoteExtension]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test remote workspace extension is chosen if it exists in remote server', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['workspace'];
const remoteExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService(), createExtensionManagementService([remoteExtension]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, remoteExtension);
});
test('Test remote workspace extension is chosen if it exists in both servers', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['workspace'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const remoteExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([remoteExtension]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, remoteExtension);
});
test('Test remote workspace extension is chosen if it exists in both servers and local is disabled', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['workspace'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const remoteExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([remoteExtension]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([localExtension], EnablementState.DisabledGlobally);
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, remoteExtension);
assert.equal(actual[0].enablementState, EnablementState.DisabledGlobally);
});
test('Test remote workspace extension is chosen if it exists in both servers and remote is disabled in workspace', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['workspace'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const remoteExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([remoteExtension]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([remoteExtension], EnablementState.DisabledWorkspace);
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, remoteExtension);
assert.equal(actual[0].enablementState, EnablementState.DisabledWorkspace);
});
test('Test local ui, workspace extension is chosen if it exists in both servers and local is disabled', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['ui', 'workspace'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const remoteExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([remoteExtension]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([localExtension], EnablementState.DisabledGlobally);
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
assert.equal(actual[0].enablementState, EnablementState.DisabledGlobally);
});
test('Test local ui, workspace extension is chosen if it exists in both servers and local is disabled in workspace', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['ui', 'workspace'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const remoteExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([remoteExtension]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
await instantiationService.get(IWorkbenchExtensionEnablementService).setEnablement([localExtension], EnablementState.DisabledWorkspace);
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
assert.equal(actual[0].enablementState, EnablementState.DisabledWorkspace);
});
test('Test local web extension is chosen if it exists in both servers', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['web'];
const localExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`) });
const remoteExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([remoteExtension]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, localExtension);
});
test('Test remote web extension is chosen if it exists only in remote', async () => {
// multi server setup
const extensionKind: ExtensionKind[] = ['web'];
const remoteExtension = aLocalExtension('a', { extensionKind }, { location: URI.file(`pub.a`).with({ scheme: Schemas.vscodeRemote }) });
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([]), createExtensionManagementService([remoteExtension]));
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
instantiationService.stub(IWorkbenchExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
testObject = await aWorkbenchService();
const actual = await testObject.queryLocal();
assert.equal(actual.length, 1);
assert.equal(actual[0].local, remoteExtension);
});
async function aWorkbenchService(): Promise<ExtensionsWorkbenchService> {
const workbenchService: ExtensionsWorkbenchService = instantiationService.createInstance(ExtensionsWorkbenchService);
await workbenchService.queryLocal();
@@ -1031,4 +1411,49 @@ suite('ExtensionsWorkbenchServiceTest', () => {
});
});
}
function aMultiExtensionManagementServerService(instantiationService: TestInstantiationService, localExtensionManagementService?: IExtensionManagementService, remoteExtensionManagementService?: IExtensionManagementService): IExtensionManagementServerService {
const localExtensionManagementServer: IExtensionManagementServer = {
id: 'vscode-local',
label: 'local',
extensionManagementService: localExtensionManagementService || createExtensionManagementService()
};
const remoteExtensionManagementServer: IExtensionManagementServer = {
id: 'vscode-remote',
label: 'remote',
extensionManagementService: remoteExtensionManagementService || createExtensionManagementService()
};
return {
_serviceBrand: undefined,
localExtensionManagementServer,
remoteExtensionManagementServer,
webExtensionManagementServer: null,
getExtensionManagementServer: (extension: IExtension) => {
if (extension.location.scheme === Schemas.file) {
return localExtensionManagementServer;
}
if (extension.location.scheme === REMOTE_HOST_SCHEME) {
return remoteExtensionManagementServer;
}
throw new Error('');
}
};
}
function createExtensionManagementService(installed: ILocalExtension[] = []): IExtensionManagementService {
return <IExtensionManagementService>{
onInstallExtension: Event.None,
onDidInstallExtension: Event.None,
onUninstallExtension: Event.None,
onDidUninstallExtension: Event.None,
getInstalled: () => Promise.resolve<ILocalExtension[]>(installed),
installFromGallery: (extension: IGalleryExtension) => Promise.reject(new Error('not supported')),
updateMetadata: async (local: ILocalExtension, metadata: IGalleryMetadata) => {
local.identifier.uuid = metadata.id;
local.publisherDisplayName = metadata.publisherDisplayName;
local.publisherId = metadata.publisherId;
return local;
}
};
}
});

View File

@@ -16,7 +16,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { attachBadgeStyler } from 'vs/platform/theme/common/styler';
import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { ActionBar, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { QuickFixAction, QuickFixActionViewItem } from 'vs/workbench/contrib/markers/browser/markersViewActions';
import { ILabelService } from 'vs/platform/label/common/label';
import { dirname, basename, isEqual } from 'vs/base/common/resources';
@@ -52,6 +52,7 @@ import { domEvent } from 'vs/base/browser/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Progress } from 'vs/platform/progress/common/progress';
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
export type TreeElement = ResourceMarkers | Marker | RelatedInformation;

View File

@@ -7,7 +7,7 @@ import 'vs/css!./media/markers';
import { URI } from 'vs/base/common/uri';
import * as dom from 'vs/base/browser/dom';
import { IAction, IActionViewItem, Action } from 'vs/base/common/actions';
import { IAction, IActionViewItem, Action, Separator } from 'vs/base/common/actions';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import Constants from 'vs/workbench/contrib/markers/browser/constants';
@@ -33,7 +33,7 @@ import { deepClone } from 'vs/base/common/objects';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { FilterData, Filter, VirtualDelegate, ResourceMarkersRenderer, MarkerRenderer, RelatedInformationRenderer, TreeElement, MarkersTreeAccessibilityProvider, MarkersViewModel, ResourceDragAndDrop } from 'vs/workbench/contrib/markers/browser/markersTreeViewer';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { Separator, ActionViewItem, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { IMenuService, MenuId, registerAction2, Action2 } from 'vs/platform/actions/common/actions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
@@ -50,6 +50,7 @@ import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/vie
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { Codicon } from 'vs/base/common/codicons';
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
function createResourceMarkersIterator(resourceMarkers: ResourceMarkers): Iterable<ITreeElement<TreeElement>> {
return Iterable.map(resourceMarkers.markers, m => {

View File

@@ -5,7 +5,7 @@
import { Delayer } from 'vs/base/common/async';
import * as DOM from 'vs/base/browser/dom';
import { Action, IAction, IActionRunner } from 'vs/base/common/actions';
import { Action, IAction, IActionRunner, Separator } from 'vs/base/common/actions';
import { HistoryInputBox } from 'vs/base/browser/ui/inputbox/inputBox';
import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
@@ -15,7 +15,7 @@ import Constants from 'vs/workbench/contrib/markers/browser/constants';
import { IThemeService, registerThemingParticipant, ICssStyleCollector, IColorTheme } from 'vs/platform/theme/common/themeService';
import { attachInputBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
import { toDisposable, Disposable } from 'vs/base/common/lifecycle';
import { BaseActionViewItem, ActionViewItem, ActionBar, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { badgeBackground, badgeForeground, contrastBorder, inputActiveOptionBorder, inputActiveOptionBackground, inputActiveOptionForeground } from 'vs/platform/theme/common/colorRegistry';
import { localize } from 'vs/nls';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -23,10 +23,11 @@ import { ContextScopedHistoryInputBox } from 'vs/platform/browser/contextScopedH
import { Marker } from 'vs/workbench/contrib/markers/browser/markersModel';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { Event, Emitter } from 'vs/base/common/event';
import { DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdown';
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
import { IViewsService } from 'vs/workbench/common/views';
import { Codicon } from 'vs/base/common/codicons';
import { BaseActionViewItem, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
import { DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdownActionViewItem';
export class ShowProblemsPanelAction extends Action {
@@ -179,11 +180,12 @@ class FiltersDropdownMenuActionViewItem extends DropdownMenuActionViewItem {
super(action,
{ getActions: () => this.getActions() },
contextMenuService,
action => undefined,
actionRunner!,
undefined,
action.class,
() => { return AnchorAlignment.RIGHT; });
{
actionRunner,
classNames: action.class,
anchorAlignmentProvider: () => AnchorAlignment.RIGHT
}
);
}
render(container: HTMLElement): void {

View File

@@ -18,7 +18,7 @@ export const BOTTOM_CELL_TOOLBAR_OFFSET = 12;
export const CELL_STATUSBAR_HEIGHT = 22;
// Margin above editor
export const EDITOR_TOP_MARGIN = 6;
export const CELL_TOP_MARGIN = 6;
export const CELL_BOTTOM_MARGIN = 6;
// Top and bottom padding inside the monaco editor in a cell, which are included in `cell.editorHeight`
@@ -26,3 +26,5 @@ export const EDITOR_TOP_PADDING = 12;
export const EDITOR_BOTTOM_PADDING = 4;
export const CELL_OUTPUT_PADDING = 14;
export const COLLAPSED_INDICATOR_HEIGHT = 24;

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { KeyCode, KeyMod, KeyChord } from 'vs/base/common/keyCodes';
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { URI } from 'vs/base/common/uri';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { getIconClasses } from 'vs/editor/common/services/getIconClasses';
@@ -18,12 +18,12 @@ import { InputFocusedContext, InputFocusedContextKey } from 'vs/platform/context
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { IQuickInputService, IQuickPickItem, QuickPickInput } from 'vs/platform/quickinput/common/quickInput';
import { BaseCellRenderTemplate, CellEditState, ICellViewModel, INotebookEditor, NOTEBOOK_CELL_EDITABLE, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE, NOTEBOOK_CELL_TYPE, NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_EDITOR_EXECUTING_NOTEBOOK, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_EDITOR_RUNNABLE, NOTEBOOK_IS_ACTIVE_EDITOR, NOTEBOOK_CELL_HAS_OUTPUTS, CellFocusMode, NOTEBOOK_OUTPUT_FOCUSED, NOTEBOOK_CELL_LIST_FOCUSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellKind, NOTEBOOK_EDITOR_CURSOR_BOUNDARY, NotebookCellRunState, CellUri } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { BaseCellRenderTemplate, CellCollapseState, CellEditState, CellFocusMode, ICellViewModel, INotebookEditor, NOTEBOOK_CELL_CONTENT_COLLAPSED, NOTEBOOK_CELL_EDITABLE, NOTEBOOK_CELL_HAS_OUTPUTS, NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE, NOTEBOOK_CELL_OUTPUT_COLLAPSED, NOTEBOOK_CELL_TYPE, NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_EDITOR_EXECUTING_NOTEBOOK, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_EDITOR_RUNNABLE, NOTEBOOK_IS_ACTIVE_EDITOR, NOTEBOOK_OUTPUT_FOCUSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
import { CellKind, CellUri, NotebookCellRunState, NOTEBOOK_EDITOR_CURSOR_BOUNDARY } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
// Notebook Commands
const EXECUTE_NOTEBOOK_COMMAND_ID = 'notebook.execute';
@@ -72,6 +72,11 @@ const CENTER_ACTIVE_CELL = 'notebook.centerActiveCell';
const FOCUS_IN_OUTPUT_COMMAND_ID = 'notebook.cell.focusInOutput';
const FOCUS_OUT_OUTPUT_COMMAND_ID = 'notebook.cell.focusOutOutput';
const COLLAPSE_CELL_CONTENT_COMMAND_ID = 'notebook.cell.collapseCellContent';
const COLLAPSE_CELL_OUTPUT_COMMAND_ID = 'notebook.cell.collapseCellOutput';
const EXPAND_CELL_CONTENT_COMMAND_ID = 'notebook.cell.expandCellContent';
const EXPAND_CELL_OUTPUT_COMMAND_ID = 'notebook.cell.expandCellOutput';
export const NOTEBOOK_ACTIONS_CATEGORY = { value: localize('notebookActions.category', "Notebook"), original: 'Notebook' };
export const CELL_TITLE_CELL_GROUP_ID = 'inline/cell';
@@ -1398,7 +1403,7 @@ registerAction2(class extends NotebookCellAction {
super(
{
id: JOIN_CELL_ABOVE_COMMAND_ID,
title: localize('notebookActions.joinCellAbove', "Join with Previous Cell"),
title: localize('notebookActions.joinCellAbove', "Join With Previous Cell"),
keybinding: {
when: NOTEBOOK_EDITOR_FOCUSED,
primary: KeyMod.WinCtrl | KeyMod.Alt | KeyMod.Shift | KeyCode.KEY_J,
@@ -1417,7 +1422,7 @@ registerAction2(class extends NotebookCellAction {
super(
{
id: JOIN_CELL_BELOW_COMMAND_ID,
title: localize('notebookActions.joinCellBelow', "Join with Next Cell"),
title: localize('notebookActions.joinCellBelow', "Join With Next Cell"),
keybinding: {
when: NOTEBOOK_EDITOR_FOCUSED,
primary: KeyMod.WinCtrl | KeyMod.Alt | KeyCode.KEY_J,
@@ -1456,3 +1461,95 @@ registerAction2(class extends NotebookCellAction {
return context.notebookEditor.revealInCenter(context.cell);
}
});
registerAction2(class extends NotebookCellAction {
constructor() {
super({
id: COLLAPSE_CELL_CONTENT_COMMAND_ID,
title: localize('notebookActions.collapseCellContent', "Collapse Cell Content"),
keybinding: {
when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_CONTENT_COLLAPSED.toNegated(), InputFocusedContext.toNegated()),
primary: KeyChord(KeyCode.KEY_C, KeyCode.KEY_C),
weight: KeybindingWeight.WorkbenchContrib
},
menu: {
id: MenuId.NotebookCellTitle,
when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_CONTENT_COLLAPSED.toNegated()),
group: '3_collapse',
}
});
}
async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext): Promise<void> {
context.cell.collapseState = CellCollapseState.Collapsed;
}
});
registerAction2(class extends NotebookCellAction {
constructor() {
super({
id: EXPAND_CELL_CONTENT_COMMAND_ID,
title: localize('notebookActions.expandCellContent', "Expand Cell Content"),
keybinding: {
when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_CONTENT_COLLAPSED),
primary: KeyChord(KeyCode.KEY_C, KeyCode.KEY_C),
weight: KeybindingWeight.WorkbenchContrib
},
menu: {
id: MenuId.NotebookCellTitle,
when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_CONTENT_COLLAPSED),
group: '3_collapse',
}
});
}
async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext): Promise<void> {
context.cell.collapseState = CellCollapseState.Normal;
}
});
registerAction2(class extends NotebookCellAction {
constructor() {
super({
id: COLLAPSE_CELL_OUTPUT_COMMAND_ID,
title: localize('notebookActions.collapseCellOutput', "Collapse Cell Output"),
keybinding: {
when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_OUTPUT_COLLAPSED.toNegated(), InputFocusedContext.toNegated()),
primary: KeyChord(KeyCode.KEY_C, KeyCode.KEY_O),
weight: KeybindingWeight.WorkbenchContrib
},
menu: {
id: MenuId.NotebookCellTitle,
when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_OUTPUT_COLLAPSED.toNegated()),
group: '3_collapse',
}
});
}
async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext): Promise<void> {
context.cell.collapseState = CellCollapseState.Collapsed;
}
});
registerAction2(class extends NotebookCellAction {
constructor() {
super({
id: EXPAND_CELL_OUTPUT_COMMAND_ID,
title: localize('notebookActions.expandCellOutput', "Expand Cell Output"),
keybinding: {
when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_OUTPUT_COLLAPSED),
primary: KeyChord(KeyCode.KEY_C, KeyCode.KEY_C),
weight: KeybindingWeight.WorkbenchContrib
},
// menu: {
// id: MenuId.NotebookCellTitle,
// when: ContextKeyExpr.and(NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_OUTPUT_COLLAPSED),
// group: '3_collapse',
// }
});
}
async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext): Promise<void> {
context.cell.collapseState = CellCollapseState.Normal;
}
});

View File

@@ -27,12 +27,14 @@ namespace NotebookRendererContribution {
export const viewType = 'viewType';
export const displayName = 'displayName';
export const mimeTypes = 'mimeTypes';
export const entrypoint = 'entrypoint';
}
interface INotebookRendererContribution {
export interface INotebookRendererContribution {
readonly [NotebookRendererContribution.viewType]: string;
readonly [NotebookRendererContribution.displayName]: string;
readonly [NotebookRendererContribution.mimeTypes]?: readonly string[];
readonly [NotebookRendererContribution.entrypoint]?: string;
}
const notebookProviderContribution: IJSONSchema = {
@@ -115,7 +117,11 @@ const notebookRendererContribution: IJSONSchema = {
items: {
type: 'string'
}
}
},
[NotebookRendererContribution.entrypoint]: {
type: 'string',
description: nls.localize('contributes.notebook.renderer.entrypoint', 'File to load in the webview to render the extension.'),
},
}
}
};

View File

@@ -211,6 +211,21 @@
outline: none !important;
}
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-collapsed-part {
cursor: pointer;
box-sizing: border-box;
padding-left: 2px;
}
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-collapsed-part .codicon {
margin-top: 2px;
}
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.collapsed .notebook-folding-indicator,
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.collapsed > .monaco-toolbar {
display: none;
}
/* top and bottom borders on cells */
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.focused .cell-focus-indicator-top:before,
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.focused .cell-focus-indicator-bottom:before,
@@ -423,7 +438,6 @@
position: absolute;
box-sizing: border-box;
top: 0px;
opacity: 0;
}
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-side {
@@ -686,12 +700,14 @@
top: 0;
left: 0;
right: 0;
height: 100%;
width: 26px;
height: 26px;
cursor: pointer;
}
.monaco-workbench .notebookOverlay > .cell-list-container .notebook-folding-indicator .codicon {
visibility: visible;
padding: 10px 0 0 10px;
padding: 8px 0 0 10px;
}
/** Theming */

View File

@@ -48,6 +48,8 @@ export const NOTEBOOK_CELL_RUNNABLE = new RawContextKey<boolean>('notebookCellRu
export const NOTEBOOK_CELL_MARKDOWN_EDIT_MODE = new RawContextKey<boolean>('notebookCellMarkdownEditMode', false); // bool
export const NOTEBOOK_CELL_RUN_STATE = new RawContextKey<string>('notebookCellRunState', undefined); // idle, running
export const NOTEBOOK_CELL_HAS_OUTPUTS = new RawContextKey<boolean>('notebookCellHasOutputs', false); // bool
export const NOTEBOOK_CELL_CONTENT_COLLAPSED = new RawContextKey<boolean>('notebookCellContentIsCollapsed', false); // bool
export const NOTEBOOK_CELL_OUTPUT_COLLAPSED = new RawContextKey<boolean>('notebookCellOutputIsCollapsed', false); // bool
// Kernels
@@ -110,6 +112,8 @@ export interface ICellViewModel {
readonly model: NotebookCellTextModel;
readonly id: string;
readonly textBuffer: IReadonlyTextBuffer;
collapseState: CellCollapseState;
outputCollapseState: CellCollapseState;
dragging: boolean;
handle: number;
uri: URI;
@@ -454,6 +458,8 @@ export interface INotebookCellList {
}
export interface BaseCellRenderTemplate {
editorPart: HTMLElement;
collapsedPart: HTMLElement;
contextKeyService: IContextKeyService;
container: HTMLElement;
cellContainer: HTMLElement;
@@ -471,7 +477,6 @@ export interface BaseCellRenderTemplate {
}
export interface MarkdownCellRenderTemplate extends BaseCellRenderTemplate {
editorPart: HTMLElement;
editorContainer: HTMLElement;
foldingIndicator: HTMLElement;
currentEditor?: ICodeEditor;
@@ -535,6 +540,11 @@ export enum CellEditState {
Editing
}
export enum CellCollapseState {
Normal,
Collapsed
}
export enum CellFocusMode {
Container,
Editor
@@ -553,6 +563,7 @@ export interface CellViewModelStateChangeEvent {
focusModeChanged?: boolean;
editStateChanged?: boolean;
languageChanged?: boolean;
collapseStateChanged?: boolean;
foldingStateChanged?: boolean;
contentChanged?: boolean;
outputIsHoveredChanged?: boolean;

View File

@@ -27,7 +27,7 @@ import { contrastBorder, editorBackground, focusBorder, foreground, registerColo
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { EditorMemento } from 'vs/workbench/browser/parts/editor/baseEditor';
import { EditorOptions, IEditorMemento } from 'vs/workbench/common/editor';
import { CELL_MARGIN, CELL_RUN_GUTTER, EDITOR_BOTTOM_PADDING, EDITOR_TOP_MARGIN, EDITOR_TOP_PADDING, SCROLLABLE_ELEMENT_PADDING_TOP, BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_BOTTOM_MARGIN, CODE_CELL_LEFT_MARGIN } from 'vs/workbench/contrib/notebook/browser/constants';
import { CELL_MARGIN, CELL_RUN_GUTTER, EDITOR_BOTTOM_PADDING, CELL_TOP_MARGIN, EDITOR_TOP_PADDING, SCROLLABLE_ELEMENT_PADDING_TOP, BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_BOTTOM_MARGIN, CODE_CELL_LEFT_MARGIN, COLLAPSED_INDICATOR_HEIGHT } from 'vs/workbench/contrib/notebook/browser/constants';
import { CellEditState, CellFocusMode, ICellRange, ICellViewModel, INotebookCellList, INotebookEditor, INotebookEditorContribution, INotebookEditorMouseEvent, NotebookLayoutInfo, NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_EDITOR_EXECUTING_NOTEBOOK, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_EDITOR_RUNNABLE, NOTEBOOK_HAS_MULTIPLE_KERNELS, NOTEBOOK_OUTPUT_FOCUSED, INotebookDeltaDecoration } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { NotebookEditorExtensionsRegistry } from 'vs/workbench/contrib/notebook/browser/notebookEditorExtensions';
import { NotebookCellList } from 'vs/workbench/contrib/notebook/browser/view/notebookCellList';
@@ -69,6 +69,8 @@ export class NotebookEditorOptions extends EditorOptions {
}
}
const NotebookEditorActiveKernelCache = 'workbench.editor.notebook.activeKernel';
export class NotebookEditorWidget extends Disposable implements INotebookEditor {
static readonly ID: string = 'workbench.editor.notebook';
private static readonly EDITOR_MEMENTOS = new Map<string, EditorMemento<unknown>>();
@@ -98,6 +100,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
protected readonly _contributions: { [key: string]: INotebookEditorContribution; };
private _scrollBeyondLastLine: boolean;
private readonly _memento: Memento;
private readonly _activeKernelMemento: Memento;
private readonly _onDidFocusEmitter = this._register(new Emitter<void>());
public readonly onDidFocus = this._onDidFocusEmitter.event;
private _cellContextKeyManager: CellContextKeyManager | null = null;
@@ -150,6 +153,10 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
}
this._activeKernel = kernel;
const memento = this._activeKernelMemento.getMemento(StorageScope.GLOBAL);
memento[this.viewModel!.viewType] = this._activeKernel?.id;
this._activeKernelMemento.saveMemento();
this._onDidChangeKernel.fire();
}
@@ -197,6 +204,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
) {
super();
this._memento = new Memento(NotebookEditorWidget.ID, storageService);
this._activeKernelMemento = new Memento(NotebookEditorActiveKernelCache, storageService);
this._outputRenderer = new OutputRenderer(this, this.instantiationService);
this._contributions = {};
@@ -613,12 +621,17 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
private async _setKernelsFromProviders(provider: NotebookProviderInfo, kernels: INotebookKernelInfo2[], tokenSource: CancellationTokenSource) {
const rawAssociations = this.configurationService.getValue<NotebookKernelProviderAssociations>(notebookKernelProviderAssociationsSettingId) || [];
const userSetKernelProvider = rawAssociations.filter(e => e.viewType === this.viewModel?.viewType)[0]?.kernelProvider;
const memento = this._activeKernelMemento.getMemento(StorageScope.GLOBAL);
if (userSetKernelProvider) {
const filteredKernels = kernels.filter(kernel => kernel.extension.value === userSetKernelProvider);
if (filteredKernels.length) {
this.activeKernel = filteredKernels.find(kernel => kernel.isPreferred) || filteredKernels[0];
const cachedKernelId = memento[provider.id];
this.activeKernel =
filteredKernels.find(kernel => kernel.isPreferred)
|| filteredKernels.find(kernel => kernel.id === cachedKernelId)
|| filteredKernels[0];
} else {
this.activeKernel = undefined;
}
@@ -628,6 +641,9 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
await (this.activeKernel as INotebookKernelInfo2).resolve(this.viewModel!.uri, this.getId(), tokenSource.token); // {{SQL CARBON EDIT}} strict-null-checks
}
memento[provider.id] = this._activeKernel?.id;
this._activeKernelMemento.saveMemento();
tokenSource.dispose();
return;
}
@@ -635,10 +651,17 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
// choose a preferred kernel
const kernelsFromSameExtension = kernels.filter(kernel => kernel.extension.value === provider.providerExtensionId);
if (kernelsFromSameExtension.length) {
const preferedKernel = kernelsFromSameExtension.find(kernel => kernel.isPreferred) || kernelsFromSameExtension[0];
const cachedKernelId = memento[provider.id];
const preferedKernel = kernelsFromSameExtension.find(kernel => kernel.isPreferred)
|| kernelsFromSameExtension.find(kernel => kernel.id === cachedKernelId)
|| kernelsFromSameExtension[0];
this.activeKernel = preferedKernel;
await this._loadKernelPreloads(this.activeKernel.extensionLocation, this.activeKernel);
await preferedKernel.resolve(this.viewModel!.uri, this.getId(), tokenSource.token);
memento[provider.id] = this._activeKernel?.id;
this._activeKernelMemento.saveMemento();
tokenSource.dispose();
return;
}
@@ -1677,12 +1700,14 @@ registerThemingParticipant((theme, collector) => {
if (cellToolbarSeperator) {
collector.addRule(`.notebookOverlay .monaco-list-row > .monaco-toolbar { border: solid 1px ${cellToolbarSeperator}; }`);
collector.addRule(`.notebookOverlay .cell-bottom-toolbar-container .action-item { border: solid 1px ${cellToolbarSeperator} }`);
collector.addRule(`.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-collapsed-part { border-bottom: solid 1px ${cellToolbarSeperator} }`);
}
const focusedCellBackgroundColor = theme.getColor(focusedCellBackground);
if (focusedCellBackgroundColor) {
collector.addRule(`.notebookOverlay .code-cell-row.focused .cell-focus-indicator,
.notebookOverlay .markdown-cell-row.focused { background-color: ${focusedCellBackgroundColor} !important; }`);
collector.addRule(`.notebookOverlay .code-cell-row.focused.collapsed .cell-collapsed-part { background-color: ${focusedCellBackgroundColor} !important; }`);
}
const cellHoverBackgroundColor = theme.getColor(cellHoverBackground);
@@ -1690,6 +1715,8 @@ registerThemingParticipant((theme, collector) => {
collector.addRule(`.notebookOverlay .code-cell-row:not(.focused):hover .cell-focus-indicator,
.notebookOverlay .code-cell-row:not(.focused).cell-output-hover .cell-focus-indicator,
.notebookOverlay .markdown-cell-row:not(.focused):hover { background-color: ${cellHoverBackgroundColor} !important; }`);
collector.addRule(`.notebookOverlay .code-cell-row:not(.focused).cell-output-hover .cell-collapsed-part,
.notebookOverlay .code-cell-row:not(.focused):hover.collapsed .cell-collapsed-part { background-color: ${cellHoverBackgroundColor} !important; }`);
}
const focusedCellBorderColor = theme.getColor(focusedCellBorder);
@@ -1765,7 +1792,7 @@ registerThemingParticipant((theme, collector) => {
// Cell Margin
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > div.cell { margin: 0px ${CELL_MARGIN * 2}px 0px ${CELL_MARGIN}px; }`);
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > div.cell.code { margin-left: ${CODE_CELL_LEFT_MARGIN}px; }`);
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row { padding-top: ${EDITOR_TOP_MARGIN}px; }`);
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row { padding-top: ${CELL_TOP_MARGIN}px; }`);
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .markdown-cell-row { padding-bottom: ${CELL_BOTTOM_MARGIN}px; }`);
collector.addRule(`.notebookOverlay .output { margin: 0px ${CELL_MARGIN}px 0px ${CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER}px; }`);
collector.addRule(`.notebookOverlay .output { width: calc(100% - ${CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER + (CELL_MARGIN * 2)}px); }`);
@@ -1773,11 +1800,13 @@ registerThemingParticipant((theme, collector) => {
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > div.cell.markdown { padding-left: ${CELL_RUN_GUTTER}px; }`);
collector.addRule(`.notebookOverlay .cell .run-button-container { width: ${CELL_RUN_GUTTER}px; }`);
collector.addRule(`.notebookOverlay .cell-drag-image .cell-editor-container > div { padding: ${EDITOR_TOP_PADDING}px 16px ${EDITOR_BOTTOM_PADDING}px 16px; }`);
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-top { height: ${EDITOR_TOP_MARGIN}px; }`);
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-top { height: ${CELL_TOP_MARGIN}px; }`);
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-side { bottom: ${BOTTOM_CELL_TOOLBAR_HEIGHT}px; }`);
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row.code-cell-row .cell-focus-indicator-left { width: ${CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER}px; }`);
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row.markdown-cell-row .cell-focus-indicator-left { width: ${CODE_CELL_LEFT_MARGIN}px; }`);
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator.cell-focus-indicator-right { width: ${CELL_MARGIN * 2}px; }`);
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-bottom { height: ${CELL_BOTTOM_MARGIN}px; }`);
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row .cell-shadow-container-bottom { top: ${CELL_BOTTOM_MARGIN}px; }`);
collector.addRule(`.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.collapsed .cell-collapsed-part { margin-left: ${CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER}px; height: ${COLLAPSED_INDICATOR_HEIGHT}px; }`);
});

View File

@@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI, UriComponents } from 'vs/base/common/uri';
import { INotebookRendererInfo, IOutputRenderResponse, IOutputRenderRequest } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { joinPath } from 'vs/base/common/resources';
/**
* A 'stub' output renderer used when the contribution has an `entrypoint`
* property. Include the entrypoint as its reload and renders an empty string.
*/
export class PureNotebookOutputRenderer implements INotebookRendererInfo {
public readonly extensionId: ExtensionIdentifier;
public readonly extensionLocation: URI;
public readonly preloads: URI[];
constructor(public readonly id: string, extension: IExtensionDescription, entrypoint: string) {
this.extensionId = extension.identifier;
this.extensionLocation = extension.extensionLocation;
this.preloads = [joinPath(extension.extensionLocation, entrypoint)];
}
public render(uri: URI, request: IOutputRenderRequest<UriComponents>): Promise<IOutputRenderResponse<UriComponents> | undefined> {
return this.render2(uri, request);
}
public render2<T>(_uri: URI, request: IOutputRenderRequest<T>): Promise<IOutputRenderResponse<T> | undefined> {
return Promise.resolve({
items: request.items.map(cellInfo => ({
key: cellInfo.key,
outputs: cellInfo.outputs.map(output => ({
index: output.index,
outputId: output.outputId,
mimeType: output.mimeType,
handlerId: this.id,
// todo@connor4312: temp approach exploring this API:
transformedOutput: `<script class="vscode-pure-data" type="application/json">
${JSON.stringify({ mimeType: output.mimeType, output: output.output })}
</script>`
}))
}))
});
}
}

View File

@@ -31,6 +31,7 @@ import { generateUuid } from 'vs/base/common/uuid';
import { flatten } from 'vs/base/common/arrays';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { NotebookKernelProviderAssociationRegistry, updateNotebookKernelProvideAssociationSchema, NotebookViewTypesExtensionRegistry } from 'vs/workbench/contrib/notebook/browser/notebookKernelAssociation';
import { PureNotebookOutputRenderer } from 'vs/workbench/contrib/notebook/browser/notebookPureOutputRenderer';
function MODEL_ID(resource: URI): string {
return resource.toString();
@@ -287,8 +288,12 @@ export class NotebookService extends Disposable implements INotebookService, ICu
this.notebookRenderersInfoStore.add(new NotebookOutputRendererInfo({
id: notebookContribution.viewType,
displayName: notebookContribution.displayName,
mimeTypes: notebookContribution.mimeTypes || []
mimeTypes: notebookContribution.mimeTypes || [],
}));
if (notebookContribution.entrypoint) {
this._notebookRenderers.set(notebookContribution.viewType, new PureNotebookOutputRenderer(notebookContribution.viewType, extension.description, notebookContribution.entrypoint));
}
}
}
@@ -371,6 +376,8 @@ export class NotebookService extends Disposable implements INotebookService, ICu
const kernelChangeEventListener = provider.onDidChangeKernels(() => {
this._onDidChangeKernels.fire();
});
this._onDidChangeKernels.fire();
return toDisposable(() => {
kernelChangeEventListener.dispose();
d.dispose();
@@ -688,7 +695,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu
let orderMimeTypes: IOrderedMimeType[] = [];
sorted.forEach(mimeType => {
let handlers = this.findBestMatchedRenderer(mimeType);
let handlers = this._findBestMatchedRenderer(mimeType);
if (handlers.length) {
const handler = handlers[0];
@@ -732,7 +739,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu
};
}
findBestMatchedRenderer(mimeType: string): readonly NotebookOutputRendererInfo[] {
private _findBestMatchedRenderer(mimeType: string): readonly NotebookOutputRendererInfo[] {
return this.notebookRenderersInfoStore.getContributedRenderer(mimeType);
}

View File

@@ -4,10 +4,10 @@
*--------------------------------------------------------------------------------------------*/
import * as DOM from 'vs/base/browser/dom';
import { Action, IAction } from 'vs/base/common/actions';
import { BaseActionViewItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action, IAction, Separator } from 'vs/base/common/actions';
import { IMenu, IMenuActionOptions, MenuItemAction, SubmenuItemAction } from 'vs/platform/actions/common/actions';
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
export class VerticalSeparator extends Action {
static readonly ID = 'vs.actions.verticalSeparator';

View File

@@ -6,7 +6,7 @@
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { INotebookTextModel, NotebookCellRunState } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { BaseCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel';
import { NOTEBOOK_CELL_TYPE, NOTEBOOK_VIEW_TYPE, NOTEBOOK_CELL_EDITABLE, NOTEBOOK_CELL_RUNNABLE, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE, NOTEBOOK_CELL_RUN_STATE, NOTEBOOK_CELL_HAS_OUTPUTS, CellViewModelStateChangeEvent, CellEditState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { NOTEBOOK_CELL_TYPE, NOTEBOOK_VIEW_TYPE, NOTEBOOK_CELL_EDITABLE, NOTEBOOK_CELL_RUNNABLE, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE, NOTEBOOK_CELL_RUN_STATE, NOTEBOOK_CELL_HAS_OUTPUTS, CellViewModelStateChangeEvent, CellEditState, NOTEBOOK_CELL_CONTENT_COLLAPSED, CellCollapseState, NOTEBOOK_CELL_OUTPUT_COLLAPSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
@@ -19,6 +19,8 @@ export class CellContextKeyManager extends Disposable {
private cellRunnable: IContextKey<boolean>;
private cellRunState: IContextKey<string>;
private cellHasOutputs: IContextKey<boolean>;
private cellContentCollapsed: IContextKey<boolean>;
private cellOutputCollapsed: IContextKey<boolean>;
private markdownEditMode: IContextKey<boolean>;
@@ -38,6 +40,8 @@ export class CellContextKeyManager extends Disposable {
this.markdownEditMode = NOTEBOOK_CELL_MARKDOWN_EDIT_MODE.bindTo(this.contextKeyService);
this.cellRunState = NOTEBOOK_CELL_RUN_STATE.bindTo(this.contextKeyService);
this.cellHasOutputs = NOTEBOOK_CELL_HAS_OUTPUTS.bindTo(this.contextKeyService);
this.cellContentCollapsed = NOTEBOOK_CELL_CONTENT_COLLAPSED.bindTo(this.contextKeyService);
this.cellOutputCollapsed = NOTEBOOK_CELL_OUTPUT_COLLAPSED.bindTo(this.contextKeyService);
this.updateForElement(element);
}
@@ -59,6 +63,7 @@ export class CellContextKeyManager extends Disposable {
this.updateForMetadata();
this.updateForEditState();
this.updateForCollapseState();
this.updateForOutputs();
this.viewType.set(this.element.viewType);
@@ -72,6 +77,10 @@ export class CellContextKeyManager extends Disposable {
if (e.editStateChanged) {
this.updateForEditState();
}
if (e.collapseStateChanged) {
this.updateForCollapseState();
}
}
private updateForMetadata() {
@@ -91,6 +100,11 @@ export class CellContextKeyManager extends Disposable {
}
}
private updateForCollapseState() {
this.cellContentCollapsed.set(this.element.collapseState === CellCollapseState.Collapsed);
this.cellOutputCollapsed.set(this.element.outputCollapseState === CellCollapseState.Collapsed);
}
private updateForOutputs() {
if (this.element instanceof CodeCellViewModel) {
this.cellHasOutputs.set(this.element.outputs.length > 0);

View File

@@ -27,8 +27,8 @@ import { ITextModel } from 'vs/editor/common/model';
import * as modes from 'vs/editor/common/modes';
import { tokenizeLineToHTML } from 'vs/editor/common/modes/textToHtmlTokenizer';
import { IModeService } from 'vs/editor/common/services/modeService';
import { ContextAwareMenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenu, MenuItemAction } from 'vs/platform/actions/common/actions';
import { MenuEntryActionViewItem, SubmenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenu, MenuItemAction, SubmenuItemAction } from 'vs/platform/actions/common/actions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
@@ -36,9 +36,9 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_BOTTOM_MARGIN, EDITOR_BOTTOM_PADDING, EDITOR_TOOLBAR_HEIGHT, EDITOR_TOP_MARGIN, EDITOR_TOP_PADDING } from 'vs/workbench/contrib/notebook/browser/constants';
import { BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_BOTTOM_MARGIN, CELL_TOP_MARGIN, EDITOR_BOTTOM_PADDING, EDITOR_TOOLBAR_HEIGHT, EDITOR_TOP_PADDING } from 'vs/workbench/contrib/notebook/browser/constants';
import { CancelCellAction, ChangeCellLanguageAction, ExecuteCellAction, INotebookCellActionContext } from 'vs/workbench/contrib/notebook/browser/contrib/coreActions';
import { BaseCellRenderTemplate, CellEditState, CodeCellRenderTemplate, ICellViewModel, INotebookCellList, INotebookEditor, isCodeCellRenderTemplate, MarkdownCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { BaseCellRenderTemplate, CellCollapseState, CellEditState, CodeCellRenderTemplate, ICellViewModel, INotebookCellList, INotebookEditor, isCodeCellRenderTemplate, MarkdownCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellContextKeyManager } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellContextKeys';
import { CellMenus } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellMenus';
import { CodeCell } from 'vs/workbench/contrib/notebook/browser/view/renderers/codeCell';
@@ -47,7 +47,7 @@ import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewMod
import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel';
import { CellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
import { CellKind, NotebookCellMetadata, NotebookCellRunState } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { VerticalSeparator, createAndFillInActionBarActionsWithVerticalSeparators, VerticalSeparatorViewItem } from './cellActionView';
import { createAndFillInActionBarActionsWithVerticalSeparators, VerticalSeparator, VerticalSeparatorViewItem } from './cellActionView';
const $ = DOM.$;
@@ -78,7 +78,7 @@ export class NotebookCellListDelegate implements IListVirtualDelegate<CellViewMo
}
}
export class CodiconActionViewItem extends ContextAwareMenuEntryActionViewItem {
export class CodiconActionViewItem extends MenuEntryActionViewItem {
constructor(
readonly _action: MenuItemAction,
keybindingService: IKeybindingService,
@@ -232,8 +232,9 @@ abstract class AbstractCellRenderer {
getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id),
actionViewItemProvider: action => {
if (action instanceof MenuItemAction) {
const item = new ContextAwareMenuEntryActionViewItem(action, this.keybindingService, this.notificationService, this.contextMenuService);
return item;
return this.instantiationService.createInstance(MenuEntryActionViewItem, action);
} else if (action instanceof SubmenuItemAction) {
return this.instantiationService.createInstance(SubmenuEntryActionViewItem, action);
}
if (action.id === VerticalSeparator.ID) {
@@ -270,14 +271,14 @@ abstract class AbstractCellRenderer {
if (actions.primary.length || actions.secondary.length) {
templateData.container.classList.add('cell-has-toolbar-actions');
if (isCodeCellRenderTemplate(templateData)) {
templateData.focusIndicator.style.top = `${EDITOR_TOOLBAR_HEIGHT + EDITOR_TOP_MARGIN}px`;
templateData.focusIndicatorRight.style.top = `${EDITOR_TOOLBAR_HEIGHT + EDITOR_TOP_MARGIN}px`;
templateData.focusIndicator.style.top = `${EDITOR_TOOLBAR_HEIGHT + CELL_TOP_MARGIN}px`;
templateData.focusIndicatorRight.style.top = `${EDITOR_TOOLBAR_HEIGHT + CELL_TOP_MARGIN}px`;
}
} else {
templateData.container.classList.remove('cell-has-toolbar-actions');
if (isCodeCellRenderTemplate(templateData)) {
templateData.focusIndicator.style.top = `${EDITOR_TOP_MARGIN}px`;
templateData.focusIndicatorRight.style.top = `${EDITOR_TOP_MARGIN}px`;
templateData.focusIndicator.style.top = `${CELL_TOP_MARGIN}px`;
templateData.focusIndicatorRight.style.top = `${CELL_TOP_MARGIN}px`;
}
}
};
@@ -298,6 +299,8 @@ abstract class AbstractCellRenderer {
this.notebookEditor.selectElement(templateData.currentRenderedCell);
}
}, true));
this.setupCollapsedPart(templateData);
}
protected commonRenderElement(element: ICellViewModel, index: number, templateData: BaseCellRenderTemplate): void {
@@ -307,6 +310,18 @@ abstract class AbstractCellRenderer {
templateData.container.classList.remove(DRAGGING_CLASS);
}
}
protected setupCollapsedPart(templateData: BaseCellRenderTemplate): void {
templateData.collapsedPart.innerHTML = renderCodicons('$(unfold)');
DOM.hide(templateData.collapsedPart);
templateData.disposables.add(domEvent(templateData.collapsedPart, DOM.EventType.CLICK)(() => {
if (!templateData.currentRenderedCell) {
return;
}
templateData.currentRenderedCell.collapseState = CellCollapseState.Normal;
}));
}
}
export class MarkdownCellRenderer extends AbstractCellRenderer implements IListRenderer<MarkdownCellViewModel, MarkdownCellRenderTemplate> {
@@ -344,7 +359,9 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
editorPart.style.display = 'none';
const innerContent = DOM.append(container, $('.cell.markdown'));
const foldingIndicator = DOM.append(focusIndicator, DOM.$('.notebook-folding-indicator'));
const foldingIndicator = DOM.append(container, DOM.$('.notebook-folding-indicator'));
const collapsedPart = DOM.append(container, $('.cell.cell-collapsed-part'));
const bottomCellContainer = DOM.append(container, $('.cell-bottom-toolbar-container'));
const betweenCellToolbar = disposables.add(this.createBetweenCellToolbar(bottomCellContainer, disposables, contextKeyService));
@@ -353,6 +370,7 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
const titleMenu = disposables.add(this.cellMenus.getCellTitleMenu(contextKeyService));
const templateData: MarkdownCellRenderTemplate = {
collapsedPart,
contextKeyService,
container,
cellContainer: innerContent,
@@ -925,6 +943,8 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
disposables.add(this.editorOptions.onDidChange(newValue => editor.updateOptions(newValue)));
const collapsedPart = DOM.append(container, $('.cell.cell-collapsed-part'));
const progressBar = new ProgressBar(editorPart);
progressBar.hide();
disposables.add(progressBar);
@@ -946,6 +966,8 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
const titleMenu = disposables.add(this.cellMenus.getCellTitleMenu(contextKeyService));
const templateData: CodeCellRenderTemplate = {
editorPart,
collapsedPart,
contextKeyService,
container,
cellContainer,

View File

@@ -11,7 +11,7 @@ import { IModeService } from 'vs/editor/common/services/modeService';
import * as nls from 'vs/nls';
import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { EDITOR_BOTTOM_PADDING, EDITOR_TOP_PADDING } from 'vs/workbench/contrib/notebook/browser/constants';
import { CellFocusMode, CodeCellRenderTemplate, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellCollapseState, CellFocusMode, CodeCellRenderTemplate, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
import { getResizesObserver } from 'vs/workbench/contrib/notebook/browser/view/renderers/sizeObserver';
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
@@ -84,14 +84,20 @@ export class CodeCell extends Disposable {
DOM.toggleClass(templateData.container, 'cell-editor-focus', viewCell.focusMode === CellFocusMode.Editor);
};
const updateForCollapseState = () => {
this.viewUpdate();
};
this._register(viewCell.onDidChangeState((e) => {
if (!e.focusModeChanged) {
return;
if (e.focusModeChanged) {
updateForFocusMode();
}
updateForFocusMode();
if (e.collapseStateChanged) {
updateForCollapseState();
}
}));
updateForFocusMode();
updateForCollapseState();
templateData.editor?.updateOptions({ readOnly: !(viewCell.getEvaluatedMetadata(notebookEditor.viewModel!.metadata).editable) });
this._register(viewCell.onDidChangeState((e) => {
@@ -101,22 +107,24 @@ export class CodeCell extends Disposable {
}));
this._register(viewCell.onDidChangeState((e) => {
if (!e.languageChanged) {
return;
if (e.languageChanged) {
const mode = this._modeService.create(viewCell.language);
templateData.editor?.getModel()?.setMode(mode.languageIdentifier);
}
const mode = this._modeService.create(viewCell.language);
templateData.editor?.getModel()?.setMode(mode.languageIdentifier);
if (e.collapseStateChanged) {
// meh
this.viewCell.layoutChange({});
this.relayoutCell();
}
}));
this._register(viewCell.onDidChangeLayout((e) => {
if (e.outerWidth === undefined) {
return;
}
const layoutInfo = templateData.editor!.getLayoutInfo();
if (layoutInfo.width !== viewCell.layoutInfo.editorWidth) {
this.onCellWidthChange();
if (e.outerWidth !== undefined) {
const layoutInfo = templateData.editor!.getLayoutInfo();
if (layoutInfo.width !== viewCell.layoutInfo.editorWidth) {
this.onCellWidthChange();
}
}
}));
@@ -249,6 +257,14 @@ export class CodeCell extends Disposable {
}
});
this._register(templateData.editor!.onMouseDown(e => {
// prevent default on right mouse click, otherwise it will trigger unexpected focus changes
// the catch is, it means we don't allow customization of right button mouse down handlers other than the built in ones.
if (e.event.rightButton) {
e.event.preventDefault();
}
}));
const updateFocusMode = () => viewCell.focusMode = templateData.editor!.hasWidgetFocus() ? CellFocusMode.Editor : CellFocusMode.Container;
this._register(templateData.editor!.onDidFocusEditorWidget(() => {
updateFocusMode();
@@ -291,6 +307,30 @@ export class CodeCell extends Disposable {
}
}
private viewUpdate(): void {
if (this.viewCell.collapseState === CellCollapseState.Collapsed) {
this.viewUpdateCollapsed();
} else {
this.viewUpdateExpanded();
}
}
private viewUpdateCollapsed(): void {
DOM.hide(this.templateData.cellContainer);
DOM.show(this.templateData.collapsedPart);
this.templateData.container.classList.toggle('collapsed', true);
this.relayoutCell();
}
private viewUpdateExpanded(): void {
DOM.show(this.templateData.cellContainer);
DOM.hide(this.templateData.collapsedPart);
this.templateData.container.classList.toggle('collapsed', false);
this.relayoutCell();
}
private layoutEditor(dimension: IDimension): void {
this.templateData.editor?.layout(dimension);
this.templateData.statusBarContainer.style.width = `${dimension.width}px`;

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { hide, IDimension, show, toggleClass, addClass, removeClass } from 'vs/base/browser/dom';
import * as DOM from 'vs/base/browser/dom';
import { raceCancellation } from 'vs/base/common/async';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { renderCodicons } from 'vs/base/common/codicons';
@@ -12,7 +12,7 @@ import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { EDITOR_BOTTOM_PADDING, EDITOR_TOP_PADDING } from 'vs/workbench/contrib/notebook/browser/constants';
import { CellEditState, CellFocusMode, INotebookEditor, MarkdownCellRenderTemplate, ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellEditState, CellFocusMode, INotebookEditor, MarkdownCellRenderTemplate, ICellViewModel, CellCollapseState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellFoldingState } from 'vs/workbench/contrib/notebook/browser/contrib/fold/foldingModel';
import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
@@ -50,7 +50,7 @@ export class StatefulMarkdownCell extends Disposable {
if (e.editStateChanged) {
this.localDisposables.clear();
this.viewUpdate();
} else if (e.contentChanged) {
} else if (e.contentChanged || e.collapseStateChanged) {
this.viewUpdate();
}
}));
@@ -66,7 +66,7 @@ export class StatefulMarkdownCell extends Disposable {
this.focusEditorIfNeeded();
}
toggleClass(templateData.container, 'cell-editor-focus', viewCell.focusMode === CellFocusMode.Editor);
templateData.container.classList.toggle('cell-editor-focus', viewCell.focusMode === CellFocusMode.Editor);
};
this._register(viewCell.onDidChangeState((e) => {
if (!e.focusModeChanged) {
@@ -105,13 +105,13 @@ export class StatefulMarkdownCell extends Disposable {
this._register(viewCell.onCellDecorationsChanged((e) => {
e.added.forEach(options => {
if (options.className) {
addClass(templateData.container, options.className);
DOM.addClass(templateData.container, options.className);
}
});
e.removed.forEach(options => {
if (options.className) {
removeClass(templateData.container, options.className);
DOM.removeClass(templateData.container, options.className);
}
});
}));
@@ -120,7 +120,7 @@ export class StatefulMarkdownCell extends Disposable {
viewCell.getCellDecorations().forEach(options => {
if (options.className) {
addClass(templateData.container, options.className);
DOM.addClass(templateData.container, options.className);
}
});
@@ -128,19 +128,31 @@ export class StatefulMarkdownCell extends Disposable {
}
private viewUpdate(): void {
if (this.viewCell.editState === CellEditState.Editing) {
if (this.viewCell.collapseState === CellCollapseState.Collapsed) {
this.viewUpdateCollapsed();
} else if (this.viewCell.editState === CellEditState.Editing) {
this.viewUpdateEditing();
} else {
this.viewUpdatePreview();
}
}
private viewUpdateCollapsed(): void {
DOM.show(this.templateData.collapsedPart);
DOM.hide(this.editorPart);
DOM.hide(this.markdownContainer);
this.templateData.container.classList.toggle('collapsed', true);
}
private viewUpdateEditing(): void {
// switch to editing mode
let editorHeight: number;
show(this.editorPart);
hide(this.markdownContainer);
DOM.show(this.editorPart);
DOM.hide(this.markdownContainer);
DOM.hide(this.templateData.collapsedPart);
this.templateData.container.classList.toggle('collapsed', false);
if (this.editor) {
editorHeight = this.editor!.getContentHeight();
@@ -216,8 +228,11 @@ export class StatefulMarkdownCell extends Disposable {
private viewUpdatePreview(): void {
this.viewCell.detachTextEditor();
hide(this.editorPart);
show(this.markdownContainer);
DOM.hide(this.editorPart);
DOM.hide(this.templateData.collapsedPart);
DOM.show(this.markdownContainer);
this.templateData.container.classList.toggle('collapsed', false);
this.renderedEditors.delete(this.viewCell);
this.markdownContainer.innerHTML = '';
@@ -259,7 +274,7 @@ export class StatefulMarkdownCell extends Disposable {
}
}
private layoutEditor(dimension: IDimension): void {
private layoutEditor(dimension: DOM.IDimension): void {
this.editor?.layout(dimension);
this.templateData.statusBarContainer.style.width = `${dimension.width}px`;
}

View File

@@ -261,6 +261,8 @@ function webviewPreloads() {
interface ICreateCellInfo {
outputId: string;
output?: unknown;
mimeType?: string;
element: HTMLElement;
}
@@ -374,10 +376,21 @@ function webviewPreloads() {
outputNode.innerHTML = content;
cellOutputContainer.appendChild(outputNode);
let pureData: { mimeType: string, output: unknown } | undefined;
const outputScript = cellOutputContainer.querySelector('script.vscode-pure-data');
if (outputScript) {
try { pureData = JSON.parse(outputScript.innerHTML); } catch { }
}
// eval
domEval(outputNode);
resizeObserve(outputNode, outputId);
onDidCreateOutput.fire([data.apiNamespace, { element: outputNode, outputId }]);
onDidCreateOutput.fire([data.apiNamespace, {
element: outputNode,
output: pureData?.output,
mimeType: pureData?.mimeType,
outputId
}]);
vscode.postMessage({
__vscode_notebook_message: true,

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
@@ -14,7 +13,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon';
import * as model from 'vs/editor/common/model';
import { SearchParams } from 'vs/editor/common/model/textModelSearch';
import { EDITOR_TOP_PADDING } from 'vs/workbench/contrib/notebook/browser/constants';
import { CellEditState, CellFocusMode, CursorAtBoundary, CellViewModelStateChangeEvent, IEditableCellViewModel, INotebookCellDecorationOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellEditState, CellFocusMode, CursorAtBoundary, CellViewModelStateChangeEvent, IEditableCellViewModel, INotebookCellDecorationOptions, CellCollapseState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellKind, NotebookCellMetadata, NotebookDocumentMetadata, INotebookSearchOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
@@ -61,13 +60,24 @@ export abstract class BaseCellViewModel extends Disposable {
}
}
private _currentTokenSource: CancellationTokenSource | undefined;
public set currentTokenSource(v: CancellationTokenSource | undefined) {
this._currentTokenSource = v;
private _collapseState: CellCollapseState = CellCollapseState.Normal;
public get collapseState(): CellCollapseState {
return this._collapseState;
}
public get currentTokenSource(): CancellationTokenSource | undefined {
return this._currentTokenSource;
public set collapseState(v: CellCollapseState) {
this._collapseState = v;
this._onDidChangeState.fire({ collapseStateChanged: true });
}
private _outputCollapseState: CellCollapseState = CellCollapseState.Normal;
public get outputCollapseState(): CellCollapseState {
return this._outputCollapseState;
}
public set outputCollapseState(v: CellCollapseState) {
this._collapseState = v;
this._onDidChangeState.fire({ collapseStateChanged: true });
}
private _focusMode: CellFocusMode = CellFocusMode.Container;

View File

@@ -8,8 +8,8 @@ import * as UUID from 'vs/base/common/uuid';
import * as editorCommon from 'vs/editor/common/editorCommon';
import * as model from 'vs/editor/common/model';
import { PrefixSumComputer } from 'vs/editor/common/viewModel/prefixSumComputer';
import { BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_MARGIN, CELL_RUN_GUTTER, CELL_STATUSBAR_HEIGHT, EDITOR_BOTTOM_PADDING, EDITOR_TOOLBAR_HEIGHT, EDITOR_TOP_MARGIN, EDITOR_TOP_PADDING, CELL_BOTTOM_MARGIN, CODE_CELL_LEFT_MARGIN, BOTTOM_CELL_TOOLBAR_OFFSET } from 'vs/workbench/contrib/notebook/browser/constants';
import { CellEditState, CellFindMatch, CodeCellLayoutChangeEvent, CodeCellLayoutInfo, ICellViewModel, NotebookLayoutInfo, CodeCellLayoutState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_MARGIN, CELL_RUN_GUTTER, CELL_STATUSBAR_HEIGHT, EDITOR_BOTTOM_PADDING, EDITOR_TOOLBAR_HEIGHT, CELL_TOP_MARGIN, EDITOR_TOP_PADDING, CELL_BOTTOM_MARGIN, CODE_CELL_LEFT_MARGIN, BOTTOM_CELL_TOOLBAR_OFFSET, COLLAPSED_INDICATOR_HEIGHT } from 'vs/workbench/contrib/notebook/browser/constants';
import { CellEditState, CellFindMatch, CodeCellLayoutChangeEvent, CodeCellLayoutInfo, ICellViewModel, NotebookLayoutInfo, CodeCellLayoutState, CellCollapseState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
import { CellKind, NotebookCellOutputsSplice, INotebookSearchOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { BaseCellViewModel } from './baseCellViewModel';
@@ -101,42 +101,61 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
this._ensureOutputsTop();
const outputTotalHeight = this._outputsTop!.getTotalValue();
let newState: CodeCellLayoutState;
let editorHeight: number;
let totalHeight: number;
if (!state.editorHeight && this._layoutInfo.layoutState === CodeCellLayoutState.FromCache) {
// No new editorHeight info - keep cached totalHeight and estimate editorHeight
editorHeight = this.estimateEditorHeight(state.font?.lineHeight);
totalHeight = this._layoutInfo.totalHeight;
newState = CodeCellLayoutState.FromCache;
} else if (state.editorHeight || this._layoutInfo.layoutState === CodeCellLayoutState.Measured) {
// Editor has been measured
editorHeight = this._editorHeight;
totalHeight = this.computeTotalHeight(this._editorHeight, outputTotalHeight);
newState = CodeCellLayoutState.Measured;
if (this.collapseState === CellCollapseState.Normal) {
let newState: CodeCellLayoutState;
let editorHeight: number;
let totalHeight: number;
if (!state.editorHeight && this._layoutInfo.layoutState === CodeCellLayoutState.FromCache) {
// No new editorHeight info - keep cached totalHeight and estimate editorHeight
editorHeight = this.estimateEditorHeight(state.font?.lineHeight);
totalHeight = this._layoutInfo.totalHeight;
newState = CodeCellLayoutState.FromCache;
} else if (state.editorHeight || this._layoutInfo.layoutState === CodeCellLayoutState.Measured) {
// Editor has been measured
editorHeight = this._editorHeight;
totalHeight = this.computeTotalHeight(this._editorHeight, outputTotalHeight);
newState = CodeCellLayoutState.Measured;
} else {
editorHeight = this.estimateEditorHeight(state.font?.lineHeight);
totalHeight = this.computeTotalHeight(editorHeight, outputTotalHeight);
newState = CodeCellLayoutState.Estimated;
}
const indicatorHeight = editorHeight + CELL_STATUSBAR_HEIGHT + outputTotalHeight;
const outputContainerOffset = EDITOR_TOOLBAR_HEIGHT + CELL_TOP_MARGIN + editorHeight + CELL_STATUSBAR_HEIGHT;
const bottomToolbarOffset = totalHeight - BOTTOM_CELL_TOOLBAR_HEIGHT - BOTTOM_CELL_TOOLBAR_OFFSET;
const editorWidth = state.outerWidth !== undefined ? this.computeEditorWidth(state.outerWidth) : this._layoutInfo?.editorWidth;
this._layoutInfo = {
fontInfo: state.font || null,
editorHeight,
editorWidth,
outputContainerOffset,
outputTotalHeight,
totalHeight,
indicatorHeight,
bottomToolbarOffset,
layoutState: newState
};
} else {
editorHeight = this.estimateEditorHeight(state.font?.lineHeight);
totalHeight = this.computeTotalHeight(editorHeight, outputTotalHeight);
newState = CodeCellLayoutState.Estimated;
const indicatorHeight = COLLAPSED_INDICATOR_HEIGHT + outputTotalHeight;
const outputContainerOffset = CELL_TOP_MARGIN + COLLAPSED_INDICATOR_HEIGHT;
const totalHeight = CELL_TOP_MARGIN + COLLAPSED_INDICATOR_HEIGHT + CELL_BOTTOM_MARGIN + BOTTOM_CELL_TOOLBAR_HEIGHT + outputTotalHeight;
const bottomToolbarOffset = totalHeight - BOTTOM_CELL_TOOLBAR_HEIGHT - BOTTOM_CELL_TOOLBAR_OFFSET;
this._layoutInfo = {
fontInfo: state.font || null,
editorHeight: this._layoutInfo.editorHeight,
editorWidth: this._layoutInfo.editorWidth,
outputContainerOffset,
outputTotalHeight,
totalHeight,
indicatorHeight,
bottomToolbarOffset,
layoutState: this._layoutInfo.layoutState
};
}
const indicatorHeight = editorHeight + CELL_STATUSBAR_HEIGHT + outputTotalHeight;
const outputContainerOffset = EDITOR_TOOLBAR_HEIGHT + EDITOR_TOP_MARGIN + editorHeight + CELL_STATUSBAR_HEIGHT;
const bottomToolbarOffset = totalHeight - BOTTOM_CELL_TOOLBAR_HEIGHT - BOTTOM_CELL_TOOLBAR_OFFSET;
const editorWidth = state.outerWidth !== undefined ? this.computeEditorWidth(state.outerWidth) : this._layoutInfo?.editorWidth;
this._layoutInfo = {
fontInfo: state.font || null,
editorHeight,
editorWidth,
outputContainerOffset,
outputTotalHeight,
totalHeight,
indicatorHeight,
bottomToolbarOffset,
layoutState: newState
};
if (state.editorHeight || state.outputHeight) {
state.totalHeight = true;
}
@@ -188,7 +207,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
}
private computeTotalHeight(editorHeight: number, outputsTotalHeight: number): number {
return EDITOR_TOOLBAR_HEIGHT + EDITOR_TOP_MARGIN + editorHeight + CELL_STATUSBAR_HEIGHT + outputsTotalHeight + BOTTOM_CELL_TOOLBAR_HEIGHT + CELL_BOTTOM_MARGIN;
return EDITOR_TOOLBAR_HEIGHT + CELL_TOP_MARGIN + editorHeight + CELL_STATUSBAR_HEIGHT + outputsTotalHeight + BOTTOM_CELL_TOOLBAR_HEIGHT + CELL_BOTTOM_MARGIN;
}
/**

View File

@@ -8,8 +8,8 @@ import { Emitter, Event } from 'vs/base/common/event';
import * as UUID from 'vs/base/common/uuid';
import * as editorCommon from 'vs/editor/common/editorCommon';
import * as model from 'vs/editor/common/model';
import { BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_MARGIN, CELL_STATUSBAR_HEIGHT, EDITOR_TOP_MARGIN, CELL_BOTTOM_MARGIN, CODE_CELL_LEFT_MARGIN, BOTTOM_CELL_TOOLBAR_OFFSET } from 'vs/workbench/contrib/notebook/browser/constants';
import { CellFindMatch, ICellViewModel, MarkdownCellLayoutChangeEvent, MarkdownCellLayoutInfo, NotebookLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_MARGIN, CELL_STATUSBAR_HEIGHT, CELL_TOP_MARGIN, CELL_BOTTOM_MARGIN, CODE_CELL_LEFT_MARGIN, BOTTOM_CELL_TOOLBAR_OFFSET, COLLAPSED_INDICATOR_HEIGHT } from 'vs/workbench/contrib/notebook/browser/constants';
import { CellCollapseState, CellFindMatch, ICellViewModel, MarkdownCellLayoutChangeEvent, MarkdownCellLayoutInfo, NotebookLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { MarkdownRenderer } from 'vs/workbench/contrib/notebook/browser/view/renderers/mdRenderer';
import { BaseCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel';
import { EditorFoldingStateDelegate } from 'vs/workbench/contrib/notebook/browser/contrib/fold/foldingModel';
@@ -45,7 +45,7 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
set editorHeight(newHeight: number) {
this._editorHeight = newHeight;
this.totalHeight = this._editorHeight + EDITOR_TOP_MARGIN + CELL_BOTTOM_MARGIN + BOTTOM_CELL_TOOLBAR_HEIGHT + CELL_STATUSBAR_HEIGHT;
this.totalHeight = this._editorHeight + CELL_TOP_MARGIN + CELL_BOTTOM_MARGIN + BOTTOM_CELL_TOOLBAR_HEIGHT + CELL_STATUSBAR_HEIGHT;
}
get editorHeight() {
@@ -92,16 +92,31 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
layoutChange(state: MarkdownCellLayoutChangeEvent) {
// recompute
const editorWidth = state.outerWidth !== undefined ? this.computeEditorWidth(state.outerWidth) : this._layoutInfo.editorWidth;
const totalHeight = state.totalHeight === undefined ? this._layoutInfo.totalHeight : state.totalHeight;
this._layoutInfo = {
fontInfo: state.font || this._layoutInfo.fontInfo,
editorWidth,
editorHeight: this._editorHeight,
bottomToolbarOffset: totalHeight - BOTTOM_CELL_TOOLBAR_HEIGHT - BOTTOM_CELL_TOOLBAR_OFFSET,
totalHeight
};
if (this.collapseState === CellCollapseState.Normal) {
const editorWidth = state.outerWidth !== undefined ? this.computeEditorWidth(state.outerWidth) : this._layoutInfo.editorWidth;
const totalHeight = state.totalHeight === undefined ? this._layoutInfo.totalHeight : state.totalHeight;
this._layoutInfo = {
fontInfo: state.font || this._layoutInfo.fontInfo,
editorWidth,
editorHeight: this._editorHeight,
bottomToolbarOffset: totalHeight - BOTTOM_CELL_TOOLBAR_HEIGHT - BOTTOM_CELL_TOOLBAR_OFFSET,
totalHeight
};
} else {
const editorWidth = state.outerWidth !== undefined ? this.computeEditorWidth(state.outerWidth) : this._layoutInfo.editorWidth;
const totalHeight = CELL_TOP_MARGIN + COLLAPSED_INDICATOR_HEIGHT + BOTTOM_CELL_TOOLBAR_HEIGHT + CELL_BOTTOM_MARGIN;
state.totalHeight = totalHeight;
this._layoutInfo = {
fontInfo: state.font || this._layoutInfo.fontInfo,
editorWidth,
editorHeight: this._editorHeight,
bottomToolbarOffset: totalHeight - BOTTOM_CELL_TOOLBAR_HEIGHT - BOTTOM_CELL_TOOLBAR_OFFSET,
totalHeight
};
}
this._onDidChangeLayout.fire(state);
}

View File

@@ -4,9 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import * as dom from 'vs/base/browser/dom';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
import { Action, IAction, RadioGroup } from 'vs/base/common/actions';
import { Action, IAction, RadioGroup, Separator } from 'vs/base/common/actions';
import { createCancelablePromise, TimeoutTimer } from 'vs/base/common/async';
import { isPromiseCanceledError } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';

View File

@@ -4,8 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { IAction } from 'vs/base/common/actions';
import { IActionViewItem, SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IAction, IActionViewItem } from 'vs/base/common/actions';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
@@ -37,6 +36,7 @@ import { groupBy } from 'vs/base/common/arrays';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { editorBackground, selectBorder } from 'vs/platform/theme/common/colorRegistry';
import { addClass } from 'vs/base/browser/dom';
import { SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
export class OutputViewPane extends ViewPane {

View File

@@ -12,8 +12,8 @@ import { dispose, Disposable, IDisposable, combinedDisposable, DisposableStore }
import { CheckboxActionViewItem } from 'vs/base/browser/ui/checkbox/checkbox';
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel';
import { IAction, Action } from 'vs/base/common/actions';
import { ActionBar, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { IAction, Action, Separator } from 'vs/base/common/actions';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { EditorOptions } from 'vs/workbench/common/editor';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';

View File

@@ -3,9 +3,8 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ContextSubMenu } from 'vs/base/browser/contextmenu';
import { EventHelper, getDomNodePagePosition } from 'vs/base/browser/dom';
import { IAction } from 'vs/base/common/actions';
import { IAction, SubmenuAction } from 'vs/base/common/actions';
import { Delayer } from 'vs/base/common/async';
import { Emitter, Event } from 'vs/base/common/event';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
@@ -826,7 +825,7 @@ class EditSettingRenderer extends Disposable {
const anchor = { x: e.event.posx, y: e.event.posy + 10 };
const actions = this.getSettings(editPreferenceWidget.getLine()).length === 1 ? this.getActions(editPreferenceWidget.preferences[0], this.getConfigurationsMap()[editPreferenceWidget.preferences[0].key])
: editPreferenceWidget.preferences.map(setting => new ContextSubMenu(setting.key, this.getActions(setting, this.getConfigurationsMap()[setting.key])));
: editPreferenceWidget.preferences.map(setting => new SubmenuAction(`preferences.submenu.${setting.key}`, setting.key, this.getActions(setting, this.getConfigurationsMap()[setting.key])));
this.contextMenuService.showContextMenu({
getAnchor: () => anchor,
getActions: () => actions

View File

@@ -5,7 +5,7 @@
import * as DOM from 'vs/base/browser/dom';
import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { ActionBar, ActionsOrientation, BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionBar, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { IInputOptions, InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
import { Widget } from 'vs/base/browser/ui/widget';
import { Action, IAction } from 'vs/base/common/actions';
@@ -36,6 +36,7 @@ import { ISettingsGroup, IPreferencesService } from 'vs/workbench/services/prefe
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { isEqual } from 'vs/base/common/resources';
import { registerIcon, Codicon } from 'vs/base/common/codicons';
import { BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
export class SettingsHeaderWidget extends Widget implements IViewZone {

View File

@@ -8,7 +8,6 @@ import * as DOM from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { renderMarkdown } from 'vs/base/browser/markdownRenderer';
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { alert as ariaAlert } from 'vs/base/browser/ui/aria/aria';
import { Button } from 'vs/base/browser/ui/button/button';
import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox';
@@ -20,7 +19,7 @@ import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { IObjectTreeOptions, ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
import { ITreeFilter, ITreeModel, ITreeNode, ITreeRenderer, TreeFilterResult, TreeVisibility } from 'vs/base/browser/ui/tree/tree';
import { Action, IAction } from 'vs/base/common/actions';
import { Action, IAction, Separator } from 'vs/base/common/actions';
import * as arrays from 'vs/base/common/arrays';
import { Color, RGBA } from 'vs/base/common/color';
import { onUnexpectedError } from 'vs/base/common/errors';

View File

@@ -7,7 +7,6 @@ import * as nls from 'vs/nls';
import * as dom from 'vs/base/browser/dom';
import { IAction, Action } from 'vs/base/common/actions';
import { SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { attachSelectBoxStyler } from 'vs/platform/theme/common/styler';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
@@ -19,6 +18,7 @@ import { isStringArray } from 'vs/base/common/types';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
export interface IRemoteSelectItem extends ISelectOptionItem {
authority: string[];

View File

@@ -21,11 +21,11 @@ import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { ITreeRenderer, ITreeNode, IAsyncDataSource, ITreeContextMenuEvent, ITreeMouseEvent } from 'vs/base/browser/ui/tree/tree';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { Disposable, IDisposable, toDisposable, MutableDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
import { ActionBar, ActionViewItem, IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel';
import { ActionRunner, IAction } from 'vs/base/common/actions';
import { IMenuService, MenuId, IMenu, MenuRegistry, MenuItemAction, ILocalizedString } from 'vs/platform/actions/common/actions';
import { createAndFillInContextMenuActions, createAndFillInActionBarActions, ContextAwareMenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenuService, MenuId, IMenu, MenuRegistry, MenuItemAction, ILocalizedString, SubmenuItemAction } from 'vs/platform/actions/common/actions';
import { createAndFillInContextMenuActions, createAndFillInActionBarActions, MenuEntryActionViewItem, SubmenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IRemoteExplorerService, TunnelModel, MakeAddress, TunnelType, ITunnelItem, Tunnel } from 'vs/workbench/services/remote/common/remoteExplorerService';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
@@ -41,6 +41,7 @@ import { RemoteTunnel } from 'vs/platform/remote/common/tunnel';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
export const forwardedPortsViewEnabled = new RawContextKey<boolean>('forwardedPortsViewEnabled', false);
@@ -213,10 +214,11 @@ class TunnelTreeRenderer extends Disposable implements ITreeRenderer<ITunnelGrou
// dom.addClass(iconLabel.element, 'tunnel-view-label');
const actionsContainer = dom.append(iconLabel.element, dom.$('.actions'));
const actionBar = new ActionBar(actionsContainer, {
// actionViewItemProvider: undefined // this.actionViewItemProvider
actionViewItemProvider: (action: IAction) => {
if (action instanceof MenuItemAction) {
return this.instantiationService.createInstance(ContextAwareMenuEntryActionViewItem, action);
return this.instantiationService.createInstance(MenuEntryActionViewItem, action);
} else if (action instanceof SubmenuItemAction) {
return this.instantiationService.createInstance(SubmenuEntryActionViewItem, action);
}
return undefined;
@@ -451,7 +453,6 @@ export class TunnelPanel extends ViewPane {
@IQuickInputService protected quickInputService: IQuickInputService,
@ICommandService protected commandService: ICommandService,
@IMenuService private readonly menuService: IMenuService,
@INotificationService private readonly notificationService: INotificationService,
@IContextViewService private readonly contextViewService: IContextViewService,
@IThemeService themeService: IThemeService,
@IRemoteExplorerService private readonly remoteExplorerService: IRemoteExplorerService,
@@ -647,10 +648,6 @@ export class TunnelPanel extends ViewPane {
super.layoutBody(height, width);
this.tree.layout(height, width);
}
getActionViewItem(action: IAction): IActionViewItem | undefined {
return action instanceof MenuItemAction ? new ContextAwareMenuEntryActionViewItem(action, this.keybindingService, this.notificationService, this.contextMenuService) : undefined;
}
}
export class TunnelPanelDescriptor implements IViewDescriptor {

View File

@@ -34,19 +34,17 @@ import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/co
import { EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget';
import { IDiffEditorOptions, EditorOption } from 'vs/editor/common/config/editorOptions';
import { Action, IAction, ActionRunner } from 'vs/base/common/actions';
import { IActionBarOptions, ActionsOrientation, IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IActionBarOptions, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { basename, isEqualOrParent } from 'vs/base/common/resources';
import { MenuId, IMenuService, IMenu, MenuItemAction, MenuRegistry } from 'vs/platform/actions/common/actions';
import { createAndFillInActionBarActions, ContextAwareMenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IChange, IEditorModel, ScrollType, IEditorContribution, IDiffEditorModel } from 'vs/editor/common/editorCommon';
import { OverviewRulerLane, ITextModel, IModelDecorationOptions, MinimapPosition } from 'vs/editor/common/model';
import { sortedDiff, firstIndex } from 'vs/base/common/arrays';
import { IMarginData } from 'vs/editor/browser/controller/mouseTarget';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { ISplice } from 'vs/base/common/sequence';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { createStyleSheet } from 'vs/base/browser/dom';
import { ITextFileEditorModel, IResolvedTextFileEditorModel, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { EncodingMode } from 'vs/workbench/common/editor';
@@ -176,14 +174,11 @@ class DirtyDiffWidget extends PeekViewWidget {
editor: ICodeEditor,
private model: DirtyDiffModel,
@IThemeService private readonly themeService: IThemeService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IInstantiationService instantiationService: IInstantiationService,
@IMenuService menuService: IMenuService,
@IKeybindingService private readonly keybindingService: IKeybindingService,
@INotificationService private readonly notificationService: INotificationService,
@IContextKeyService contextKeyService: IContextKeyService,
@IContextMenuService private readonly contextMenuService: IContextMenuService
@IContextKeyService contextKeyService: IContextKeyService
) {
super(editor, { isResizeable: true, frameWidth: 1, keepEditorSelection: true });
super(editor, { isResizeable: true, frameWidth: 1, keepEditorSelection: true }, instantiationService);
this._disposables.add(themeService.onDidColorThemeChange(this._applyTheme, this));
this._applyTheme(themeService.getColorTheme());
@@ -274,20 +269,12 @@ class DirtyDiffWidget extends PeekViewWidget {
});
return {
...super._getActionBarOptions(),
actionRunner,
actionViewItemProvider: action => this.getActionViewItem(action),
orientation: ActionsOrientation.HORIZONTAL_REVERSE
};
}
getActionViewItem(action: IAction): IActionViewItem | undefined {
if (!(action instanceof MenuItemAction)) {
return undefined;
}
return new ContextAwareMenuEntryActionViewItem(action, this.keybindingService, this.notificationService, this.contextMenuService);
}
protected _fillBody(container: HTMLElement): void {
const options: IDiffEditorOptions = {
scrollBeyondLastLine: true,

View File

@@ -123,7 +123,6 @@ export class SCMRepositoryMenus implements IDisposable {
disposable.dispose();
menu.dispose();
contextKeyService.dispose();
if (this.provider.rootUri) {
secondary.push(new Action('_openInTerminal', localize('open in terminal', "Open In Terminal"), undefined, true, async () => {
@@ -157,7 +156,6 @@ export class SCMRepositoryMenus implements IDisposable {
createAndFillInContextMenuActions(menu, { shouldForwardArgs: true }, result, this.contextMenuService, g => /^inline/.test(g));
menu.dispose();
contextKeyService.dispose();
return result;
}

View File

@@ -20,17 +20,15 @@ import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/c
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { MenuItemAction, IMenuService } from 'vs/platform/actions/common/actions';
import { IAction, IActionViewItem, ActionRunner, Action, RadioGroup } from 'vs/base/common/actions';
import { ContextAwareMenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IAction, IActionViewItem, ActionRunner, Action, RadioGroup, Separator, SubmenuAction, IActionViewItemProvider } from 'vs/base/common/actions';
import { SCMMenus } from './menus';
import { ActionBar, IActionViewItemProvider, Separator, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { IThemeService, LIGHT, registerThemingParticipant, IFileIconTheme } from 'vs/platform/theme/common/themeService';
import { isSCMResource, isSCMResourceGroup, connectPrimaryMenuToInlineActionBar, isSCMRepository, isSCMInput, connectPrimaryMenu } from './util';
import { attachBadgeStyler } from 'vs/platform/theme/common/styler';
import { WorkbenchCompressibleObjectTree, IOpenEvent } from 'vs/platform/list/browser/listService';
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { disposableTimeout, ThrottledDelayer } from 'vs/base/common/async';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ITreeNode, ITreeFilter, ITreeSorter, ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree';
import { ResourceTree, IResourceNode } from 'vs/base/common/resourceTree';
import { ISequence, ISplice, SimpleSequence } from 'vs/base/common/sequence';
@@ -72,7 +70,6 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
import { IModeService } from 'vs/editor/common/services/modeService';
import { ILabelService } from 'vs/platform/label/common/label';
import { ContextSubMenu } from 'vs/base/browser/contextmenu';
import { KeyCode } from 'vs/base/common/keyCodes';
import { DEFAULT_FONT_FAMILY } from 'vs/workbench/browser/style';
import { Command } from 'vs/editor/common/modes';
@@ -81,6 +78,7 @@ import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
import { domEvent } from 'vs/base/browser/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
type TreeElement = ISCMRepository | ISCMInput | ISCMResourceGroup | IResourceNode<ISCMResource, ISCMResourceGroup> | ISCMResource;
@@ -1102,7 +1100,7 @@ class ViewModel {
const viewAction = new SCMViewSubMenuAction(this);
if (this.repositories.elements.length !== 1) {
return viewAction.entries;
return Array.isArray(viewAction.actions) ? viewAction.actions : viewAction.actions();
}
const menus = this.menus.getRepositoryMenus(this.repositories.elements[0].provider);
@@ -1167,9 +1165,11 @@ class ViewModel {
}
}
class SCMViewSubMenuAction extends ContextSubMenu {
class SCMViewSubMenuAction extends SubmenuAction {
constructor(viewModel: ViewModel) {
super(localize('sortAction', "View & Sort"),
super(
'scm.viewsort',
localize('sortAction', "View & Sort"),
[
...new RadioGroup([
new SCMViewModeListAction(viewModel),
@@ -1591,7 +1591,6 @@ export class SCMViewPane extends ViewPane {
@IContextMenuService protected contextMenuService: IContextMenuService,
@IContextViewService protected contextViewService: IContextViewService,
@ICommandService protected commandService: ICommandService,
@INotificationService private readonly notificationService: INotificationService,
@IEditorService protected editorService: IEditorService,
@IInstantiationService protected instantiationService: IInstantiationService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@@ -1768,11 +1767,7 @@ export class SCMViewPane extends ViewPane {
return new StatusBarActionViewItem(action);
}
if (!(action instanceof MenuItemAction)) {
return undefined;
}
return new ContextAwareMenuEntryActionViewItem(action, this.keybindingService, this.notificationService, this.contextMenuService);
return super.getActionViewItem(action);
}
getActionsContext(): any {

View File

@@ -80,6 +80,7 @@ import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cance
import { IViewsService, IViewDescriptorService } from 'vs/workbench/common/views';
import { isWorkspaceFolder, TaskQuickPickEntry, QUICKOPEN_DETAIL_CONFIG, TaskQuickPick, QUICKOPEN_SKIP_CONFIG } from 'vs/workbench/contrib/tasks/browser/taskQuickPick';
import { ILogService } from 'vs/platform/log/common/log';
import { once } from 'vs/base/common/functional';
const QUICKOPEN_HISTORY_LIMIT_CONFIG = 'task.quickOpen.history';
const PROBLEM_MATCHER_NEVER_CONFIG = 'task.problemMatchers.neverPrompt';
@@ -223,6 +224,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
protected _outputChannel: IOutputChannel;
protected readonly _onDidStateChange: Emitter<TaskEvent>;
private _waitForSupportedExecutions: Promise<void>;
private _onDidRegisterSupportedExecutions: Emitter<void> = new Emitter();
constructor(
@IConfigurationService private readonly configurationService: IConfigurationService,
@@ -331,16 +334,26 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}
return task._label;
});
this.setExecutionContexts();
this._waitForSupportedExecutions = new Promise(resolve => {
once(this._onDidRegisterSupportedExecutions.event)(() => resolve());
});
}
protected setExecutionContexts(custom: boolean = true, shell: boolean = true, process: boolean = true): void {
const customContext = CustomExecutionSupportedContext.bindTo(this.contextKeyService);
customContext.set(custom);
const shellContext = ShellExecutionSupportedContext.bindTo(this.contextKeyService);
shellContext.set(shell);
const processContext = ProcessExecutionSupportedContext.bindTo(this.contextKeyService);
processContext.set(process);
public registerSupportedExecutions(custom?: boolean, shell?: boolean, process?: boolean) {
if (custom !== undefined) {
const customContext = CustomExecutionSupportedContext.bindTo(this.contextKeyService);
customContext.set(custom);
}
if (shell !== undefined) {
const shellContext = ShellExecutionSupportedContext.bindTo(this.contextKeyService);
shellContext.set(shell);
}
if (process !== undefined) {
const processContext = ProcessExecutionSupportedContext.bindTo(this.contextKeyService);
processContext.set(process);
}
this._onDidRegisterSupportedExecutions.fire();
}
public get onDidStateChange(): Event<TaskEvent> {
@@ -530,9 +543,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}
public registerTaskSystem(key: string, info: TaskSystemInfo): void {
if (info.platform === Platform.Platform.Web) {
this.setExecutionContexts(true, false, false);
}
this._taskSystemInfos.set(key, info);
}
@@ -834,7 +844,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
this.openerService.open(URI.parse('https://go.microsoft.com/fwlink/?LinkId=733558'));
}
public build(): Promise<ITaskSummary> {
public async build(): Promise<ITaskSummary> {
return this.getGroupedTasks().then((tasks) => {
let runnable = this.createRunnableTask(tasks, TaskGroup.Build);
if (!runnable || !runnable.task) {
@@ -844,7 +854,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
throw new TaskError(Severity.Info, nls.localize('TaskService.noBuildTask2', 'No build task defined. Mark a task with as a \'build\' group in the tasks.json file.'), TaskErrors.NoBuildTask);
}
}
return this.executeTask(runnable.task, runnable.resolver);
return this.executeTask(runnable.task, runnable.resolver, TaskRunSource.User);
}).then(value => value, (error) => {
this.handleError(error);
return Promise.reject(error);
@@ -861,7 +871,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
throw new TaskError(Severity.Info, nls.localize('TaskService.noTestTask2', 'No test task defined. Mark a task with as a \'test\' group in the tasks.json file.'), TaskErrors.NoTestTask);
}
}
return this.executeTask(runnable.task, runnable.resolver);
return this.executeTask(runnable.task, runnable.resolver, TaskRunSource.User);
}).then(value => value, (error) => {
this.handleError(error);
return Promise.reject(error);
@@ -878,7 +888,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
if (options && options.attachProblemMatcher && this.shouldAttachProblemMatcher(task) && !InMemoryTask.is(task)) {
const toExecute = await this.attachProblemMatcher(task);
if (toExecute) {
resolve(this.executeTask(toExecute, resolver));
resolve(this.executeTask(toExecute, resolver, runSource));
} else {
resolve(undefined);
}
@@ -1452,7 +1462,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
};
}
private executeTask(task: Task, resolver: ITaskResolver, runSource?: TaskRunSource): Promise<ITaskSummary> {
private executeTask(task: Task, resolver: ITaskResolver, runSource: TaskRunSource): Promise<ITaskSummary> {
enum SaveBeforeRunConfigOptions {
Always = 'always',
Never = 'never',
@@ -1831,7 +1841,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
return result;
}
public getWorkspaceTasks(runSource: TaskRunSource = TaskRunSource.User): Promise<Map<string, WorkspaceFolderTaskResult>> {
public async getWorkspaceTasks(runSource: TaskRunSource = TaskRunSource.User): Promise<Map<string, WorkspaceFolderTaskResult>> {
await this._waitForSupportedExecutions;
if (this._workspaceTasksPromise) {
return this._workspaceTasksPromise;
}

View File

@@ -528,7 +528,7 @@ export class TerminalTaskSystem implements ITaskSystem {
}
}
private resolveVariablesFromSet(taskSystemInfo: TaskSystemInfo | undefined, workspaceFolder: IWorkspaceFolder | undefined, task: CustomTask | ContributedTask, variables: Set<string>, alreadyResolved: Map<string, string>): Promise<ResolvedVariables> {
private resolveVariablesFromSet(taskSystemInfo: TaskSystemInfo | undefined, workspaceFolder: IWorkspaceFolder | undefined, task: CustomTask | ContributedTask, variables: Set<string>, alreadyResolved: Map<string, string>): Promise<ResolvedVariables | undefined> {
let isProcess = task.command && task.command.runtime === RuntimeType.Process;
let options = task.command && task.command.options ? task.command.options : undefined;
let cwd = options ? options.cwd : undefined;
@@ -544,7 +544,7 @@ export class TerminalTaskSystem implements ITaskSystem {
}
}
const unresolved = this.findUnresolvedVariables(variables, alreadyResolved);
let resolvedVariables: Promise<ResolvedVariables>;
let resolvedVariables: Promise<ResolvedVariables | undefined>;
if (taskSystemInfo && workspaceFolder) {
let resolveSet: ResolveSet = {
variables: unresolved
@@ -560,6 +560,10 @@ export class TerminalTaskSystem implements ITaskSystem {
}
}
resolvedVariables = taskSystemInfo.resolveVariables(workspaceFolder, resolveSet, TaskSourceKind.toConfigurationTarget(task._source.kind)).then(async (resolved) => {
if (!resolved) {
return undefined;
}
this.mergeMaps(alreadyResolved, resolved.variables);
resolved.variables = new Map(alreadyResolved);
if (isProcess) {
@@ -569,14 +573,14 @@ export class TerminalTaskSystem implements ITaskSystem {
}
resolved.variables.set(TerminalTaskSystem.ProcessVarName, process);
}
return Promise.resolve(resolved);
return resolved;
});
return resolvedVariables;
} else {
let variablesArray = new Array<string>();
unresolved.forEach(variable => variablesArray.push(variable));
return new Promise((resolve, reject) => {
return new Promise<ResolvedVariables | undefined>((resolve, reject) => {
this.configurationResolverService.resolveWithInteraction(workspaceFolder, variablesArray, 'tasks', undefined, TaskSourceKind.toConfigurationTarget(task._source.kind)).then(async (resolvedVariablesMap: Map<string, string> | undefined) => {
if (resolvedVariablesMap) {
this.mergeMaps(alreadyResolved, resolvedVariablesMap);
@@ -657,6 +661,9 @@ export class TerminalTaskSystem implements ITaskSystem {
if (!hasAllVariables) {
return this.resolveVariablesFromSet(lastTask.getVerifiedTask().systemInfo, lastTask.getVerifiedTask().workspaceFolder, task, variables, alreadyResolved).then((resolvedVariables) => {
if (!resolvedVariables) {
return { exitCode: 0 };
}
this.currentTask.resolvedVariables = resolvedVariables;
return this.executeInTerminal(task, trigger, new VariableResolver(lastTask.getVerifiedTask().workspaceFolder, lastTask.getVerifiedTask().systemInfo, resolvedVariables.variables, this.configurationResolverService), workspaceFolder!);
}, reason => {

View File

@@ -95,6 +95,7 @@ export interface ITaskService {
registerTaskProvider(taskProvider: ITaskProvider, type: string): IDisposable;
registerTaskSystem(scheme: string, taskSystemInfo: TaskSystemInfo): void;
registerSupportedExecutions(custom?: boolean, shell?: boolean, process?: boolean): void;
setJsonTasksSupported(areSuppored: Promise<boolean>): void;
extensionCallbackTaskComplete(task: Task, result: number | undefined): Promise<void>;

View File

@@ -119,7 +119,7 @@ export interface TaskSystemInfo {
platform: Platform;
context: any;
uriProvider: (this: void, path: string) => URI;
resolveVariables(workspaceFolder: IWorkspaceFolder, toResolve: ResolveSet, target: ConfigurationTarget): Promise<ResolvedVariables>;
resolveVariables(workspaceFolder: IWorkspaceFolder, toResolve: ResolveSet, target: ConfigurationTarget): Promise<ResolvedVariables | undefined>;
getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }>;
findExecutable(command: string, cwd?: string, paths?: string[]): Promise<string | undefined>;
}

View File

@@ -7,7 +7,6 @@ import { Action, IAction } from 'vs/base/common/actions';
import { EndOfLinePreference } from 'vs/editor/common/model';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
import { TERMINAL_VIEW_ID, ITerminalConfigHelper, TitleEventSource, TERMINAL_COMMAND_ID, KEYBINDING_CONTEXT_TERMINAL_FIND_FOCUSED, TERMINAL_ACTION_CATEGORY, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, KEYBINDING_CONTEXT_TERMINAL_FIND_NOT_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS } from 'vs/workbench/contrib/terminal/common/terminal';
import { SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { attachSelectBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
@@ -39,6 +38,7 @@ import { localize } from 'vs/nls';
import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { ITerminalContributionService } from 'vs/workbench/contrib/terminal/common/terminalExtensionPoints';
import { SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
async function getCwdForSplit(configHelper: ITerminalConfigHelper, instance: ITerminalInstance, folders?: IWorkspaceFolder[], commandService?: ICommandService): Promise<string | URI | undefined> {
switch (configHelper.config.splitCwd) {

View File

@@ -6,8 +6,7 @@
import * as dom from 'vs/base/browser/dom';
import * as nls from 'vs/nls';
import * as platform from 'vs/base/common/platform';
import { Action, IAction } from 'vs/base/common/actions';
import { IActionViewItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action, IAction, Separator, IActionViewItem } from 'vs/base/common/actions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';

View File

@@ -6,7 +6,7 @@
import 'vs/css!./media/timelinePane';
import { localize } from 'vs/nls';
import * as DOM from 'vs/base/browser/dom';
import { IAction, ActionRunner } from 'vs/base/common/actions';
import { IAction, ActionRunner, IActionViewItemProvider } from 'vs/base/common/actions';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { fromNow } from 'vs/base/common/date';
import { debounce } from 'vs/base/common/decorators';
@@ -36,10 +36,11 @@ import { IThemeService, LIGHT, ThemeIcon } from 'vs/platform/theme/common/themeS
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { IProgressService } from 'vs/platform/progress/common/progress';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IActionViewItemProvider, ActionBar, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { ContextAwareMenuEntryActionViewItem, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { MenuItemAction, IMenuService, MenuId, registerAction2, Action2, MenuRegistry } from 'vs/platform/actions/common/actions';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { MenuEntryActionViewItem, createAndFillInContextMenuActions, SubmenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { MenuItemAction, IMenuService, MenuId, registerAction2, Action2, MenuRegistry, SubmenuItemAction } from 'vs/platform/actions/common/actions';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
const ItemHeight = 22;
@@ -1092,9 +1093,15 @@ class TimelineTreeRenderer implements ITreeRenderer<TreeElement, FuzzyScore, Tim
@IInstantiationService protected readonly instantiationService: IInstantiationService,
@IThemeService private themeService: IThemeService
) {
this.actionViewItemProvider = (action: IAction) => action instanceof MenuItemAction
? this.instantiationService.createInstance(ContextAwareMenuEntryActionViewItem, action)
: undefined;
this.actionViewItemProvider = (action: IAction) => {
if (action instanceof MenuItemAction) {
return this.instantiationService.createInstance(MenuEntryActionViewItem, action);
} else if (action instanceof SubmenuItemAction) {
return this.instantiationService.createInstance(SubmenuEntryActionViewItem, action);
}
return undefined;
};
}
private uri: URI | undefined;
@@ -1239,7 +1246,6 @@ class TimelinePaneCommands extends Disposable {
createAndFillInContextMenuActions(menu, { shouldForwardArgs: true }, result, this.contextMenuService, g => /^inline/.test(g));
menu.dispose();
scoped.dispose();
return result;
}

View File

@@ -7,11 +7,11 @@ import 'vs/css!./media/views';
import { Event, Emitter } from 'vs/base/common/event';
import { IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IAction, ActionRunner } from 'vs/base/common/actions';
import { IAction, ActionRunner, IActionViewItemProvider } from 'vs/base/common/actions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IMenuService, MenuId, MenuItemAction, registerAction2, Action2 } from 'vs/platform/actions/common/actions';
import { ContextAwareMenuEntryActionViewItem, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenuService, MenuId, MenuItemAction, registerAction2, Action2, SubmenuItemAction } from 'vs/platform/actions/common/actions';
import { MenuEntryActionViewItem, createAndFillInContextMenuActions, SubmenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IContextKeyService, ContextKeyExpr, ContextKeyEqualsExpr, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { ITreeView, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ITreeItemLabel, IViewDescriptorService, ViewContainer, ViewContainerLocation, ResolvableTreeItem } from 'vs/workbench/common/views';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -21,7 +21,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
import { ICommandService } from 'vs/platform/commands/common/commands';
import * as DOM from 'vs/base/browser/dom';
import { ResourceLabels, IResourceLabel } from 'vs/workbench/browser/labels';
import { ActionBar, IActionViewItemProvider, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { URI } from 'vs/base/common/uri';
import { dirname, basename } from 'vs/base/common/resources';
import { LIGHT, FileThemeIcon, FolderThemeIcon, registerThemingParticipant, ThemeIcon, IThemeService } from 'vs/platform/theme/common/themeService';
@@ -39,6 +39,7 @@ import { CollapseAllAction } from 'vs/base/browser/ui/tree/treeDefaults';
import { isFalsyOrWhitespace } from 'vs/base/common/strings';
import { SIDE_BAR_BACKGROUND, PANEL_BACKGROUND } from 'vs/workbench/common/theme';
import { IHoverService, IHoverOptions } from 'vs/workbench/services/hover/browser/hover';
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
class Root implements ITreeItem {
label = { label: 'root' };
@@ -349,7 +350,15 @@ export class TreeView extends Disposable implements ITreeView {
}
private createTree() {
const actionViewItemProvider = (action: IAction) => action instanceof MenuItemAction ? this.instantiationService.createInstance(ContextAwareMenuEntryActionViewItem, action) : undefined;
const actionViewItemProvider = (action: IAction) => {
if (action instanceof MenuItemAction) {
return this.instantiationService.createInstance(MenuEntryActionViewItem, action);
} else if (action instanceof SubmenuItemAction) {
return this.instantiationService.createInstance(SubmenuEntryActionViewItem, action);
}
return undefined;
};
const treeMenus = this._register(this.instantiationService.createInstance(TreeMenus, this.id));
this.treeLabels = this._register(this.instantiationService.createInstance(ResourceLabels, this));
const dataSource = this.instantiationService.createInstance(TreeDataSource, this, <T>(task: Promise<T>) => this.progressService.withProgress({ location: this.id }, () => task));
@@ -980,7 +989,6 @@ class TreeMenus extends Disposable implements IDisposable {
createAndFillInContextMenuActions(menu, { shouldForwardArgs: true }, result, this.contextMenuService, g => /^inline/.test(g));
menu.dispose();
contextKeyService.dispose();
return result;
}