Merge from vscode 966b87dd4013be1a9c06e2b8334522ec61905cc2 (#4696)
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/callHierarchy';
|
||||
import { PeekViewWidget } from 'vs/editor/contrib/referenceSearch/peekViewWidget';
|
||||
import { PeekViewWidget, IPeekViewService } from 'vs/editor/contrib/referenceSearch/peekViewWidget';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { CallHierarchyProvider, CallHierarchyDirection, CallHierarchyItem } from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';
|
||||
@@ -106,6 +106,7 @@ export class CallHierarchyTreePeekWidget extends PeekViewWidget {
|
||||
private readonly _provider: CallHierarchyProvider,
|
||||
private _direction: CallHierarchyDirection,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IPeekViewService private readonly _peekViewService: IPeekViewService,
|
||||
@IEditorService private readonly _editorService: IEditorService,
|
||||
@ITextModelService private readonly _textModelService: ITextModelService,
|
||||
@ILabelService private readonly _labelService: ILabelService,
|
||||
@@ -114,6 +115,7 @@ export class CallHierarchyTreePeekWidget extends PeekViewWidget {
|
||||
) {
|
||||
super(editor, { showFrame: true, showArrow: true, isResizeable: true, isAccessible: true });
|
||||
this.create();
|
||||
this._peekViewService.addExclusiveWidget(editor, this);
|
||||
this._applyTheme(themeService.getTheme());
|
||||
themeService.onThemeChange(this._applyTheme, this, this._disposables);
|
||||
}
|
||||
|
||||
@@ -32,10 +32,11 @@
|
||||
background-position: left center;
|
||||
}
|
||||
|
||||
.monaco-workbench .call-hierarchy .monaco-split-view2.horizontal > .split-view-container > .split-view-view{
|
||||
.monaco-workbench .call-hierarchy .monaco-split-view2.horizontal > .split-view-container > .split-view-view {
|
||||
/* this is a little bizare.. */
|
||||
height: unset;
|
||||
}
|
||||
.monaco-workbench .call-hierarchy .tree{
|
||||
|
||||
.monaco-workbench .call-hierarchy .tree {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
||||
import { inputValidationErrorBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { attachButtonStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { ICommentService } from 'vs/workbench/contrib/comments/electron-browser/commentService';
|
||||
import { SimpleCommentEditor } from 'vs/workbench/contrib/comments/electron-browser/simpleCommentEditor';
|
||||
import { ICommentService } from 'vs/workbench/contrib/comments/browser/commentService';
|
||||
import { SimpleCommentEditor } from 'vs/workbench/contrib/comments/browser/simpleCommentEditor';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
@@ -13,7 +13,7 @@ import { keys } from 'vs/base/common/map';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { ICommentThreadChangedEvent } from 'vs/workbench/contrib/comments/common/commentModel';
|
||||
import { MainThreadCommentController } from 'vs/workbench/api/electron-browser/mainThreadComments';
|
||||
import { MainThreadCommentController } from 'vs/workbench/api/browser/mainThreadComments';
|
||||
|
||||
export const ICommentService = createDecorator<ICommentService>('commentService');
|
||||
|
||||
@@ -65,8 +65,8 @@ export interface ICommentService {
|
||||
deleteReaction(owner: string, resource: URI, comment: Comment, reaction: CommentReaction): Promise<void>;
|
||||
getReactionGroup(owner: string): CommentReaction[] | undefined;
|
||||
toggleReaction(owner: string, resource: URI, thread: CommentThread2, comment: Comment, reaction: CommentReaction): Promise<void>;
|
||||
setActiveCommentThread(commentThread: CommentThread | null);
|
||||
setInput(input: string);
|
||||
setActiveCommentThread(commentThread: CommentThread | null): void;
|
||||
setInput(input: string): void;
|
||||
}
|
||||
|
||||
export class CommentService extends Disposable implements ICommentService {
|
||||
@@ -19,20 +19,20 @@ import { peekViewBorder } from 'vs/editor/contrib/referenceSearch/referencesWidg
|
||||
import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/zoneWidget';
|
||||
import { attachButtonStyler } from 'vs/platform/theme/common/styler';
|
||||
import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { CommentGlyphWidget } from 'vs/workbench/contrib/comments/electron-browser/commentGlyphWidget';
|
||||
import { CommentGlyphWidget } from 'vs/workbench/contrib/comments/browser/commentGlyphWidget';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { SimpleCommentEditor } from './simpleCommentEditor';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { transparent, editorForeground, textLinkActiveForeground, textLinkForeground, focusBorder, textBlockQuoteBackground, textBlockQuoteBorder, contrastBorder, inputValidationErrorBorder, inputValidationErrorBackground, inputValidationErrorForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { ICommentService } from 'vs/workbench/contrib/comments/electron-browser/commentService';
|
||||
import { ICommentService } from 'vs/workbench/contrib/comments/browser/commentService';
|
||||
import { Range, IRange } from 'vs/editor/common/core/range';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { MarkdownRenderer } from 'vs/editor/contrib/markdown/markdownRenderer';
|
||||
import { IMarginData } from 'vs/editor/browser/controller/mouseTarget';
|
||||
import { CommentNode } from 'vs/workbench/contrib/comments/electron-browser/commentNode';
|
||||
import { CommentNode } from 'vs/workbench/contrib/comments/browser/commentNode';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
@@ -6,8 +6,8 @@
|
||||
import * as nls from 'vs/nls';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import 'vs/workbench/contrib/comments/electron-browser/commentsEditorContribution';
|
||||
import { ICommentService, CommentService } from 'vs/workbench/contrib/comments/electron-browser/commentService';
|
||||
import 'vs/workbench/contrib/comments/browser/commentsEditorContribution';
|
||||
import { ICommentService, CommentService } from 'vs/workbench/contrib/comments/browser/commentService';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
|
||||
export interface ICommentsConfiguration {
|
||||
@@ -21,20 +21,19 @@ import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiati
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { editorForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { CommentThreadCollapsibleState } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { ReviewZoneWidget, COMMENTEDITOR_DECORATION_KEY } from 'vs/workbench/contrib/comments/electron-browser/commentThreadWidget';
|
||||
import { ICommentService, ICommentInfo } from 'vs/workbench/contrib/comments/electron-browser/commentService';
|
||||
import { ReviewZoneWidget, COMMENTEDITOR_DECORATION_KEY } from 'vs/workbench/contrib/comments/browser/commentThreadWidget';
|
||||
import { ICommentService, ICommentInfo } from 'vs/workbench/contrib/comments/browser/commentService';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
import { IModelDecorationOptions } from 'vs/editor/common/model';
|
||||
import { IMarginData } from 'vs/editor/browser/controller/mouseTarget';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { CancelablePromise, createCancelablePromise, Delayer } from 'vs/base/common/async';
|
||||
import { overviewRulerCommentingRangeForeground } from 'vs/workbench/contrib/comments/electron-browser/commentGlyphWidget';
|
||||
import { overviewRulerCommentingRangeForeground } from 'vs/workbench/contrib/comments/browser/commentGlyphWidget';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { STATUS_BAR_ITEM_HOVER_BACKGROUND, STATUS_BAR_ITEM_ACTIVE_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ctxCommentEditorFocused, SimpleCommentEditor } from 'vs/workbench/contrib/comments/electron-browser/simpleCommentEditor';
|
||||
import { ctxCommentEditorFocused, SimpleCommentEditor } from 'vs/workbench/contrib/comments/browser/simpleCommentEditor';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
|
||||
export const ctxCommentThreadVisible = new RawContextKey<boolean>('commentThreadVisible', false);
|
||||
@@ -472,7 +471,7 @@ export class ReviewController implements IEditorContribution {
|
||||
endColumn: 0
|
||||
},
|
||||
reply: replyCommand,
|
||||
collapsibleState: CommentThreadCollapsibleState.Expanded,
|
||||
collapsibleState: modes.CommentThreadCollapsibleState.Expanded,
|
||||
}, pendingComment, draftMode);
|
||||
|
||||
this.localToDispose.push(this._newCommentWidget!.onDidClose(e => {
|
||||
@@ -596,6 +595,7 @@ export class ReviewController implements IEditorContribution {
|
||||
const args = replyCommand.arguments || [];
|
||||
|
||||
this._commandService.executeCommand(commandId, ...args);
|
||||
this._addInProgress = false;
|
||||
}
|
||||
} else if (commentingRangesInfo.newCommentThreadCallback) {
|
||||
return commentingRangesInfo.newCommentThreadCallback(this.editor.getModel().uri, range)
|
||||
@@ -610,11 +610,13 @@ export class ReviewController implements IEditorContribution {
|
||||
} else {
|
||||
const commentInfo = this._commentInfos.filter(info => info.owner === ownerId);
|
||||
if (!commentInfo || !commentInfo.length) {
|
||||
this._addInProgress = false;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const draftMode = commentInfo[0].draftMode;
|
||||
this.addComment(lineNumber, replyCommand, ownerId, extensionId, draftMode, null);
|
||||
this._addInProgress = false;
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
@@ -15,9 +15,9 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { Panel } from 'vs/workbench/browser/panel';
|
||||
import { CommentNode, CommentsModel, ResourceWithCommentThreads, ICommentThreadChangedEvent } from 'vs/workbench/contrib/comments/common/commentModel';
|
||||
import { ReviewController } from 'vs/workbench/contrib/comments/electron-browser/commentsEditorContribution';
|
||||
import { CommentsDataFilter, CommentsDataSource, CommentsModelRenderer } from 'vs/workbench/contrib/comments/electron-browser/commentsTreeViewer';
|
||||
import { ICommentService, IWorkspaceCommentThreadsEvent } from 'vs/workbench/contrib/comments/electron-browser/commentService';
|
||||
import { ReviewController } from 'vs/workbench/contrib/comments/browser/commentsEditorContribution';
|
||||
import { CommentsDataFilter, CommentsDataSource, CommentsModelRenderer } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer';
|
||||
import { ICommentService, IWorkspaceCommentThreadsEvent } from 'vs/workbench/contrib/comments/browser/commentService';
|
||||
import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { textLinkForeground, textLinkActiveForeground, focusBorder, textPreformatForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
|
Before Width: | Height: | Size: 307 B After Width: | Height: | Size: 307 B |
|
Before Width: | Height: | Size: 293 B After Width: | Height: | Size: 293 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
@@ -126,7 +126,7 @@ export interface IExpressionTemplateData {
|
||||
name: HTMLSpanElement;
|
||||
value: HTMLSpanElement;
|
||||
inputBoxContainer: HTMLElement;
|
||||
enableInputBox(expression: IExpression, options: IInputBoxOptions);
|
||||
enableInputBox(expression: IExpression, options: IInputBoxOptions): void;
|
||||
toDispose: IDisposable[];
|
||||
label: HighlightedLabel;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ export class BreakpointsView extends ViewletPanel {
|
||||
], {
|
||||
identityProvider: { getId: (element: IEnablement) => element.getId() },
|
||||
multipleSelectionSupport: false,
|
||||
keyboardNavigationLabelProvider: { getKeyboardNavigationLabel: e => e }
|
||||
keyboardNavigationLabelProvider: { getKeyboardNavigationLabel: (e: IEnablement) => e }
|
||||
}) as WorkbenchList<IEnablement>;
|
||||
|
||||
CONTEXT_BREAKPOINTS_FOCUSED.bindTo(this.list.contextKeyService);
|
||||
|
||||
@@ -109,7 +109,7 @@ export class CallStackView extends ViewletPanel {
|
||||
accessibilityProvider: new CallStackAccessibilityProvider(),
|
||||
ariaLabel: nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'callStackAriaLabel' }, "Debug Call Stack"),
|
||||
identityProvider: {
|
||||
getId: element => {
|
||||
getId: (element: CallStackItem) => {
|
||||
if (typeof element === 'string') {
|
||||
return element;
|
||||
}
|
||||
@@ -117,11 +117,11 @@ export class CallStackView extends ViewletPanel {
|
||||
return `showMore ${element[0].getId()}`;
|
||||
}
|
||||
|
||||
return (<IStackFrame | IThread | IDebugSession | ThreadAndSessionIds>element).getId();
|
||||
return element.getId();
|
||||
}
|
||||
},
|
||||
keyboardNavigationLabelProvider: {
|
||||
getKeyboardNavigationLabel: e => {
|
||||
getKeyboardNavigationLabel: (e: CallStackItem) => {
|
||||
if (isDebugSession(e)) {
|
||||
return e.getLabel();
|
||||
}
|
||||
@@ -170,7 +170,7 @@ export class CallStackView extends ViewletPanel {
|
||||
focusStackFrame(undefined, undefined, element);
|
||||
}
|
||||
if (element instanceof ThreadAndSessionIds) {
|
||||
const session = this.debugService.getModel().getSessions().filter(p => p.getId() === element.sessionId).pop();
|
||||
const session = this.debugService.getModel().getSession(element.sessionId);
|
||||
const thread = session && session.getThread(element.threadId);
|
||||
if (thread) {
|
||||
(<Thread>thread).fetchCallStack()
|
||||
|
||||
@@ -125,7 +125,7 @@ export function registerCommands(): void {
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: STEP_INTO_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
weight: KeybindingWeight.WorkbenchContrib + 10, // Have a stronger weight to have priority over full screen when debugging
|
||||
primary: KeyCode.F11,
|
||||
when: CONTEXT_DEBUG_STATE.isEqualTo('stopped'),
|
||||
handler: (accessor: ServicesAccessor, _: string, thread: IThread | undefined) => {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/debugToolbar';
|
||||
import 'vs/css!./media/debugToolBar';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
@@ -46,14 +46,14 @@ export const debugToolBarBorder = registerColor('debugToolBar.border', {
|
||||
hc: null
|
||||
}, localize('debugToolBarBorder', "Debug toolbar border color."));
|
||||
|
||||
export class DebugToolbar extends Themable implements IWorkbenchContribution {
|
||||
export class DebugToolBar extends Themable implements IWorkbenchContribution {
|
||||
|
||||
private $el: HTMLElement;
|
||||
private dragArea: HTMLElement;
|
||||
private actionBar: ActionBar;
|
||||
private activeActions: IAction[];
|
||||
private updateScheduler: RunOnceScheduler;
|
||||
private debugToolbarMenu: IMenu;
|
||||
private debugToolBarMenu: IMenu;
|
||||
|
||||
private isVisible: boolean;
|
||||
private isBuilt: boolean;
|
||||
@@ -81,8 +81,8 @@ export class DebugToolbar extends Themable implements IWorkbenchContribution {
|
||||
this.dragArea = dom.append(this.$el, dom.$('div.drag-area'));
|
||||
|
||||
const actionBarContainer = dom.append(this.$el, dom.$('div.action-bar-container'));
|
||||
this.debugToolbarMenu = menuService.createMenu(MenuId.DebugToolbar, contextKeyService);
|
||||
this.toDispose.push(this.debugToolbarMenu);
|
||||
this.debugToolBarMenu = menuService.createMenu(MenuId.DebugToolBar, contextKeyService);
|
||||
this.toDispose.push(this.debugToolBarMenu);
|
||||
|
||||
this.activeActions = [];
|
||||
this.actionBar = this._register(new ActionBar(actionBarContainer, {
|
||||
@@ -106,7 +106,7 @@ export class DebugToolbar extends Themable implements IWorkbenchContribution {
|
||||
return this.hide();
|
||||
}
|
||||
|
||||
const actions = DebugToolbar.getActions(this.debugToolbarMenu, this.debugService, this.instantiationService);
|
||||
const actions = DebugToolBar.getActions(this.debugToolBarMenu, this.debugService, this.instantiationService);
|
||||
if (!arrays.equals(actions, this.activeActions, (first, second) => first.id === second.id)) {
|
||||
this.actionBar.clear();
|
||||
this.actionBar.push(actions, { icon: true, label: false });
|
||||
@@ -24,7 +24,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
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 { DebugToolBar } from 'vs/workbench/contrib/debug/browser/debugToolBar';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { ViewletPanel } from 'vs/workbench/browser/parts/views/panelViewlet';
|
||||
import { IMenu, MenuId, IMenuService, MenuItemAction } from 'vs/platform/actions/common/actions';
|
||||
@@ -40,7 +40,7 @@ export class DebugViewlet extends ViewContainerViewlet {
|
||||
private progressRunner: IProgressRunner;
|
||||
private breakpointView: ViewletPanel;
|
||||
private panelListeners = new Map<string, IDisposable>();
|
||||
private debugToolbarMenu: IMenu;
|
||||
private debugToolBarMenu: IMenu;
|
||||
|
||||
constructor(
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||
@@ -63,6 +63,7 @@ export class DebugViewlet extends ViewContainerViewlet {
|
||||
super(VIEWLET_ID, `${VIEWLET_ID}.state`, false, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService);
|
||||
|
||||
this._register(this.debugService.onDidChangeState(state => this.onDebugServiceStateChange(state)));
|
||||
this._register(this.debugService.onDidNewSession(() => this.updateToolBar()));
|
||||
this._register(this.contextService.onDidChangeWorkbenchState(() => this.updateTitleArea()));
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('debug.toolBarLocation')) {
|
||||
@@ -109,11 +110,11 @@ export class DebugViewlet extends ViewContainerViewlet {
|
||||
return [this.startAction, this.configureAction, this.toggleReplAction];
|
||||
}
|
||||
|
||||
if (!this.debugToolbarMenu) {
|
||||
this.debugToolbarMenu = this.menuService.createMenu(MenuId.DebugToolbar, this.contextKeyService);
|
||||
this.toDispose.push(this.debugToolbarMenu);
|
||||
if (!this.debugToolBarMenu) {
|
||||
this.debugToolBarMenu = this.menuService.createMenu(MenuId.DebugToolBar, this.contextKeyService);
|
||||
this.toDispose.push(this.debugToolBarMenu);
|
||||
}
|
||||
return DebugToolbar.getActions(this.debugToolbarMenu, this.debugService, this.instantiationService);
|
||||
return DebugToolBar.getActions(this.debugToolBarMenu, this.debugService, this.instantiationService);
|
||||
}
|
||||
|
||||
get showInitialDebugActions(): boolean {
|
||||
@@ -160,6 +161,10 @@ export class DebugViewlet extends ViewContainerViewlet {
|
||||
this.progressRunner = this.progressService.show(true);
|
||||
}
|
||||
|
||||
this.updateToolBar();
|
||||
}
|
||||
|
||||
private updateToolBar(): void {
|
||||
if (this.configurationService.getValue<IDebugConfiguration>('debug').toolBarLocation === 'docked') {
|
||||
this.updateTitleArea();
|
||||
}
|
||||
|
||||
@@ -424,10 +424,10 @@ export class LoadedScriptsView extends ViewletPanel {
|
||||
new LoadedScriptsDataSource(),
|
||||
{
|
||||
identityProvider: {
|
||||
getId: element => (<LoadedScriptsItem>element).getId()
|
||||
getId: (element: LoadedScriptsItem) => element.getId()
|
||||
},
|
||||
keyboardNavigationLabelProvider: {
|
||||
getKeyboardNavigationLabel: element => (<LoadedScriptsItem>element).getLabel()
|
||||
getKeyboardNavigationLabel: (element: LoadedScriptsItem) => element.getLabel()
|
||||
},
|
||||
filter: this.filter,
|
||||
accessibilityProvider: new LoadedSciptsAccessibilityProvider(),
|
||||
|
||||
@@ -373,9 +373,9 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
||||
], new ReplDataSource(), {
|
||||
ariaLabel: nls.localize('replAriaLabel', "Read Eval Print Loop Panel"),
|
||||
accessibilityProvider: new ReplAccessibilityProvider(),
|
||||
identityProvider: { getId: element => (<IReplElement>element).getId() },
|
||||
identityProvider: { getId: (element: IReplElement) => element.getId() },
|
||||
mouseSupport: false,
|
||||
keyboardNavigationLabelProvider: { getKeyboardNavigationLabel: e => e },
|
||||
keyboardNavigationLabelProvider: { getKeyboardNavigationLabel: (e: IReplElement) => e },
|
||||
horizontalScrolling: false,
|
||||
setRowLineHeight: false,
|
||||
supportDynamicHeights: true
|
||||
@@ -452,7 +452,10 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
||||
private onContextMenu(e: ITreeContextMenuEvent<IReplElement>): void {
|
||||
const actions: IAction[] = [];
|
||||
actions.push(new Action('debug.replCopy', nls.localize('copy', "Copy"), undefined, true, () => {
|
||||
this.clipboardService.writeText(window.getSelection().toString());
|
||||
const nativeSelection = window.getSelection();
|
||||
if (nativeSelection) {
|
||||
this.clipboardService.writeText(nativeSelection.toString());
|
||||
}
|
||||
return Promise.resolve();
|
||||
}));
|
||||
actions.push(new Action('workbench.debug.action.copyAll', nls.localize('copyAll', "Copy All"), undefined, true, () => {
|
||||
@@ -740,7 +743,8 @@ class ReplDelegate implements IListVirtualDelegate<IReplElement> {
|
||||
}
|
||||
|
||||
hasDynamicHeight?(element: IReplElement): boolean {
|
||||
return true;
|
||||
// Empty elements should not have dynamic height since they will be invisible
|
||||
return element.toString().length > 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,8 +76,8 @@ export class VariablesView extends ViewletPanel {
|
||||
new VariablesDataSource(), {
|
||||
ariaLabel: nls.localize('variablesAriaTreeLabel', "Debug Variables"),
|
||||
accessibilityProvider: new VariablesAccessibilityProvider(),
|
||||
identityProvider: { getId: element => (<IExpression | IScope>element).getId() },
|
||||
keyboardNavigationLabelProvider: { getKeyboardNavigationLabel: e => e }
|
||||
identityProvider: { getId: (element: IExpression | IScope) => element.getId() },
|
||||
keyboardNavigationLabelProvider: { getKeyboardNavigationLabel: (e: IExpression | IScope) => e }
|
||||
}) as WorkbenchAsyncDataTree<IViewModel | IExpression | IScope, IExpression | IScope, FuzzyScore>;
|
||||
|
||||
this.tree.setInput(this.debugService.getViewModel()).then(null, onUnexpectedError);
|
||||
|
||||
@@ -63,8 +63,8 @@ export class WatchExpressionsView extends ViewletPanel {
|
||||
new WatchExpressionsDataSource(), {
|
||||
ariaLabel: nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'watchAriaTreeLabel' }, "Debug Watch Expressions"),
|
||||
accessibilityProvider: new WatchExpressionsAccessibilityProvider(),
|
||||
identityProvider: { getId: element => (<IExpression>element).getId() },
|
||||
keyboardNavigationLabelProvider: { getKeyboardNavigationLabel: e => e },
|
||||
identityProvider: { getId: (element: IExpression) => element.getId() },
|
||||
keyboardNavigationLabelProvider: { getKeyboardNavigationLabel: (e: IExpression) => e },
|
||||
dnd: new WatchExpressionsDragAndDrop(this.debugService),
|
||||
}) as WorkbenchAsyncDataTree<IDebugService | IExpression, IExpression, FuzzyScore>;
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ export interface IDebugSession extends ITreeElement {
|
||||
removeReplExpressions(): void;
|
||||
addReplExpression(stackFrame: IStackFrame | undefined, name: string): Promise<void>;
|
||||
appendToRepl(data: string | IExpression, severity: severity, source?: IReplElementSource): void;
|
||||
logToRepl(sev: severity, args: any[], frame?: { uri: uri, line: number, column: number });
|
||||
logToRepl(sev: severity, args: any[], frame?: { uri: uri, line: number, column: number }): void;
|
||||
|
||||
// session events
|
||||
readonly onDidEndAdapter: Event<AdapterEndEvent>;
|
||||
@@ -389,6 +389,7 @@ export interface IEvaluate {
|
||||
}
|
||||
|
||||
export interface IDebugModel extends ITreeElement {
|
||||
getSession(sessionId: string | undefined, includeInactive?: boolean): IDebugSession | undefined;
|
||||
getSessions(includeInactive?: boolean): IDebugSession[];
|
||||
getBreakpoints(filter?: { uri?: uri, lineNumber?: number, column?: number, enabledOnly?: boolean }): ReadonlyArray<IBreakpoint>;
|
||||
areBreakpointsActivated(): boolean;
|
||||
@@ -471,8 +472,8 @@ export interface ICompound {
|
||||
export interface IDebugAdapter extends IDisposable {
|
||||
readonly onError: Event<Error>;
|
||||
readonly onExit: Event<number | null>;
|
||||
onRequest(callback: (request: DebugProtocol.Request) => void);
|
||||
onEvent(callback: (event: DebugProtocol.Event) => void);
|
||||
onRequest(callback: (request: DebugProtocol.Request) => void): void;
|
||||
onEvent(callback: (event: DebugProtocol.Event) => void): void;
|
||||
startSession(): Promise<void>;
|
||||
sendMessage(message: DebugProtocol.ProtocolMessage): void;
|
||||
sendResponse(response: DebugProtocol.Response): void;
|
||||
|
||||
@@ -81,7 +81,7 @@ export class DebugContentProvider implements IWorkbenchContribution, ITextModelC
|
||||
|
||||
if (resource.query) {
|
||||
const data = Source.getEncodedDebugData(resource);
|
||||
session = this.debugService.getModel().getSessions().filter(p => p.getId() === data.sessionId).pop();
|
||||
session = this.debugService.getModel().getSession(data.sessionId);
|
||||
}
|
||||
|
||||
if (!session) {
|
||||
|
||||
@@ -778,6 +778,13 @@ export class DebugModel implements IDebugModel {
|
||||
return 'root';
|
||||
}
|
||||
|
||||
getSession(sessionId: string | undefined, includeInactive = false): IDebugSession | undefined {
|
||||
if (sessionId) {
|
||||
return this.getSessions(includeInactive).filter(s => s.getId() === sessionId).pop();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getSessions(includeInactive = false): IDebugSession[] {
|
||||
// By default do not return inactive sesions.
|
||||
// However we are still holding onto inactive sessions due to repl and debug service session revival (eh scenario)
|
||||
|
||||
@@ -199,7 +199,7 @@ function convertPaths(msg: DebugProtocol.ProtocolMessage, fixSourcePath: (toDA:
|
||||
fixSourcePath(true, (<DebugProtocol.GotoTargetsArguments>request.arguments).source);
|
||||
break;
|
||||
case 'launchVSCode':
|
||||
request.arguments.args.forEach(arg => fixSourcePath(false, arg));
|
||||
request.arguments.args.forEach((arg: PathContainer | undefined) => fixSourcePath(false, arg));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -28,7 +28,7 @@ import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/la
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { DebugEditorModelManager } from 'vs/workbench/contrib/debug/browser/debugEditorModelManager';
|
||||
import { StartAction, AddFunctionBreakpointAction, ConfigureAction, DisableAllBreakpointsAction, EnableAllBreakpointsAction, RemoveAllBreakpointsAction, RunAction, ReapplyBreakpointsAction, SelectAndStartAction } from 'vs/workbench/contrib/debug/browser/debugActions';
|
||||
import { DebugToolbar } from 'vs/workbench/contrib/debug/browser/debugToolbar';
|
||||
import { DebugToolBar } from 'vs/workbench/contrib/debug/browser/debugToolBar';
|
||||
import * as service from 'vs/workbench/contrib/debug/electron-browser/debugService';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { registerCommands, ADD_CONFIGURATION_ID, TOGGLE_INLINE_BREAKPOINT_ID, COPY_STACK_TRACE_ID, REVERSE_CONTINUE_ID, STEP_BACK_ID, RESTART_SESSION_ID, TERMINATE_THREAD_ID, STEP_OVER_ID, STEP_INTO_ID, STEP_OUT_ID, PAUSE_ID, DISCONNECT_ID, STOP_ID, RESTART_FRAME_ID, CONTINUE_ID, FOCUS_REPL_ID } from 'vs/workbench/contrib/debug/browser/debugCommands';
|
||||
@@ -124,7 +124,7 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(OpenDebugPanelAction,
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenDebugViewletAction, OpenDebugViewletAction.ID, OpenDebugViewletAction.LABEL, openViewletKb), 'View: Show Debug', nls.localize('view', "View"));
|
||||
|
||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DebugEditorModelManager, LifecyclePhase.Restored);
|
||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DebugToolbar, LifecyclePhase.Restored);
|
||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DebugToolBar, LifecyclePhase.Restored);
|
||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DebugContentProvider, LifecyclePhase.Eventually);
|
||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(StatusBarColorProvider, LifecyclePhase.Eventually);
|
||||
|
||||
@@ -259,8 +259,8 @@ statusBar.registerStatusbarItem(new StatusbarItemDescriptor(DebugStatus, Statusb
|
||||
|
||||
// Debug toolbar
|
||||
|
||||
const registerDebugToolbarItem = (id: string, title: string, icon: string, order: number, when?: ContextKeyExpr, precondition?: ContextKeyExpr) => {
|
||||
MenuRegistry.appendMenuItem(MenuId.DebugToolbar, {
|
||||
const registerDebugToolBarItem = (id: string, title: string, icon: string, order: number, when?: ContextKeyExpr, precondition?: ContextKeyExpr) => {
|
||||
MenuRegistry.appendMenuItem(MenuId.DebugToolBar, {
|
||||
group: 'navigation',
|
||||
when,
|
||||
order,
|
||||
@@ -276,16 +276,16 @@ const registerDebugToolbarItem = (id: string, title: string, icon: string, order
|
||||
});
|
||||
};
|
||||
|
||||
registerDebugToolbarItem(CONTINUE_ID, continueLabel, 'continue', 10, CONTEXT_DEBUG_STATE.notEqualsTo('running'));
|
||||
registerDebugToolbarItem(PAUSE_ID, pauseLabel, 'pause', 10, CONTEXT_DEBUG_STATE.isEqualTo('running'));
|
||||
registerDebugToolbarItem(STOP_ID, stopLabel, 'stop', 70, CONTEXT_FOCUSED_SESSION_IS_ATTACH.toNegated());
|
||||
registerDebugToolbarItem(DISCONNECT_ID, disconnectLabel, 'disconnect', 70, CONTEXT_FOCUSED_SESSION_IS_ATTACH);
|
||||
registerDebugToolbarItem(STEP_OVER_ID, stepOverLabel, 'step-over', 20, undefined, CONTEXT_DEBUG_STATE.isEqualTo('stopped'));
|
||||
registerDebugToolbarItem(STEP_INTO_ID, stepIntoLabel, 'step-into', 30, undefined, CONTEXT_DEBUG_STATE.isEqualTo('stopped'));
|
||||
registerDebugToolbarItem(STEP_OUT_ID, stepOutLabel, 'step-out', 40, undefined, CONTEXT_DEBUG_STATE.isEqualTo('stopped'));
|
||||
registerDebugToolbarItem(RESTART_SESSION_ID, restartLabel, 'restart', 60);
|
||||
registerDebugToolbarItem(STEP_BACK_ID, nls.localize('stepBackDebug', "Step Back"), 'step-back', 50, CONTEXT_STEP_BACK_SUPPORTED, CONTEXT_DEBUG_STATE.isEqualTo('stopped'));
|
||||
registerDebugToolbarItem(REVERSE_CONTINUE_ID, nls.localize('reverseContinue', "Reverse"), 'reverse-continue', 60, CONTEXT_STEP_BACK_SUPPORTED, CONTEXT_DEBUG_STATE.isEqualTo('stopped'));
|
||||
registerDebugToolBarItem(CONTINUE_ID, continueLabel, 'continue', 10, CONTEXT_DEBUG_STATE.isEqualTo('stopped'));
|
||||
registerDebugToolBarItem(PAUSE_ID, pauseLabel, 'pause', 10, CONTEXT_DEBUG_STATE.notEqualsTo('stopped'), CONTEXT_DEBUG_STATE.isEqualTo('running'));
|
||||
registerDebugToolBarItem(STOP_ID, stopLabel, 'stop', 70, CONTEXT_FOCUSED_SESSION_IS_ATTACH.toNegated());
|
||||
registerDebugToolBarItem(DISCONNECT_ID, disconnectLabel, 'disconnect', 70, CONTEXT_FOCUSED_SESSION_IS_ATTACH);
|
||||
registerDebugToolBarItem(STEP_OVER_ID, stepOverLabel, 'step-over', 20, undefined, CONTEXT_DEBUG_STATE.isEqualTo('stopped'));
|
||||
registerDebugToolBarItem(STEP_INTO_ID, stepIntoLabel, 'step-into', 30, undefined, CONTEXT_DEBUG_STATE.isEqualTo('stopped'));
|
||||
registerDebugToolBarItem(STEP_OUT_ID, stepOutLabel, 'step-out', 40, undefined, CONTEXT_DEBUG_STATE.isEqualTo('stopped'));
|
||||
registerDebugToolBarItem(RESTART_SESSION_ID, restartLabel, 'restart', 60);
|
||||
registerDebugToolBarItem(STEP_BACK_ID, nls.localize('stepBackDebug', "Step Back"), 'step-back', 50, CONTEXT_STEP_BACK_SUPPORTED, CONTEXT_DEBUG_STATE.isEqualTo('stopped'));
|
||||
registerDebugToolBarItem(REVERSE_CONTINUE_ID, nls.localize('reverseContinue', "Reverse"), 'reverse-continue', 60, CONTEXT_STEP_BACK_SUPPORTED, CONTEXT_DEBUG_STATE.isEqualTo('stopped'));
|
||||
|
||||
// Debug callstack context menu
|
||||
const registerDebugCallstackItem = (id: string, title: string, order: number, when?: ContextKeyExpr, precondition?: ContextKeyExpr, group = 'navigation') => {
|
||||
@@ -529,7 +529,7 @@ MenuRegistry.appendMenuItem(MenuId.MenubarDebugMenu, {
|
||||
// Touch Bar
|
||||
if (isMacintosh) {
|
||||
|
||||
const registerTouchBarEntry = (id: string, title: string, order, when: ContextKeyExpr, icon: string) => {
|
||||
const registerTouchBarEntry = (id: string, title: string, order: number, when: ContextKeyExpr, icon: string) => {
|
||||
MenuRegistry.appendMenuItem(MenuId.TouchBarContext, {
|
||||
command: {
|
||||
id, title, iconLocation: { dark: URI.parse(require.toUrl(`vs/workbench/contrib/debug/electron-browser/media/${icon}`)) }
|
||||
|
||||
@@ -137,7 +137,7 @@ export class DebugService implements IDebugService {
|
||||
this.lifecycleService.onShutdown(this.dispose, this);
|
||||
|
||||
this.toDispose.push(this.broadcastService.onBroadcast(broadcast => {
|
||||
const session = this.model.getSessions(true).filter(s => s.getId() === broadcast.payload.debugId).pop();
|
||||
const session = this.model.getSession(broadcast.payload.debugId, true);
|
||||
if (session) {
|
||||
switch (broadcast.channel) {
|
||||
|
||||
|
||||
@@ -497,7 +497,7 @@ export class RawDebugSession {
|
||||
success: true
|
||||
};
|
||||
|
||||
const safeSendResponse = (response) => this.debugAdapter && this.debugAdapter.sendResponse(response);
|
||||
const safeSendResponse = (response: DebugProtocol.Response) => this.debugAdapter && this.debugAdapter.sendResponse(response);
|
||||
|
||||
switch (request.command) {
|
||||
case 'launchVSCode':
|
||||
|
||||
@@ -71,7 +71,7 @@ abstract class TerminalLauncher implements ITerminalLauncher {
|
||||
return this.runInTerminal0(args.title!, args.cwd, args.args, args.env || {}, config);
|
||||
}
|
||||
|
||||
abstract runInTerminal0(title: string, dir: string, args: string[], envVars: env.IProcessEnvironment | {}, config): Promise<number | undefined>;
|
||||
abstract runInTerminal0(title: string, dir: string, args: string[], envVars: env.IProcessEnvironment | {}, config: ITerminalSettings): Promise<number | undefined>;
|
||||
}
|
||||
|
||||
class WinTerminalService extends TerminalLauncher {
|
||||
|
||||
@@ -23,7 +23,7 @@ suite('Experimental Prompts', () => {
|
||||
let experimentalPrompt: ExperimentalPrompts;
|
||||
let onExperimentEnabledEvent: Emitter<IExperiment>;
|
||||
|
||||
let storageData = {};
|
||||
let storageData: { [key: string]: any } = {};
|
||||
const promptText = 'Hello there! Can you see this?';
|
||||
const experiment: IExperiment =
|
||||
{
|
||||
|
||||
@@ -86,7 +86,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
private _workspaceIgnoredRecommendations: string[] = [];
|
||||
private _extensionsRecommendationsUrl: string;
|
||||
private _disposables: IDisposable[] = [];
|
||||
public loadWorkspaceConfigPromise: Promise<any>;
|
||||
public loadWorkspaceConfigPromise: Promise<void>;
|
||||
private proactiveRecommendationsFetched: boolean = false;
|
||||
|
||||
private readonly _onRecommendationChange = new Emitter<RecommendationChangeNotification>();
|
||||
@@ -137,7 +137,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}} disable extension recommendation prompt
|
||||
this.loadWorkspaceConfigPromise = this.getWorkspaceRecommendations();
|
||||
this.loadWorkspaceConfigPromise = this.getWorkspaceRecommendations().then();
|
||||
// .then(() => {
|
||||
// this.promptWorkspaceRecommendations();
|
||||
// this._modelService.onModelAdded(this.promptFiletypeBasedRecommendations, this, this._disposables);
|
||||
@@ -879,7 +879,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
/**
|
||||
* If user has any of the tools listed in product.exeBasedExtensionTips, fetch corresponding recommendations
|
||||
*/
|
||||
private fetchExecutableRecommendations(): Promise<any> {
|
||||
private fetchExecutableRecommendations(): Promise<void> {
|
||||
const homeDir = os.homedir();
|
||||
let foundExecutables: Set<string> = new Set<string>();
|
||||
|
||||
@@ -897,7 +897,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
});
|
||||
};
|
||||
|
||||
let promises: Promise<any>[] = [];
|
||||
let promises: Promise<void>[] = [];
|
||||
// Loop through recommended extensions
|
||||
forEach(product.exeBasedExtensionTips, entry => {
|
||||
if (typeof entry.value !== 'object' || !Array.isArray(entry.value['recommendations'])) {
|
||||
@@ -921,7 +921,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.all(promises);
|
||||
return Promise.all(promises).then(() => undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1016,17 +1016,18 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
* Fetch extension recommendations from currently running experiments
|
||||
*/
|
||||
private fetchExperimentalRecommendations() {
|
||||
// {{SQL CARBON EDIT}} disable experiements
|
||||
// this.experimentService.getExperimentsByType(ExperimentActionType.AddToRecommendations).then(experiments => {
|
||||
// (experiments || []).forEach(experiment => {
|
||||
// const action = experiment.action;
|
||||
// if (action && experiment.state === ExperimentState.Run && action.properties && Array.isArray(action.properties.recommendations) && action.properties.recommendationReason) {
|
||||
// action.properties.recommendations.forEach(id => {
|
||||
// this._experimentalRecommendations[id] = action.properties.recommendationReason;
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
/* // {{SQL CARBON EDIT}} disable experiements
|
||||
this.experimentService.getExperimentsByType(ExperimentActionType.AddToRecommendations).then(experiments => {
|
||||
(experiments || []).forEach(experiment => {
|
||||
const action = experiment.action;
|
||||
if (action && experiment.state === ExperimentState.Run && action.properties && Array.isArray(action.properties.recommendations) && action.properties.recommendationReason) {
|
||||
action.properties.recommendations.forEach((id: string) => {
|
||||
this._experimentalRecommendations[id] = action.properties.recommendationReason;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
@@ -340,13 +340,13 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
|
||||
|
||||
this.searchBox = this.instantiationService.createInstance(SuggestEnabledInput, `${VIEWLET_ID}.searchbox`, header, {
|
||||
triggerCharacters: ['@'],
|
||||
sortKey: item => {
|
||||
sortKey: (item: string) => {
|
||||
if (item.indexOf(':') === -1) { return 'a'; }
|
||||
else if (/ext:/.test(item) || /tag:/.test(item)) { return 'b'; }
|
||||
else if (/sort:/.test(item)) { return 'c'; }
|
||||
else { return 'd'; }
|
||||
},
|
||||
provideResults: (query) => Query.suggestions(query)
|
||||
provideResults: (query: string) => Query.suggestions(query)
|
||||
}, placeholder, 'extensions:searchinput', { placeholderText: placeholder, value: searchValue });
|
||||
|
||||
if (this.searchBox.getValue()) {
|
||||
@@ -453,7 +453,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
|
||||
super.saveState();
|
||||
}
|
||||
|
||||
private doSearch(): Promise<any> {
|
||||
private doSearch(): Promise<void> {
|
||||
const value = this.normalizedQuery();
|
||||
this.searchExtensionsContextKey.set(!!value);
|
||||
this.searchBuiltInExtensionsContextKey.set(ExtensionsListView.isBuiltInExtensionsQuery(value));
|
||||
@@ -465,9 +465,9 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
|
||||
return this.progress(Promise.all(this.panels.map(view =>
|
||||
(<ExtensionsListView>view).show(this.normalizedQuery())
|
||||
.then(model => this.alertSearchResult(model.length, view.id))
|
||||
)));
|
||||
))).then(() => undefined);
|
||||
}
|
||||
return Promise.resolve(null);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
protected onDidAddViews(added: IAddedViewDescriptorRef[]): ViewletPanel[] {
|
||||
@@ -479,7 +479,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
|
||||
return addedViews;
|
||||
}
|
||||
|
||||
private alertSearchResult(count: number, viewId: string) {
|
||||
private alertSearchResult(count: number, viewId: string): void {
|
||||
switch (count) {
|
||||
case 0:
|
||||
break;
|
||||
@@ -531,7 +531,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
|
||||
return this.progressService.withProgress({ location: ProgressLocation.Extensions }, () => promise);
|
||||
}
|
||||
|
||||
private onError(err: any): void {
|
||||
private onError(err: Error): void {
|
||||
if (isPromiseCanceledError(err)) {
|
||||
return;
|
||||
}
|
||||
@@ -614,7 +614,7 @@ export class MaliciousExtensionChecker implements IWorkbenchContribution {
|
||||
.then(() => this.loopCheckForMaliciousExtensions());
|
||||
}
|
||||
|
||||
private checkForMaliciousExtensions(): Promise<any> {
|
||||
private checkForMaliciousExtensions(): Promise<void> {
|
||||
return this.extensionsManagementService.getExtensionsReport().then(report => {
|
||||
const maliciousSet = getMaliciousExtensionsSet(report);
|
||||
|
||||
@@ -635,9 +635,9 @@ export class MaliciousExtensionChecker implements IWorkbenchContribution {
|
||||
);
|
||||
})));
|
||||
} else {
|
||||
return Promise.resolve(null);
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
});
|
||||
}).then(() => undefined);
|
||||
}, err => this.logService.error(err));
|
||||
}
|
||||
|
||||
|
||||
@@ -178,10 +178,9 @@ export class ExtensionsListView extends ViewletPanel {
|
||||
return this.list ? this.list.model : model;
|
||||
};
|
||||
|
||||
const isLocalQuery = ExtensionsListView.isInstalledExtensionsQuery(query) || /@builtin/.test(query);
|
||||
const request = createCancelablePromise(token => (isLocalQuery ? this.queryLocal(parsedQuery, options) : this.queryGallery(parsedQuery, options, token)).then(successCallback).catch(errorCallback));
|
||||
const request = createCancelablePromise(token => this.query(parsedQuery, options, token).then(successCallback).catch(errorCallback));
|
||||
this.queryRequest = { query, request };
|
||||
return request.then(successCallback).catch(errorCallback);
|
||||
return request;
|
||||
}
|
||||
|
||||
count(): number {
|
||||
@@ -215,6 +214,36 @@ export class ExtensionsListView extends ViewletPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private async query(query: Query, options: IQueryOptions, token: CancellationToken): Promise<IPagedModel<IExtension>> {
|
||||
const idRegex = /@id:(([a-z0-9A-Z][a-z0-9\-A-Z]*)\.([a-z0-9A-Z][a-z0-9\-A-Z]*))/g;
|
||||
const ids: string[] = [];
|
||||
let idMatch;
|
||||
while ((idMatch = idRegex.exec(query.value)) !== null) {
|
||||
const name = idMatch[1];
|
||||
ids.push(name);
|
||||
}
|
||||
if (ids.length) {
|
||||
return this.queryByIds(ids, options, token);
|
||||
}
|
||||
if (ExtensionsListView.isInstalledExtensionsQuery(query.value) || /@builtin/.test(query.value)) {
|
||||
return this.queryLocal(query, options);
|
||||
}
|
||||
return this.queryGallery(query, options, token);
|
||||
}
|
||||
|
||||
private async queryByIds(ids: string[], options: IQueryOptions, token: CancellationToken): Promise<IPagedModel<IExtension>> {
|
||||
const idsSet: Set<string> = ids.reduce((result, id) => { result.add(id.toLowerCase()); return result; }, new Set<string>());
|
||||
const result = (await this.extensionsWorkbenchService.queryLocal())
|
||||
.filter(e => idsSet.has(e.identifier.id.toLowerCase()));
|
||||
|
||||
if (result.length) {
|
||||
return this.getPagedModel(this.sortExtensions(result, options));
|
||||
}
|
||||
|
||||
return this.extensionsWorkbenchService.queryGallery({ names: ids, source: 'queryById' }, token)
|
||||
.then(pager => this.getPagedModel(pager));
|
||||
}
|
||||
|
||||
private async queryLocal(query: Query, options: IQueryOptions): Promise<IPagedModel<IExtension>> {
|
||||
let value = query.value;
|
||||
if (/@builtin/i.test(value)) {
|
||||
@@ -347,21 +376,6 @@ export class ExtensionsListView extends ViewletPanel {
|
||||
options.sortBy = SortBy.InstallCount;
|
||||
}
|
||||
|
||||
let value = query.value;
|
||||
|
||||
const idRegex = /@id:(([a-z0-9A-Z][a-z0-9\-A-Z]*)\.([a-z0-9A-Z][a-z0-9\-A-Z]*))/g;
|
||||
let idMatch;
|
||||
const names: string[] = [];
|
||||
while ((idMatch = idRegex.exec(value)) !== null) {
|
||||
const name = idMatch[1];
|
||||
names.push(name);
|
||||
}
|
||||
|
||||
if (names.length) {
|
||||
return this.extensionsWorkbenchService.queryGallery({ names, source: 'queryById' }, token)
|
||||
.then(pager => this.getPagedModel(pager));
|
||||
}
|
||||
|
||||
if (ExtensionsListView.isWorkspaceRecommendedExtensionsQuery(query.value)) {
|
||||
return this.getWorkspaceRecommendationsModel(query, options, token);
|
||||
} else if (ExtensionsListView.isKeymapsRecommendedExtensionsQuery(query.value)) {
|
||||
|
||||
@@ -1056,7 +1056,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
|
||||
const extension = local.filter(local => areSameExtensions(local.identifier, { id: extensionId }))[0];
|
||||
|
||||
if (extension) {
|
||||
return this.windowService.show()
|
||||
return this.windowService.focusWindow()
|
||||
.then(() => this.open(extension));
|
||||
}
|
||||
|
||||
@@ -1067,7 +1067,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService,
|
||||
|
||||
const extension = result.firstPage[0];
|
||||
|
||||
return this.windowService.show().then(() => {
|
||||
return this.windowService.focusWindow().then(() => {
|
||||
return this.open(extension).then(() => {
|
||||
this.notificationService.prompt(
|
||||
Severity.Info,
|
||||
|
||||
@@ -71,7 +71,7 @@ export class WindowsExternalTerminalService implements IExternalTerminalService
|
||||
});
|
||||
}
|
||||
|
||||
private spawnTerminal(spawner, configuration: IExternalTerminalConfiguration, command: string, cwd?: string): Promise<void> {
|
||||
private spawnTerminal(spawner: typeof cp, configuration: IExternalTerminalConfiguration, command: string, cwd?: string): Promise<void> {
|
||||
const terminalConfig = configuration.terminal.external;
|
||||
const exec = terminalConfig.windowsExec || getDefaultTerminalWindows();
|
||||
const spawnType = this.getSpawnType(exec);
|
||||
@@ -84,7 +84,7 @@ export class WindowsExternalTerminalService implements IExternalTerminalService
|
||||
// cmder ignores the environment cwd and instead opts to always open in %USERPROFILE%
|
||||
// unless otherwise specified
|
||||
if (spawnType === WinSpawnType.CMDER) {
|
||||
spawner.spawn(exec, [cwd]);
|
||||
spawner.spawn(exec, cwd ? [cwd] : undefined);
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
@@ -192,12 +192,16 @@ export class MacExternalTerminalService implements IExternalTerminalService {
|
||||
});
|
||||
}
|
||||
|
||||
private spawnTerminal(spawner, configuration: IExternalTerminalConfiguration, cwd?: string): Promise<void> {
|
||||
private spawnTerminal(spawner: typeof cp, configuration: IExternalTerminalConfiguration, cwd?: string): Promise<void> {
|
||||
const terminalConfig = configuration.terminal.external;
|
||||
const terminalApp = terminalConfig.osxExec || DEFAULT_TERMINAL_OSX;
|
||||
|
||||
return new Promise<void>((c, e) => {
|
||||
const child = spawner.spawn('/usr/bin/open', ['-a', terminalApp, cwd]);
|
||||
const args = ['-a', terminalApp];
|
||||
if (cwd) {
|
||||
args.push(cwd);
|
||||
}
|
||||
const child = spawner.spawn('/usr/bin/open', args);
|
||||
child.on('error', e);
|
||||
child.on('exit', () => c());
|
||||
});
|
||||
@@ -276,13 +280,13 @@ export class LinuxExternalTerminalService implements IExternalTerminalService {
|
||||
});
|
||||
}
|
||||
|
||||
private spawnTerminal(spawner, configuration: IExternalTerminalConfiguration, cwd?: string): Promise<void> {
|
||||
private spawnTerminal(spawner: typeof cp, configuration: IExternalTerminalConfiguration, cwd?: string): Promise<void> {
|
||||
const terminalConfig = configuration.terminal.external;
|
||||
const execPromise = terminalConfig.linuxExec ? Promise.resolve(terminalConfig.linuxExec) : getDefaultTerminalLinuxReady();
|
||||
const env = cwd ? { cwd: cwd } : undefined;
|
||||
|
||||
return new Promise<void>((c, e) => {
|
||||
execPromise.then(exec => {
|
||||
const env = cwd ? { cwd } : undefined;
|
||||
const child = spawner.spawn(exec, [], env);
|
||||
child.on('error', e);
|
||||
child.on('exit', () => c());
|
||||
|
||||
@@ -285,16 +285,15 @@ export class ExplorerView extends ViewletPanel {
|
||||
accessibilityProvider: new ExplorerAccessibilityProvider(),
|
||||
ariaLabel: nls.localize('treeAriaLabel', "Files Explorer"),
|
||||
identityProvider: {
|
||||
getId: stat => (<ExplorerItem>stat).resource
|
||||
getId: (stat: ExplorerItem) => stat.resource
|
||||
},
|
||||
keyboardNavigationLabelProvider: {
|
||||
getKeyboardNavigationLabel: stat => {
|
||||
const item = <ExplorerItem>stat;
|
||||
if (this.explorerService.isEditable(item)) {
|
||||
getKeyboardNavigationLabel: (stat: ExplorerItem) => {
|
||||
if (this.explorerService.isEditable(stat)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return item.name;
|
||||
return stat.name;
|
||||
}
|
||||
},
|
||||
multipleSelectionSupport: true,
|
||||
|
||||
@@ -67,7 +67,8 @@ export class ExplorerDataSource implements IAsyncDataSource<ExplorerItem | Explo
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
|
||||
@IFileService private readonly fileService: IFileService,
|
||||
@IExplorerService private readonly explorerService: IExplorerService
|
||||
@IExplorerService private readonly explorerService: IExplorerService,
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService
|
||||
) { }
|
||||
|
||||
hasChildren(element: ExplorerItem | ExplorerItem[]): boolean {
|
||||
@@ -80,8 +81,17 @@ export class ExplorerDataSource implements IAsyncDataSource<ExplorerItem | Explo
|
||||
}
|
||||
|
||||
const promise = element.fetchChildren(this.fileService, this.explorerService).then(undefined, e => {
|
||||
// Do not show error for roots since we already use an explorer decoration to notify user
|
||||
if (!(element instanceof ExplorerItem && element.isRoot)) {
|
||||
|
||||
if (element instanceof ExplorerItem && element.isRoot) {
|
||||
if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) {
|
||||
// Single folder create a dummy explorer item to show error
|
||||
const placeholder = new ExplorerItem(element.resource, undefined, false);
|
||||
placeholder.isError = true;
|
||||
|
||||
return [placeholder];
|
||||
}
|
||||
} else {
|
||||
// Do not show error for roots since we already use an explorer decoration to notify user
|
||||
this.notificationService.error(e);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,14 +3,12 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { EditorAction, registerEditorAction, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { DocumentRangeFormattingEditProviderRegistry } from 'vs/editor/common/modes';
|
||||
import * as nls from 'vs/nls';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { IQuickInputService, IQuickPickItem, IQuickInputButton } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -18,6 +16,8 @@ import { formatDocumentRangeWithProvider, formatDocumentWithProvider, getRealAnd
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { showExtensionQuery } from 'vs/workbench/contrib/format/browser/showExtensionQuery';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
interface IIndexedPick extends IQuickPickItem {
|
||||
index: number;
|
||||
@@ -28,20 +28,34 @@ const openExtensionAction: IQuickInputButton = {
|
||||
iconClass: 'format-show-extension'
|
||||
};
|
||||
|
||||
function logFormatterTelemetry<T extends { extensionId?: ExtensionIdentifier }>(telemetryService: ITelemetryService, mode: 'document' | 'range', options: T[], pick?: T) {
|
||||
|
||||
function extKey(obj: T): string {
|
||||
return obj.extensionId ? ExtensionIdentifier.toKey(obj.extensionId) : 'unknown';
|
||||
}
|
||||
/*
|
||||
* __GDPR__
|
||||
"formatterpick" : {
|
||||
"mode" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"extensions" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"pick" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
telemetryService.publicLog('formatterpick', {
|
||||
mode,
|
||||
extensions: options.map(extKey),
|
||||
pick: pick ? extKey(pick) : 'none'
|
||||
});
|
||||
}
|
||||
|
||||
registerEditorAction(class FormatDocumentMultipleAction extends EditorAction {
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: 'editor.action.formatDocument.multiple',
|
||||
label: nls.localize('formatDocument.label.multiple', "Format Document..."),
|
||||
label: nls.localize('formatDocument.label.multiple', "Format Document With..."),
|
||||
alias: 'Format Document...',
|
||||
precondition: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasMultipleDocumentFormattingProvider),
|
||||
kbOpts: {
|
||||
kbExpr: EditorContextKeys.editorTextFocus,
|
||||
primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_F,
|
||||
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_I },
|
||||
weight: KeybindingWeight.EditorContrib,
|
||||
},
|
||||
menuOpts: {
|
||||
group: '1_modification',
|
||||
order: 1.3
|
||||
@@ -56,6 +70,7 @@ registerEditorAction(class FormatDocumentMultipleAction extends EditorAction {
|
||||
const instaService = accessor.get(IInstantiationService);
|
||||
const quickPickService = accessor.get(IQuickInputService);
|
||||
const viewletService = accessor.get(IViewletService);
|
||||
const telemetryService = accessor.get(ITelemetryService);
|
||||
const model = editor.getModel();
|
||||
|
||||
const provider = getRealAndSyntheticDocumentFormattersOrdered(model);
|
||||
@@ -77,6 +92,8 @@ registerEditorAction(class FormatDocumentMultipleAction extends EditorAction {
|
||||
if (pick) {
|
||||
await instaService.invokeFunction(formatDocumentWithProvider, provider[pick.index], editor, CancellationToken.None);
|
||||
}
|
||||
|
||||
logFormatterTelemetry(telemetryService, 'document', provider, pick && provider[pick.index]);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -85,14 +102,9 @@ registerEditorAction(class FormatSelectionMultipleAction extends EditorAction {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'editor.action.formatSelection.multiple',
|
||||
label: nls.localize('formatSelection.label.multiple', "Format Selection..."),
|
||||
label: nls.localize('formatSelection.label.multiple', "Format Selection With..."),
|
||||
alias: 'Format Code...',
|
||||
precondition: ContextKeyExpr.and(ContextKeyExpr.and(EditorContextKeys.writable), EditorContextKeys.hasMultipleDocumentSelectionFormattingProvider),
|
||||
kbOpts: {
|
||||
kbExpr: EditorContextKeys.editorTextFocus,
|
||||
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_F),
|
||||
weight: KeybindingWeight.EditorContrib
|
||||
},
|
||||
menuOpts: {
|
||||
when: ContextKeyExpr.and(EditorContextKeys.hasNonEmptySelection),
|
||||
group: '1_modification',
|
||||
@@ -108,6 +120,7 @@ registerEditorAction(class FormatSelectionMultipleAction extends EditorAction {
|
||||
const instaService = accessor.get(IInstantiationService);
|
||||
const quickPickService = accessor.get(IQuickInputService);
|
||||
const viewletService = accessor.get(IViewletService);
|
||||
const telemetryService = accessor.get(ITelemetryService);
|
||||
const model = editor.getModel();
|
||||
|
||||
let range: Range = editor.getSelection();
|
||||
@@ -134,5 +147,7 @@ registerEditorAction(class FormatSelectionMultipleAction extends EditorAction {
|
||||
if (pick) {
|
||||
await instaService.invokeFunction(formatDocumentRangeWithProvider, provider[pick.index], editor, range, CancellationToken.None);
|
||||
}
|
||||
|
||||
logFormatterTelemetry(telemetryService, 'range', provider, pick && provider[pick.index]);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -12,6 +12,8 @@ import { OpenIssueReporterAction, ReportPerformanceIssueUsingReporterAction, Ope
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issue';
|
||||
import { WorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issueService';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { IIssueService } from 'vs/platform/issue/common/issue';
|
||||
|
||||
const helpCategory = nls.localize('help', "Help");
|
||||
const workbenchActionsRegistry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
|
||||
@@ -25,3 +27,7 @@ const developerCategory = nls.localize('developer', "Developer");
|
||||
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenProcessExplorer, OpenProcessExplorer.ID, OpenProcessExplorer.LABEL), 'Developer: Open Process Explorer', developerCategory);
|
||||
|
||||
registerSingleton(IWorkbenchIssueService, WorkbenchIssueService, true);
|
||||
|
||||
CommandsRegistry.registerCommand('_issues.getSystemStatus', (accessor) => {
|
||||
return accessor.get(IIssueService).getSystemStatus();
|
||||
});
|
||||
|
||||
@@ -318,7 +318,7 @@ class MarkerWidget extends Disposable {
|
||||
dom.toggleClass(messageContainer, 'multiline', multiline);
|
||||
|
||||
let lastLineElement = messageContainer;
|
||||
for (let index = 0; index < lines.length; index++) {
|
||||
for (let index = 0; index < (multiline ? lines.length : 1); index++) {
|
||||
lastLineElement = dom.append(messageContainer, dom.$('.marker-message-line'));
|
||||
const highlightedLabel = new HighlightedLabel(lastLineElement, false);
|
||||
highlightedLabel.set(lines[index], lineMatches[index]);
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
.vs .monaco-action-bar .markers-panel-action-filter .monaco-inputbox {
|
||||
height: 25px;
|
||||
border: 1px solid #ddd;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.markers-panel-action-filter > .markers-panel-filter-controls {
|
||||
|
||||
@@ -368,7 +368,7 @@ export class OutlinePanel extends ViewletPanel {
|
||||
|
||||
this.disposables.push(this.onDidChangeBodyVisibility(visible => {
|
||||
if (visible && !this._requestOracle) {
|
||||
this._requestOracle = this._instantiationService.createInstance(RequestOracle, (editor, event) => this._doUpdate(editor, event), DocumentSymbolProviderRegistry);
|
||||
this._requestOracle = this._instantiationService.createInstance(RequestOracle, (editor: ICodeEditor | undefined, event: IModelContentChangedEvent | undefined) => this._doUpdate(editor, event), DocumentSymbolProviderRegistry);
|
||||
} else if (!visible) {
|
||||
dispose(this._requestOracle);
|
||||
this._requestOracle = undefined;
|
||||
|
||||
@@ -88,6 +88,24 @@ export class OpenGlobalSettingsAction extends Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class OpenRemoteSettingsAction extends Action {
|
||||
|
||||
static readonly ID = 'workbench.action.openRemoteSettings';
|
||||
static readonly LABEL = nls.localize('openRemoteSettings', "Open User Settings (Remote)");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IPreferencesService private readonly preferencesService: IPreferencesService,
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(event?: any): Promise<any> {
|
||||
return this.preferencesService.openRemoteSettings();
|
||||
}
|
||||
}
|
||||
|
||||
export class OpenGlobalKeybindingsAction extends Action {
|
||||
|
||||
static readonly ID = 'workbench.action.openGlobalKeybindings';
|
||||
|
||||
@@ -995,6 +995,9 @@ export class SettingBoolRenderer extends AbstractSettingRenderer implements ITre
|
||||
}
|
||||
}));
|
||||
|
||||
toDispose.push(DOM.addDisposableListener(titleElement, DOM.EventType.MOUSE_ENTER, e => container.classList.add('mouseover')));
|
||||
toDispose.push(DOM.addDisposableListener(titleElement, DOM.EventType.MOUSE_LEAVE, e => container.classList.remove('mouseover')));
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import * as nls from 'vs/nls';
|
||||
import { MenuId, MenuRegistry, SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { WorkbenchStateContext } from 'vs/workbench/common/contextkeys';
|
||||
import { WorkbenchStateContext, IsRemoteContext } from 'vs/workbench/common/contextkeys';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
@@ -28,7 +28,7 @@ import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchCo
|
||||
import { EditorInput, Extensions as EditorInputExtensions, IEditorInputFactory, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor';
|
||||
import { ResourceContextKey } from 'vs/workbench/common/resources';
|
||||
import { KeybindingsEditor } from 'vs/workbench/contrib/preferences/browser/keybindingsEditor';
|
||||
import { ConfigureLanguageBasedSettingsAction, OpenDefaultKeybindingsFileAction, OpenFolderSettingsAction, OpenGlobalKeybindingsAction, OpenGlobalKeybindingsFileAction, OpenGlobalSettingsAction, OpenRawDefaultSettingsAction, OpenSettings2Action, OpenSettingsJsonAction, OpenWorkspaceSettingsAction, OPEN_FOLDER_SETTINGS_COMMAND, OPEN_FOLDER_SETTINGS_LABEL } from 'vs/workbench/contrib/preferences/browser/preferencesActions';
|
||||
import { ConfigureLanguageBasedSettingsAction, OpenDefaultKeybindingsFileAction, OpenFolderSettingsAction, OpenGlobalKeybindingsAction, OpenGlobalKeybindingsFileAction, OpenGlobalSettingsAction, OpenRawDefaultSettingsAction, OpenSettings2Action, OpenSettingsJsonAction, OpenWorkspaceSettingsAction, OPEN_FOLDER_SETTINGS_COMMAND, OPEN_FOLDER_SETTINGS_LABEL, OpenRemoteSettingsAction } from 'vs/workbench/contrib/preferences/browser/preferencesActions';
|
||||
import { PreferencesEditor } from 'vs/workbench/contrib/preferences/browser/preferencesEditor';
|
||||
import { CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDINGS_SEARCH_FOCUS, CONTEXT_KEYBINDING_FOCUS, CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_JSON_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IKeybindingsEditor, IPreferencesSearchService, KEYBINDINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, KEYBINDINGS_EDITOR_COMMAND_COPY, KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND, KEYBINDINGS_EDITOR_COMMAND_DEFINE, KEYBINDINGS_EDITOR_COMMAND_FOCUS_KEYBINDINGS, KEYBINDINGS_EDITOR_COMMAND_RECORD_SEARCH_KEYS, KEYBINDINGS_EDITOR_COMMAND_REMOVE, KEYBINDINGS_EDITOR_COMMAND_RESET, KEYBINDINGS_EDITOR_COMMAND_SEARCH, KEYBINDINGS_EDITOR_COMMAND_SHOW_SIMILAR, KEYBINDINGS_EDITOR_COMMAND_SORTBY_PRECEDENCE, KEYBINDINGS_EDITOR_SHOW_DEFAULT_KEYBINDINGS, KEYBINDINGS_EDITOR_SHOW_USER_KEYBINDINGS, MODIFIED_SETTING_TAG, SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_EDIT_FOCUSED_SETTING, SETTINGS_EDITOR_COMMAND_FILTER_MODIFIED, SETTINGS_EDITOR_COMMAND_FILTER_ONLINE, SETTINGS_EDITOR_COMMAND_FOCUS_FILE, SETTINGS_EDITOR_COMMAND_FOCUS_NEXT_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_PREVIOUS_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_FROM_SEARCH, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_LIST, SETTINGS_EDITOR_COMMAND_SEARCH, SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU, SETTINGS_EDITOR_COMMAND_SWITCH_TO_JSON, SETTINGS_COMMAND_OPEN_SETTINGS, KEYBINDINGS_EDITOR_COMMAND_DEFINE_WHEN } from 'vs/workbench/contrib/preferences/common/preferences';
|
||||
import { PreferencesContribution } from 'vs/workbench/contrib/preferences/common/preferencesContribution';
|
||||
@@ -566,6 +566,18 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
|
||||
group: '1_keyboard_preferences_actions'
|
||||
});
|
||||
|
||||
CommandsRegistry.registerCommand(OpenRemoteSettingsAction.ID, serviceAccessor => {
|
||||
serviceAccessor.get(IInstantiationService).createInstance(OpenRemoteSettingsAction, OpenRemoteSettingsAction.ID, OpenRemoteSettingsAction.LABEL).run();
|
||||
});
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: OpenRemoteSettingsAction.ID,
|
||||
title: { value: OpenRemoteSettingsAction.LABEL, original: 'Preferences: Open Remote Settings' },
|
||||
category: nls.localize('preferencesCategory', "Preferences")
|
||||
},
|
||||
when: IsRemoteContext
|
||||
});
|
||||
|
||||
abstract class SettingsCommand extends Command {
|
||||
|
||||
protected getPreferencesEditor(accessor: ServicesAccessor): PreferencesEditor | SettingsEditor2 | null {
|
||||
|
||||
@@ -234,7 +234,7 @@ export class MainPanel extends ViewletPanel {
|
||||
protected renderBody(container: HTMLElement): void {
|
||||
const delegate = new ProvidersListDelegate();
|
||||
const renderer = this.instantiationService.createInstance(ProviderRenderer);
|
||||
const identityProvider = { getId: r => r.provider.id };
|
||||
const identityProvider = { getId: (r: ISCMRepository) => r.provider.id };
|
||||
|
||||
this.list = this.instantiationService.createInstance(WorkbenchList, container, delegate, [renderer], {
|
||||
identityProvider,
|
||||
|
||||
@@ -394,5 +394,5 @@
|
||||
}
|
||||
|
||||
.vs .search-panel .search-view .monaco-inputbox {
|
||||
border: 1px solid #ddd;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
@@ -3,37 +3,38 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import * as nls from 'vs/nls';
|
||||
import { isAbsolute } from 'vs/base/common/path';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { defaultGenerator } from 'vs/base/common/idGenerator';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { basename, dirname } from 'vs/base/common/resources';
|
||||
import { IIconLabelValueOptions } from 'vs/base/browser/ui/iconLabel/iconLabel';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import { defaultGenerator } from 'vs/base/common/idGenerator';
|
||||
import { untildify } from 'vs/base/common/labels';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { isAbsolute } from 'vs/base/common/path';
|
||||
import { basename, dirname } from 'vs/base/common/resources';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { QuickOpenEntry, QuickOpenModel } from 'vs/base/parts/quickopen/browser/quickOpenModel';
|
||||
import { IAutoFocus } from 'vs/base/parts/quickopen/common/quickOpen';
|
||||
import { IPreparedQuery, prepareQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { getIconClasses } from 'vs/editor/common/services/getIconClasses';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { IAutoFocus } from 'vs/base/parts/quickopen/common/quickOpen';
|
||||
import { QuickOpenEntry, QuickOpenModel } from 'vs/base/parts/quickopen/browser/quickOpenModel';
|
||||
import { QuickOpenHandler, EditorQuickOpenEntry } from 'vs/workbench/browser/quickopen';
|
||||
import { QueryBuilder, IFileQueryBuilderOptions } from 'vs/workbench/contrib/search/common/queryBuilder';
|
||||
import { EditorInput, IWorkbenchEditorConfiguration } from 'vs/workbench/common/editor';
|
||||
import { IResourceInput } from 'vs/platform/editor/common/editor';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import * as nls from 'vs/nls';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ISearchService, IFileSearchStats, IFileQuery, ISearchComplete } from 'vs/workbench/services/search/common/search';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IResourceInput } from 'vs/platform/editor/common/editor';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { EditorQuickOpenEntry, QuickOpenHandler } from 'vs/workbench/browser/quickopen';
|
||||
import { EditorInput, IWorkbenchEditorConfiguration } from 'vs/workbench/common/editor';
|
||||
import { IFileQueryBuilderOptions, QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder';
|
||||
import { getOutOfWorkspaceEditorResources } from 'vs/workbench/contrib/search/common/search';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { prepareQuery, IPreparedQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { untildify } from 'vs/base/common/labels';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IFileQuery, IFileSearchStats, ISearchComplete, ISearchService } from 'vs/workbench/services/search/common/search';
|
||||
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
|
||||
export class FileQuickOpenModel extends QuickOpenModel {
|
||||
|
||||
@@ -142,9 +143,6 @@ export class OpenFileHandler extends QuickOpenHandler {
|
||||
return Promise.resolve(new FileQuickOpenModel([]));
|
||||
}
|
||||
|
||||
// Untildify file pattern
|
||||
query.value = untildify(query.value, this.environmentService.userHome);
|
||||
|
||||
// Do find results
|
||||
return this.doFindResults(query, token, this.cacheState.cacheKey, maxSortedResults);
|
||||
}
|
||||
@@ -186,10 +184,16 @@ export class OpenFileHandler extends QuickOpenHandler {
|
||||
}
|
||||
|
||||
private getAbsolutePathResult(query: IPreparedQuery): Promise<URI | undefined> {
|
||||
if (isAbsolute(query.original)) {
|
||||
const resource = URI.file(query.original);
|
||||
const detildifiedQuery = untildify(query.original, this.environmentService.userHome);
|
||||
if (isAbsolute(detildifiedQuery)) {
|
||||
const workspaceFolders = this.contextService.getWorkspace().folders;
|
||||
const resource = workspaceFolders[0] && workspaceFolders[0].uri.scheme !== Schemas.file ?
|
||||
workspaceFolders[0].uri.with({ path: detildifiedQuery }) :
|
||||
URI.file(detildifiedQuery);
|
||||
|
||||
return this.fileService.resolveFile(resource).then(stat => stat.isDirectory ? undefined : resource, error => undefined);
|
||||
return this.fileService.resolveFile(resource).then(
|
||||
stat => stat.isDirectory ? undefined : resource,
|
||||
error => undefined);
|
||||
}
|
||||
|
||||
return Promise.resolve(undefined);
|
||||
|
||||
@@ -888,7 +888,8 @@ export interface TaskEvent {
|
||||
}
|
||||
|
||||
export const enum TaskRunSource {
|
||||
User, // Default
|
||||
System,
|
||||
User,
|
||||
FolderOpen,
|
||||
ConfigurationChange
|
||||
}
|
||||
@@ -932,7 +933,7 @@ export namespace KeyedTaskIdentifier {
|
||||
for (let position in keys) {
|
||||
let stringified = literal[keys[position]];
|
||||
if (stringified instanceof Object) {
|
||||
stringified = sortedStringify(test);
|
||||
stringified = sortedStringify(stringified);
|
||||
} else if (typeof stringified === 'string') {
|
||||
stringified = stringified.replace(/,/g, ',,');
|
||||
}
|
||||
@@ -942,7 +943,6 @@ export namespace KeyedTaskIdentifier {
|
||||
}
|
||||
export function create(value: TaskIdentifier): KeyedTaskIdentifier {
|
||||
const resultKey = sortedStringify(value);
|
||||
console.log(resultKey);
|
||||
return { _key: resultKey, type: value.taskType };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -870,7 +870,7 @@ class TaskService extends Disposable implements ITaskService {
|
||||
});
|
||||
}
|
||||
|
||||
public run(task: Task | undefined, options?: ProblemMatcherRunOptions): Promise<ITaskSummary> {
|
||||
public run(task: Task | undefined, options?: ProblemMatcherRunOptions, runSource: TaskRunSource = TaskRunSource.System): Promise<ITaskSummary> {
|
||||
if (!task) {
|
||||
throw new TaskError(Severity.Info, nls.localize('TaskServer.noTask', 'Task to execute is undefined'), TaskErrors.TaskNotFound);
|
||||
}
|
||||
@@ -886,7 +886,14 @@ class TaskService extends Disposable implements ITaskService {
|
||||
});
|
||||
}
|
||||
return this.executeTask(task, resolver);
|
||||
}).then(value => value, (error) => {
|
||||
}).then((value) => {
|
||||
if (runSource === TaskRunSource.User) {
|
||||
this.getWorkspaceTasks().then(workspaceTasks => {
|
||||
RunAutomaticTasks.promptForPermission(this, this.storageService, this.notificationService, workspaceTasks);
|
||||
});
|
||||
}
|
||||
return value;
|
||||
}, (error) => {
|
||||
this.handleError(error);
|
||||
return Promise.reject(error);
|
||||
});
|
||||
@@ -1548,11 +1555,6 @@ class TaskService extends Disposable implements ITaskService {
|
||||
return this._workspaceTasksPromise;
|
||||
}
|
||||
this.updateWorkspaceTasks(runSource);
|
||||
if (runSource === TaskRunSource.User) {
|
||||
this._workspaceTasksPromise!.then(workspaceFolderTasks => {
|
||||
RunAutomaticTasks.promptForPermission(this, this.storageService, this.notificationService, workspaceFolderTasks);
|
||||
});
|
||||
}
|
||||
return this._workspaceTasksPromise!;
|
||||
}
|
||||
|
||||
@@ -2049,7 +2051,7 @@ class TaskService extends Disposable implements ITaskService {
|
||||
if (task === null) {
|
||||
this.runConfigureTasks();
|
||||
} else {
|
||||
this.run(task, { attachProblemMatcher: true }).then(undefined, reason => {
|
||||
this.run(task, { attachProblemMatcher: true }, TaskRunSource.User).then(undefined, reason => {
|
||||
// eat the error, it has already been surfaced to the user and we don't care about it here
|
||||
});
|
||||
}
|
||||
|
||||
@@ -422,11 +422,13 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
if (this._shellLaunchConfig.initialText) {
|
||||
this._xterm.writeln(this._shellLaunchConfig.initialText);
|
||||
}
|
||||
this._xterm.winptyCompatInit();
|
||||
this._xterm.on('linefeed', () => this._onLineFeed());
|
||||
this._xterm.on('key', (key, ev) => this._onKey(key, ev));
|
||||
|
||||
if (this._processManager) {
|
||||
if (this._processManager.os === platform.OperatingSystem.Windows) {
|
||||
this._xterm.winptyCompatInit();
|
||||
}
|
||||
this._processManager.onProcessData(data => this._onProcessData(data));
|
||||
this._xterm.on('data', data => this._processManager!.write(data));
|
||||
// TODO: How does the cwd work on detached processes?
|
||||
|
||||
@@ -646,9 +646,9 @@ export interface ITerminalProcessManager extends IDisposable {
|
||||
readonly onProcessTitle: Event<string>;
|
||||
readonly onProcessExit: Event<number>;
|
||||
|
||||
addDisposable(disposable: IDisposable);
|
||||
dispose(immediate?: boolean);
|
||||
createProcess(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number);
|
||||
addDisposable(disposable: IDisposable): void;
|
||||
dispose(immediate?: boolean): void;
|
||||
createProcess(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number): void;
|
||||
write(data: string): void;
|
||||
setDimensions(cols: number, rows: number): void;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configur
|
||||
import { LIGHT, DARK, HIGH_CONTRAST } from 'vs/platform/theme/common/themeService';
|
||||
import { colorThemeSchemaId } from 'vs/workbench/services/themes/common/colorThemeSchema';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { IQuickInputService, IQuickPickItem, QuickPickInput } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IQuickInputService, QuickPickInput } from 'vs/platform/quickinput/common/quickInput';
|
||||
|
||||
export class SelectColorThemeAction extends Action {
|
||||
|
||||
@@ -45,20 +45,21 @@ export class SelectColorThemeAction extends Action {
|
||||
return this.themeService.getColorThemes().then(themes => {
|
||||
const currentTheme = this.themeService.getColorTheme();
|
||||
|
||||
const picks: QuickPickInput[] = ([] as QuickPickInput[]).concat(
|
||||
toEntries(themes.filter(t => t.type === LIGHT), localize('themes.category.light', "light themes")),
|
||||
toEntries(themes.filter(t => t.type === DARK), localize('themes.category.dark', "dark themes")),
|
||||
toEntries(themes.filter(t => t.type === HIGH_CONTRAST), localize('themes.category.hc', "high contrast themes")),
|
||||
const picks: QuickPickInput<ThemeItem>[] = [
|
||||
...toEntries(themes.filter(t => t.type === LIGHT), localize('themes.category.light', "light themes")),
|
||||
...toEntries(themes.filter(t => t.type === DARK), localize('themes.category.dark', "dark themes")),
|
||||
...toEntries(themes.filter(t => t.type === HIGH_CONTRAST), localize('themes.category.hc', "high contrast themes")),
|
||||
// {{SQL CARBON EDIT}}
|
||||
//configurationEntries(this.extensionGalleryService, localize('installColorThemes', "Install Additional Color Themes..."))
|
||||
);
|
||||
// ...configurationEntries(this.extensionGalleryService, localize('installColorThemes', "Install Additional Color Themes..."))
|
||||
];
|
||||
|
||||
const selectTheme = (theme: IColorTheme, applyTheme: boolean) => {
|
||||
const selectTheme = (theme: ThemeItem, applyTheme: boolean) => {
|
||||
let themeId = theme.id;
|
||||
if (typeof theme.id === 'undefined') { // 'pick in marketplace' entry
|
||||
if (applyTheme) {
|
||||
openExtensionViewlet(this.viewletService, 'category:themes ');
|
||||
}
|
||||
theme = currentTheme;
|
||||
themeId = currentTheme.id;
|
||||
}
|
||||
let target: ConfigurationTarget | undefined = undefined;
|
||||
if (applyTheme) {
|
||||
@@ -66,7 +67,7 @@ export class SelectColorThemeAction extends Action {
|
||||
target = typeof confValue.workspace !== 'undefined' ? ConfigurationTarget.WORKSPACE : ConfigurationTarget.USER;
|
||||
}
|
||||
|
||||
this.themeService.setColorTheme(theme.id, target).then(undefined,
|
||||
this.themeService.setColorTheme(themeId, target).then(undefined,
|
||||
err => {
|
||||
onUnexpectedError(err);
|
||||
this.themeService.setColorTheme(currentTheme.id, undefined);
|
||||
@@ -75,12 +76,13 @@ export class SelectColorThemeAction extends Action {
|
||||
};
|
||||
|
||||
const placeHolder = localize('themes.selectTheme', "Select Color Theme (Up/Down Keys to Preview)");
|
||||
const autoFocusIndex = firstIndex(picks, p => p.type !== 'separator' && p.id === currentTheme.id);
|
||||
const autoFocusIndex = firstIndex(picks, p => isItem(p) && p.id === currentTheme.id);
|
||||
const activeItem: ThemeItem = picks[autoFocusIndex] as ThemeItem;
|
||||
const delayer = new Delayer<void>(100);
|
||||
const chooseTheme = theme => delayer.trigger(() => selectTheme(theme || currentTheme, true), 0);
|
||||
const tryTheme = theme => delayer.trigger(() => selectTheme(theme, false));
|
||||
const chooseTheme = (theme: ThemeItem) => delayer.trigger(() => selectTheme(theme || currentTheme, true), 0);
|
||||
const tryTheme = (theme: ThemeItem) => delayer.trigger(() => selectTheme(theme, false));
|
||||
|
||||
return this.quickInputService.pick(picks, { placeHolder, activeItem: picks[autoFocusIndex], onDidFocus: tryTheme })
|
||||
return this.quickInputService.pick(picks, { placeHolder, activeItem, onDidFocus: tryTheme })
|
||||
.then(chooseTheme);
|
||||
});
|
||||
}
|
||||
@@ -108,26 +110,27 @@ class SelectIconThemeAction extends Action {
|
||||
return this.themeService.getFileIconThemes().then(themes => {
|
||||
const currentTheme = this.themeService.getFileIconTheme();
|
||||
|
||||
let picks: QuickPickInput[] = [{ id: '', label: localize('noIconThemeLabel', 'None'), description: localize('noIconThemeDesc', 'Disable file icons') }];
|
||||
let picks: QuickPickInput<ThemeItem>[] = [{ id: '', label: localize('noIconThemeLabel', 'None'), description: localize('noIconThemeDesc', 'Disable file icons') }];
|
||||
picks = picks.concat(
|
||||
toEntries(themes),
|
||||
// {{SQL CARBON EDIT}}
|
||||
// configurationEntries(this.extensionGalleryService, localize('installIconThemes', "Install Additional File Icon Themes..."))
|
||||
);
|
||||
|
||||
const selectTheme = (theme, applyTheme: boolean) => {
|
||||
const selectTheme = (theme: ThemeItem, applyTheme: boolean) => {
|
||||
let themeId = theme.id;
|
||||
if (typeof theme.id === 'undefined') { // 'pick in marketplace' entry
|
||||
if (applyTheme) {
|
||||
openExtensionViewlet(this.viewletService, 'tag:icon-theme ');
|
||||
}
|
||||
theme = currentTheme;
|
||||
themeId = currentTheme.id;
|
||||
}
|
||||
let target: ConfigurationTarget | undefined = undefined;
|
||||
if (applyTheme) {
|
||||
let confValue = this.configurationService.inspect(ICON_THEME_SETTING);
|
||||
target = typeof confValue.workspace !== 'undefined' ? ConfigurationTarget.WORKSPACE : ConfigurationTarget.USER;
|
||||
}
|
||||
this.themeService.setFileIconTheme(theme && theme.id, target).then(undefined,
|
||||
this.themeService.setFileIconTheme(themeId, target).then(undefined,
|
||||
err => {
|
||||
onUnexpectedError(err);
|
||||
this.themeService.setFileIconTheme(currentTheme.id, undefined);
|
||||
@@ -136,18 +139,19 @@ class SelectIconThemeAction extends Action {
|
||||
};
|
||||
|
||||
const placeHolder = localize('themes.selectIconTheme', "Select File Icon Theme");
|
||||
const autoFocusIndex = firstIndex(picks, p => p.type !== 'separator' && p.id === currentTheme.id);
|
||||
const autoFocusIndex = firstIndex(picks, p => isItem(p) && p.id === currentTheme.id);
|
||||
const activeItem: ThemeItem = picks[autoFocusIndex] as ThemeItem;
|
||||
const delayer = new Delayer<void>(100);
|
||||
const chooseTheme = theme => delayer.trigger(() => selectTheme(theme || currentTheme, true), 0);
|
||||
const tryTheme = theme => delayer.trigger(() => selectTheme(theme, false));
|
||||
const chooseTheme = (theme: ThemeItem) => delayer.trigger(() => selectTheme(theme || currentTheme, true), 0);
|
||||
const tryTheme = (theme: ThemeItem) => delayer.trigger(() => selectTheme(theme, false));
|
||||
|
||||
return this.quickInputService.pick(picks, { placeHolder, activeItem: picks[autoFocusIndex], onDidFocus: tryTheme })
|
||||
return this.quickInputService.pick(picks, { placeHolder, activeItem, onDidFocus: tryTheme })
|
||||
.then(chooseTheme);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function configurationEntries(extensionGalleryService: IExtensionGalleryService, label: string): QuickPickInput[] {
|
||||
function configurationEntries(extensionGalleryService: IExtensionGalleryService, label: string): QuickPickInput<ThemeItem>[] {
|
||||
if (extensionGalleryService.isEnabled()) {
|
||||
return [
|
||||
{
|
||||
@@ -156,7 +160,7 @@ function configurationEntries(extensionGalleryService: IExtensionGalleryService,
|
||||
{
|
||||
id: undefined,
|
||||
label: label,
|
||||
alwaysShow: true,
|
||||
alwaysShow: true
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -171,11 +175,21 @@ function openExtensionViewlet(viewletService: IViewletService, query: string) {
|
||||
}
|
||||
});
|
||||
}
|
||||
interface ThemeItem {
|
||||
id: string | undefined;
|
||||
label: string;
|
||||
description?: string;
|
||||
alwaysShow?: boolean;
|
||||
}
|
||||
|
||||
function toEntries(themes: Array<IColorTheme | IFileIconTheme>, label?: string) {
|
||||
const toEntry = theme => <IQuickPickItem>{ id: theme.id, label: theme.label, description: theme.description };
|
||||
const sorter = (t1: IQuickPickItem, t2: IQuickPickItem) => t1.label.localeCompare(t2.label);
|
||||
let entries: QuickPickInput[] = themes.map(toEntry).sort(sorter);
|
||||
function isItem(i: QuickPickInput<ThemeItem>): i is ThemeItem {
|
||||
return i['type'] !== 'separatpr';
|
||||
}
|
||||
|
||||
function toEntries(themes: Array<IColorTheme | IFileIconTheme>, label?: string): QuickPickInput<ThemeItem>[] {
|
||||
const toEntry = (theme: IColorTheme): ThemeItem => ({ id: theme.id, label: theme.label, description: theme.description });
|
||||
const sorter = (t1: ThemeItem, t2: ThemeItem) => t1.label.localeCompare(t2.label);
|
||||
let entries: QuickPickInput<ThemeItem>[] = themes.map(toEntry).sort(sorter);
|
||||
if (entries.length > 0 && label) {
|
||||
entries.unshift({ type: 'separator', label });
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ export class ReleaseNotesManager {
|
||||
|
||||
renderer.code = (code, lang) => {
|
||||
const modeId = this._modeService.getModeIdForLanguageName(lang);
|
||||
return `<code>${tokenizeToString(code, modeId ? TokenizationRegistry.get(modeId) : undefined)}</code>`;
|
||||
return `<code>${tokenizeToString(code, modeId ? TokenizationRegistry.get(modeId)! : undefined)}</code>`;
|
||||
};
|
||||
return renderer;
|
||||
}
|
||||
|
||||
@@ -257,9 +257,9 @@ export class WebviewEditor extends BaseEditor {
|
||||
|
||||
private getDefaultLocalResourceRoots(): URI[] {
|
||||
const rootPaths = this._contextService.getWorkspace().folders.map(x => x.uri);
|
||||
const extensionLocation = (this.input as WebviewEditorInput).extensionLocation;
|
||||
if (extensionLocation) {
|
||||
rootPaths.push(extensionLocation);
|
||||
const extension = (this.input as WebviewEditorInput).extension;
|
||||
if (extension) {
|
||||
rootPaths.push(extension.location);
|
||||
}
|
||||
return rootPaths;
|
||||
}
|
||||
@@ -283,7 +283,7 @@ export class WebviewEditor extends BaseEditor {
|
||||
this._layoutService.getContainer(Parts.EDITOR_PART),
|
||||
{
|
||||
allowSvgs: true,
|
||||
extensionLocation: input.extensionLocation,
|
||||
extension: input.extension,
|
||||
enableFindWidget: input.options.enableFindWidget
|
||||
},
|
||||
{});
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Emitter } from 'vs/base/common/event';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IEditorModel } from 'vs/platform/editor/common/editor';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { EditorInput, EditorModel, GroupIdentifier, IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { WebviewEvents, WebviewInputOptions } from './webviewEditorService';
|
||||
@@ -63,7 +64,10 @@ export class WebviewEditorInput extends EditorInput {
|
||||
private _scrollYPercentage: number = 0;
|
||||
private _state: any;
|
||||
|
||||
public readonly extensionLocation: URI | undefined;
|
||||
public readonly extension?: {
|
||||
readonly location: URI;
|
||||
readonly id: ExtensionIdentifier;
|
||||
};
|
||||
private readonly _id: number;
|
||||
|
||||
constructor(
|
||||
@@ -73,7 +77,10 @@ export class WebviewEditorInput extends EditorInput {
|
||||
options: WebviewInputOptions,
|
||||
state: any,
|
||||
events: WebviewEvents,
|
||||
extensionLocation: URI | undefined,
|
||||
extension: undefined | {
|
||||
readonly location: URI;
|
||||
readonly id: ExtensionIdentifier;
|
||||
},
|
||||
@IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService,
|
||||
) {
|
||||
super();
|
||||
@@ -89,7 +96,7 @@ export class WebviewEditorInput extends EditorInput {
|
||||
this._options = options;
|
||||
this._events = events;
|
||||
this._state = state;
|
||||
this.extensionLocation = extensionLocation;
|
||||
this.extension = extension;
|
||||
}
|
||||
|
||||
public getTypeId(): string {
|
||||
@@ -313,11 +320,14 @@ export class RevivedWebviewEditorInput extends WebviewEditorInput {
|
||||
options: WebviewInputOptions,
|
||||
state: any,
|
||||
events: WebviewEvents,
|
||||
extensionLocation: URI | undefined,
|
||||
extension: undefined | {
|
||||
readonly location: URI;
|
||||
readonly id: ExtensionIdentifier
|
||||
},
|
||||
public readonly reviver: (input: WebviewEditorInput) => Promise<void>,
|
||||
@IWorkbenchLayoutService partService: IWorkbenchLayoutService,
|
||||
) {
|
||||
super(viewType, id, name, options, state, events, extensionLocation, partService);
|
||||
super(viewType, id, name, options, state, events, extension, partService);
|
||||
}
|
||||
|
||||
public async resolve(): Promise<IEditorModel> {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { IEditorInputFactory } from 'vs/workbench/common/editor';
|
||||
import { WebviewEditorInput } from './webviewEditorInput';
|
||||
import { IWebviewEditorService, WebviewInputOptions } from './webviewEditorService';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
interface SerializedIconPath {
|
||||
light: string | UriComponents;
|
||||
@@ -20,6 +21,7 @@ interface SerializedWebview {
|
||||
readonly title: string;
|
||||
readonly options: WebviewInputOptions;
|
||||
readonly extensionLocation: string | UriComponents | undefined;
|
||||
readonly extensionId: string | undefined;
|
||||
readonly state: any;
|
||||
readonly iconPath: SerializedIconPath | undefined;
|
||||
readonly group?: number;
|
||||
@@ -45,7 +47,8 @@ export class WebviewEditorInputFactory implements IEditorInputFactory {
|
||||
id: input.getId(),
|
||||
title: input.getName(),
|
||||
options: input.options,
|
||||
extensionLocation: input.extensionLocation,
|
||||
extensionLocation: input.extension ? input.extension.location : undefined,
|
||||
extensionId: input.extension ? input.extension.id.value : undefined,
|
||||
state: input.state,
|
||||
iconPath: input.iconPath ? { light: input.iconPath.light, dark: input.iconPath.dark, } : undefined,
|
||||
group: input.group
|
||||
@@ -64,8 +67,12 @@ export class WebviewEditorInputFactory implements IEditorInputFactory {
|
||||
): WebviewEditorInput {
|
||||
const data: SerializedWebview = JSON.parse(serializedEditorInput);
|
||||
const extensionLocation = reviveUri(data.extensionLocation);
|
||||
const extensionId = data.extensionId ? new ExtensionIdentifier(data.extensionId) : undefined;
|
||||
const iconPath = reviveIconPath(data.iconPath);
|
||||
return this._webviewService.reviveWebview(data.viewType, data.id, data.title, iconPath, data.state, data.options, extensionLocation, data.group);
|
||||
return this._webviewService.reviveWebview(data.viewType, data.id, data.title, iconPath, data.state, data.options, extensionLocation ? {
|
||||
location: extensionLocation,
|
||||
id: extensionId
|
||||
} : undefined, data.group);
|
||||
}
|
||||
}
|
||||
function reviveIconPath(data: SerializedIconPath | undefined) {
|
||||
|
||||
@@ -7,12 +7,13 @@ import { equals } from 'vs/base/common/arrays';
|
||||
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { values } from 'vs/base/common/map';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IWebviewOptions, IWebviewPanelOptions } from 'vs/editor/common/modes';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { GroupIdentifier } from 'vs/workbench/common/editor';
|
||||
import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { ACTIVE_GROUP_TYPE, IEditorService, SIDE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { RevivedWebviewEditorInput, WebviewEditorInput } from './webviewEditorInput';
|
||||
import { IWebviewOptions, IWebviewPanelOptions } from 'vs/editor/common/modes';
|
||||
|
||||
export const IWebviewEditorService = createDecorator<IWebviewEditorService>('webviewEditorService');
|
||||
|
||||
@@ -29,7 +30,10 @@ export interface IWebviewEditorService {
|
||||
title: string,
|
||||
showOptions: ICreateWebViewShowOptions,
|
||||
options: WebviewInputOptions,
|
||||
extensionLocation: URI | undefined,
|
||||
extension: undefined | {
|
||||
location: URI,
|
||||
id: ExtensionIdentifier
|
||||
},
|
||||
events: WebviewEvents
|
||||
): WebviewEditorInput;
|
||||
|
||||
@@ -40,7 +44,10 @@ export interface IWebviewEditorService {
|
||||
iconPath: { light: URI, dark: URI } | undefined,
|
||||
state: any,
|
||||
options: WebviewInputOptions,
|
||||
extensionLocation: URI | undefined,
|
||||
extension: undefined | {
|
||||
readonly location: URI,
|
||||
readonly id?: ExtensionIdentifier
|
||||
},
|
||||
group: number | undefined
|
||||
): WebviewEditorInput;
|
||||
|
||||
@@ -130,10 +137,13 @@ export class WebviewEditorService implements IWebviewEditorService {
|
||||
title: string,
|
||||
showOptions: ICreateWebViewShowOptions,
|
||||
options: IWebviewOptions,
|
||||
extensionLocation: URI | undefined,
|
||||
extension: undefined | {
|
||||
location: URI,
|
||||
id: ExtensionIdentifier
|
||||
},
|
||||
events: WebviewEvents
|
||||
): WebviewEditorInput {
|
||||
const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, viewType, undefined, title, options, {}, events, extensionLocation);
|
||||
const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, viewType, undefined, title, options, {}, events, extension);
|
||||
this._editorService.openEditor(webviewInput, { pinned: true, preserveFocus: showOptions.preserveFocus }, showOptions.group);
|
||||
return webviewInput;
|
||||
}
|
||||
@@ -160,10 +170,13 @@ export class WebviewEditorService implements IWebviewEditorService {
|
||||
iconPath: { light: URI, dark: URI } | undefined,
|
||||
state: any,
|
||||
options: WebviewInputOptions,
|
||||
extensionLocation: URI,
|
||||
extension: undefined | {
|
||||
readonly location: URI,
|
||||
readonly id?: ExtensionIdentifier
|
||||
},
|
||||
group: number | undefined,
|
||||
): WebviewEditorInput {
|
||||
const webviewInput = this._instantiationService.createInstance(RevivedWebviewEditorInput, viewType, id, title, options, state, {}, extensionLocation, async (webview: WebviewEditorInput): Promise<void> => {
|
||||
const webviewInput = this._instantiationService.createInstance(RevivedWebviewEditorInput, viewType, id, title, options, state, {}, extension, async (webview: WebviewEditorInput): Promise<void> => {
|
||||
const didRevive = await this.tryRevive(webview);
|
||||
if (didRevive) {
|
||||
return Promise.resolve(undefined);
|
||||
|
||||
@@ -19,6 +19,8 @@ import { DARK, ITheme, IThemeService, LIGHT } from 'vs/platform/theme/common/the
|
||||
import { registerFileProtocol, WebviewProtocol } from 'vs/workbench/contrib/webview/electron-browser/webviewProtocols';
|
||||
import { areWebviewInputOptionsEqual } from './webviewEditorService';
|
||||
import { WebviewFindWidget } from './webviewFindWidget';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
export interface WebviewPortMapping {
|
||||
readonly port: number;
|
||||
@@ -32,7 +34,10 @@ export interface WebviewPortMapping {
|
||||
|
||||
export interface WebviewOptions {
|
||||
readonly allowSvgs?: boolean;
|
||||
readonly extensionLocation?: URI;
|
||||
readonly extension?: {
|
||||
readonly location: URI;
|
||||
readonly id?: ExtensionIdentifier;
|
||||
};
|
||||
readonly enableFindWidget?: boolean;
|
||||
}
|
||||
|
||||
@@ -145,10 +150,14 @@ class WebviewPortMappingProvider extends Disposable {
|
||||
|
||||
constructor(
|
||||
session: WebviewSession,
|
||||
mappings: () => ReadonlyArray<WebviewPortMapping>
|
||||
mappings: () => ReadonlyArray<WebviewPortMapping>,
|
||||
extensionId: ExtensionIdentifier | undefined,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
) {
|
||||
super();
|
||||
|
||||
let hasLogged = false;
|
||||
|
||||
session.onBeforeRequest(async (details) => {
|
||||
const uri = URI.parse(details.url);
|
||||
if (uri.scheme !== 'http' && uri.scheme !== 'https') {
|
||||
@@ -157,6 +166,17 @@ class WebviewPortMappingProvider extends Disposable {
|
||||
|
||||
const localhostMatch = /^localhost:(\d+)$/.exec(uri.authority);
|
||||
if (localhostMatch) {
|
||||
if (!hasLogged && extensionId) {
|
||||
hasLogged = true;
|
||||
|
||||
/* __GDPR__
|
||||
"webview.accessLocalhost" : {
|
||||
"extension" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
telemetryService.publicLog('webview.accessLocalhost', { extension: extensionId.value });
|
||||
}
|
||||
|
||||
const port = +localhostMatch[1];
|
||||
for (const mapping of mappings()) {
|
||||
if (mapping.port === port && mapping.port !== mapping.resolvedPort) {
|
||||
@@ -317,6 +337,7 @@ export class WebviewElement extends Disposable {
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IEnvironmentService environmentService: IEnvironmentService,
|
||||
@IFileService fileService: IFileService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
) {
|
||||
super();
|
||||
this._webview = document.createElement('webview');
|
||||
@@ -348,15 +369,16 @@ export class WebviewElement extends Disposable {
|
||||
|
||||
this._register(new WebviewProtocolProvider(
|
||||
this._webview,
|
||||
this._options.extensionLocation,
|
||||
this._options.extension ? this._options.extension.location : undefined,
|
||||
() => (this._contentOptions.localResourceRoots || []),
|
||||
environmentService,
|
||||
fileService));
|
||||
|
||||
this._register(new WebviewPortMappingProvider(
|
||||
session,
|
||||
() => (this._contentOptions.portMappings || [])
|
||||
));
|
||||
() => (this._contentOptions.portMappings || []),
|
||||
_options.extension ? _options.extension.id : undefined,
|
||||
telemetryService));
|
||||
|
||||
|
||||
if (!this._options.allowSvgs) {
|
||||
@@ -556,7 +578,7 @@ export class WebviewElement extends Disposable {
|
||||
colors['vscode-' + entry.id.replace('.', '-')] = color.toString();
|
||||
}
|
||||
return colors;
|
||||
}, {});
|
||||
}, {} as { [key: string]: string });
|
||||
|
||||
|
||||
const styles = {
|
||||
|
||||