Merge from vscode 966b87dd4013be1a9c06e2b8334522ec61905cc2 (#4696)

This commit is contained in:
Anthony Dresser
2019-03-26 11:43:38 -07:00
committed by GitHub
parent b1393ae615
commit 0d8ef9583b
268 changed files with 5947 additions and 3422 deletions

View File

@@ -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);
}

View File

@@ -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%;
}

View File

@@ -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';

View File

@@ -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 {

View File

@@ -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';

View File

@@ -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 {

View File

@@ -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();

View File

@@ -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';

View File

Before

Width:  |  Height:  |  Size: 307 B

After

Width:  |  Height:  |  Size: 307 B

View File

Before

Width:  |  Height:  |  Size: 293 B

After

Width:  |  Height:  |  Size: 293 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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()

View File

@@ -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) => {

View File

@@ -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 });

View File

@@ -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();
}

View File

@@ -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(),

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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>;

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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;

View File

@@ -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}`)) }

View File

@@ -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) {

View File

@@ -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':

View File

@@ -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 {

View File

@@ -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 =
{

View File

@@ -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

View File

@@ -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));
}

View File

@@ -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)) {

View File

@@ -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,

View File

@@ -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());

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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]);
}
});

View File

@@ -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();
});

View File

@@ -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]);

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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';

View File

@@ -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;
}

View File

@@ -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 {

View File

@@ -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,

View File

@@ -394,5 +394,5 @@
}
.vs .search-panel .search-view .monaco-inputbox {
border: 1px solid #ddd;
border: 1px solid transparent;
}

View File

@@ -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);

View File

@@ -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 };
}
}

View File

@@ -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
});
}

View File

@@ -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?

View File

@@ -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;

View File

@@ -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 });
}

View File

@@ -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;
}

View File

@@ -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
},
{});

View File

@@ -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> {

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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 = {