Merge from vscode 6268feb42ba4f2e2fa15484e88c9af60d254998c (#6530)

This commit is contained in:
Anthony Dresser
2019-07-29 21:03:02 -07:00
committed by GitHub
parent 2c8a22bb0d
commit 6db84eefa3
104 changed files with 1797 additions and 3740 deletions

View File

@@ -30,6 +30,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet';
import { ILabelService } from 'vs/platform/label/common/label';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
const $ = dom.$;
@@ -56,9 +57,10 @@ export class BreakpointsView extends ViewletPanel {
@IThemeService private readonly themeService: IThemeService,
@IEditorService private readonly editorService: IEditorService,
@IContextViewService private readonly contextViewService: IContextViewService,
@IConfigurationService configurationService: IConfigurationService
@IConfigurationService configurationService: IConfigurationService,
@IContextKeyService contextKeyService: IContextKeyService,
) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('breakpointsSection', "Breakpoints Section") }, keybindingService, contextMenuService, configurationService);
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('breakpointsSection', "Breakpoints Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.minimumBodySize = this.maximumBodySize = this.getExpandedBodySize();
this._register(this.debugService.getModel().onDidChangeBreakpoints(() => this.onBreakpointsChange()));

View File

@@ -60,7 +60,7 @@ export class CallStackView extends ViewletPanel {
@IMenuService menuService: IMenuService,
@IContextKeyService readonly contextKeyService: IContextKeyService,
) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('callstackSection', "Call Stack Section") }, keybindingService, contextMenuService, configurationService);
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('callstackSection', "Call Stack Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.callStackItemType = CONTEXT_CALLSTACK_ITEM_TYPE.bindTo(contextKeyService);
this.contributedContextMenu = menuService.createMenu(MenuId.DebugCallStackContext, contextKeyService);

View File

@@ -402,7 +402,7 @@ export class LoadedScriptsView extends ViewletPanel {
@IDebugService private readonly debugService: IDebugService,
@ILabelService private readonly labelService: ILabelService
) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('loadedScriptsSection', "Loaded Scripts Section") }, keybindingService, contextMenuService, configurationService);
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('loadedScriptsSection', "Loaded Scripts Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.loadedScriptsItemType = CONTEXT_LOADED_SCRIPTS_ITEM_TYPE.bindTo(contextKeyService);
}

View File

@@ -29,6 +29,7 @@ import { onUnexpectedError } from 'vs/base/common/errors';
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
import { HighlightedLabel, IHighlight } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
const $ = dom.$;
let forgetScopes = true;
@@ -49,9 +50,10 @@ export class VariablesView extends ViewletPanel {
@IKeybindingService keybindingService: IKeybindingService,
@IConfigurationService configurationService: IConfigurationService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IClipboardService private readonly clipboardService: IClipboardService
@IClipboardService private readonly clipboardService: IClipboardService,
@IContextKeyService contextKeyService: IContextKeyService
) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('variablesSection', "Variables Section") }, keybindingService, contextMenuService, configurationService);
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('variablesSection', "Variables Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
// Use scheduler to prevent unnecessary flashing
this.onFocusStackFrameScheduler = new RunOnceScheduler(() => {

View File

@@ -29,6 +29,7 @@ import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
import { FuzzyScore } from 'vs/base/common/filters';
import { IHighlight } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import { variableSetEmitter, VariablesRenderer } from 'vs/workbench/contrib/debug/browser/variablesView';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
const MAX_VALUE_RENDER_LENGTH_IN_VIEWLET = 1024;
@@ -45,8 +46,9 @@ export class WatchExpressionsView extends ViewletPanel {
@IKeybindingService keybindingService: IKeybindingService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService,
@IContextKeyService contextKeyService: IContextKeyService,
) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('watchExpressionsSection', "Watch Expressions Section") }, keybindingService, contextMenuService, configurationService);
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('watchExpressionsSection', "Watch Expressions Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.onWatchExpressionsUpdatedScheduler = new RunOnceScheduler(() => {
this.needsRefresh = false;

View File

@@ -13,9 +13,9 @@ import { Event, Emitter } from 'vs/base/common/event';
import { Cache, CacheResult } from 'vs/base/common/cache';
import { Action } from 'vs/base/common/actions';
import { isPromiseCanceledError } from 'vs/base/common/errors';
import { dispose, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { dispose, toDisposable, Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { domEvent } from 'vs/base/browser/event';
import { append, $, addClass, removeClass, finalHandler, join, toggleClass, hide, show } from 'vs/base/browser/dom';
import { append, $, addClass, removeClass, finalHandler, join, toggleClass, hide, show, addDisposableListener, EventType } from 'vs/base/browser/dom';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
@@ -52,6 +52,7 @@ import { isUndefined } from 'vs/base/common/types';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { URI } from 'vs/base/common/uri';
import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/common/webview';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
// {{SQL CARBON EDIT}}
import { renderDashboardContributions } from 'sql/workbench/parts/extensions/browser/contributionRenders';
@@ -280,6 +281,20 @@ export class ExtensionEditor extends BaseEditor {
this.content = append(body, $('.content'));
}
private onClick(element: HTMLElement, callback: () => void): IDisposable {
const disposables: DisposableStore = new DisposableStore();
disposables.add(addDisposableListener(element, EventType.CLICK, finalHandler(callback)));
disposables.add(addDisposableListener(element, EventType.KEY_UP, e => {
const keyboardEvent = new StandardKeyboardEvent(e);
if (keyboardEvent.equals(KeyCode.Space) || keyboardEvent.equals(KeyCode.Enter)) {
e.preventDefault();
e.stopPropagation();
callback();
}
}));
return disposables;
}
async setInput(input: ExtensionsInput, options: EditorOptions, token: CancellationToken): Promise<void> {
const runningExtensions = await this.extensionService.getExtensions();
const colorThemes = await this.workbenchThemeService.getColorThemes();
@@ -328,26 +343,21 @@ export class ExtensionEditor extends BaseEditor {
toggleClass(this.publisher, 'clickable', !!extension.url);
toggleClass(this.rating, 'clickable', !!extension.url);
if (extension.url) {
this.name.onclick = finalHandler(() => window.open(extension.url));
this.rating.onclick = finalHandler(() => window.open(`${extension.url}#review-details`));
this.publisher.onclick = finalHandler(() => {
this.transientDisposables.add(this.onClick(this.name, () => window.open(extension.url)));
this.transientDisposables.add(this.onClick(this.rating, () => window.open(`${extension.url}#review-details`)));
this.transientDisposables.add(this.onClick(this.publisher, () => {
this.viewletService.openViewlet(VIEWLET_ID, true)
.then(viewlet => viewlet as IExtensionsViewlet)
.then(viewlet => viewlet.search(`publisher:"${extension.publisherDisplayName}"`));
});
}));
if (extension.licenseUrl) {
this.license.onclick = finalHandler(() => window.open(extension.licenseUrl));
this.transientDisposables.add(this.onClick(this.license, () => window.open(extension.licenseUrl)));
this.license.style.display = 'initial';
} else {
this.license.onclick = null;
this.license.style.display = 'none';
}
} else {
this.name.onclick = null;
this.rating.onclick = null;
this.publisher.onclick = null;
this.license.onclick = null;
this.license.style.display = 'none';
}
@@ -362,11 +372,10 @@ export class ExtensionEditor extends BaseEditor {
// {{SQL CARBON EDIT}} - End
if (extension.repository) {
this.repository.onclick = finalHandler(() => window.open(extension.repository));
this.transientDisposables.add(this.onClick(this.repository, () => window.open(extension.repository)));
this.repository.style.display = 'initial';
}
else {
this.repository.onclick = null;
this.repository.style.display = 'none';
}
@@ -712,7 +721,7 @@ export class ExtensionEditor extends BaseEditor {
}
const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('settings', "Settings ({0})", contrib.length)),
$('summary', { tabindex: '0' }, localize('settings', "Settings ({0})", contrib.length)),
$('table', undefined,
$('tr', undefined,
$('th', undefined, localize('setting name', "Name")),
@@ -740,7 +749,7 @@ export class ExtensionEditor extends BaseEditor {
}
const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('debuggers', "Debuggers ({0})", contrib.length)),
$('summary', { tabindex: '0' }, localize('debuggers', "Debuggers ({0})", contrib.length)),
$('table', undefined,
$('tr', undefined,
$('th', undefined, localize('debugger name', "Name")),
@@ -771,7 +780,7 @@ export class ExtensionEditor extends BaseEditor {
}
const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('viewContainers', "View Containers ({0})", viewContainers.length)),
$('summary', { tabindex: '0' }, localize('viewContainers', "View Containers ({0})", viewContainers.length)),
$('table', undefined,
$('tr', undefined, $('th', undefined, localize('view container id', "ID")), $('th', undefined, localize('view container title', "Title")), $('th', undefined, localize('view container location', "Where"))),
...viewContainers.map(viewContainer => $('tr', undefined, $('td', undefined, viewContainer.id), $('td', undefined, viewContainer.title), $('td', undefined, viewContainer.location)))
@@ -797,7 +806,7 @@ export class ExtensionEditor extends BaseEditor {
}
const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('views', "Views ({0})", views.length)),
$('summary', { tabindex: '0' }, localize('views', "Views ({0})", views.length)),
$('table', undefined,
$('tr', undefined, $('th', undefined, localize('view id', "ID")), $('th', undefined, localize('view name', "Name")), $('th', undefined, localize('view location', "Where"))),
...views.map(view => $('tr', undefined, $('td', undefined, view.id), $('td', undefined, view.name), $('td', undefined, view.location)))
@@ -817,7 +826,7 @@ export class ExtensionEditor extends BaseEditor {
}
const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('localizations', "Localizations ({0})", localizations.length)),
$('summary', { tabindex: '0' }, localize('localizations', "Localizations ({0})", localizations.length)),
$('table', undefined,
$('tr', undefined, $('th', undefined, localize('localizations language id', "Language Id")), $('th', undefined, localize('localizations language name', "Language Name")), $('th', undefined, localize('localizations localized language name', "Language Name (Localized)"))),
...localizations.map(localization => $('tr', undefined, $('td', undefined, localization.languageId), $('td', undefined, localization.languageName || ''), $('td', undefined, localization.localizedLanguageName || '')))
@@ -837,7 +846,7 @@ export class ExtensionEditor extends BaseEditor {
}
const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('colorThemes', "Color Themes ({0})", contrib.length)),
$('summary', { tabindex: '0' }, localize('colorThemes', "Color Themes ({0})", contrib.length)),
$('ul', undefined, ...contrib.map(theme => $('li', undefined, theme.label)))
);
@@ -854,7 +863,7 @@ export class ExtensionEditor extends BaseEditor {
}
const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('iconThemes', "Icon Themes ({0})", contrib.length)),
$('summary', { tabindex: '0' }, localize('iconThemes', "Icon Themes ({0})", contrib.length)),
$('ul', undefined, ...contrib.map(theme => $('li', undefined, theme.label)))
);
@@ -883,7 +892,7 @@ export class ExtensionEditor extends BaseEditor {
}
const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('colors', "Colors ({0})", colors.length)),
$('summary', { tabindex: '0' }, localize('colors', "Colors ({0})", colors.length)),
$('table', undefined,
$('tr', undefined,
$('th', undefined, localize('colorId', "Id")),
@@ -916,7 +925,7 @@ export class ExtensionEditor extends BaseEditor {
}
const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('JSON Validation', "JSON Validation ({0})", contrib.length)),
$('summary', { tabindex: '0' }, localize('JSON Validation', "JSON Validation ({0})", contrib.length)),
$('table', undefined,
$('tr', undefined,
$('th', undefined, localize('fileMatch', "File Match")),
@@ -990,7 +999,7 @@ export class ExtensionEditor extends BaseEditor {
};
const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('commands', "Commands ({0})", commands.length)),
$('summary', { tabindex: '0' }, localize('commands', "Commands ({0})", commands.length)),
$('table', undefined,
$('tr', undefined,
$('th', undefined, localize('command name', "Name")),
@@ -1057,7 +1066,7 @@ export class ExtensionEditor extends BaseEditor {
}
const details = $('details', { open: true, ontoggle: onDetailsToggle },
$('summary', undefined, localize('languages', "Languages ({0})", languages.length)),
$('summary', { tabindex: '0' }, localize('languages', "Languages ({0})", languages.length)),
$('table', undefined,
$('tr', undefined,
$('th', undefined, localize('language id', "ID")),

View File

@@ -10,7 +10,7 @@ import { Event, Emitter } from 'vs/base/common/event';
import { isPromiseCanceledError, getErrorMessage } from 'vs/base/common/errors';
import { PagedModel, IPagedModel, IPager, DelayedPagedModel } from 'vs/base/common/paging';
import { SortBy, SortOrder, IQueryOptions } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionManagementServer, IExtensionManagementServerService, IExtensionTipsService, IExtensionRecommendation } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionManagementServer, IExtensionManagementServerService, IExtensionTipsService, IExtensionRecommendation, EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
@@ -44,11 +44,11 @@ import { IAction } from 'vs/base/common/actions';
import { ExtensionType, ExtensionIdentifier, IExtensionDescription, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
import { isUIExtension } from 'vs/workbench/services/extensions/common/extensionsUtil';
import { IProductService } from 'vs/platform/product/common/product';
import { SeverityIcon } from 'vs/platform/severityIcon/common/severityIcon';
// {{SQL CARBON EDIT}}
import product from 'vs/platform/product/node/product';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import product from 'vs/platform/product/node/product'; // {{SQL CARBON EDIT}}
class ExtensionsViewState extends Disposable implements IExtensionsViewState {
@@ -104,8 +104,9 @@ export class ExtensionsListView extends ViewletPanel {
@IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService,
@IExtensionManagementServerService protected readonly extensionManagementServerService: IExtensionManagementServerService,
@IProductService protected readonly productService: IProductService,
@IContextKeyService contextKeyService: IContextKeyService,
) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService);
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.server = options.server;
}
@@ -934,9 +935,10 @@ export class ServerExtensionsView extends ExtensionsListView {
@IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService,
@IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService,
@IProductService productService: IProductService,
@IContextKeyService contextKeyService: IContextKeyService,
) {
options.server = server;
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, workbenchThemeService, extensionManagementServerService, productService);
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, workbenchThemeService, extensionManagementServerService, productService, contextKeyService);
this._register(onDidChangeTitle(title => this.updateTitle(title)));
}
@@ -1080,10 +1082,14 @@ export class WorkspaceRecommendedExtensionsView extends ExtensionsListView {
return this.tipsService.getWorkspaceRecommendations()
.then(recommendations => recommendations.filter(({ extensionId }) => {
const extension = this.extensionsWorkbenchService.local.filter(i => areSameExtensions({ id: extensionId }, i.identifier))[0];
if (!extension || !extension.local || extension.state !== ExtensionState.Installed) {
if (!extension
|| !extension.local
|| extension.state !== ExtensionState.Installed
|| extension.enablementState === EnablementState.DisabledByExtensionKind
) {
return true;
}
return isUIExtension(extension.local.manifest, this.productService, this.configurationService) ? extension.server !== this.extensionManagementServerService.localExtensionManagementServer : extension.server !== this.extensionManagementServerService.remoteExtensionManagementServer;
return false;
}));
}
}

View File

@@ -256,11 +256,8 @@
font-weight: bold;
font-size: 120%;
border-bottom: 1px solid rgba(128, 128, 128, 0.22);
padding-bottom: 6px;
}
.extension-editor > .body > .content details > summary:focus {
outline: none;
padding: 3px 6px;
line-height: 22px;
}
.extension-editor > .body > .content details > summary::-webkit-details-marker {
@@ -386,4 +383,4 @@
font-size: 90%;
font-weight: 600;
opacity: 0.6;
}
}

View File

@@ -12,12 +12,13 @@ export class Query {
}
static suggestions(query: string): string[] {
const commands = ['installed', 'outdated', 'enabled', 'disabled', 'builtin', 'recommended', 'sort', 'category', 'tag', 'ext'];
const commands = ['installed', 'outdated', 'enabled', 'disabled', 'builtin', 'recommended', 'sort', 'category', 'tag', 'ext', 'id'];
const subcommands = {
'sort': ['installs', 'rating', 'name'],
'category': ['"programming languages"', 'snippets', 'linters', 'themes', 'debuggers', 'formatters', 'keymaps', '"scm providers"', 'other', '"extension packs"', '"language packs"'],
'tag': [''],
'ext': ['']
'ext': [''],
'id': ['']
};
let queryContains = (substr: string) => query.indexOf(substr) > -1;
@@ -77,4 +78,4 @@ export class Query {
equals(other: Query): boolean {
return this.value === other.value && this.sortBy === other.sortBy;
}
}
}

View File

@@ -10,7 +10,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { match } from 'vs/base/common/glob';
import * as json from 'vs/base/common/json';
import { IExtensionManagementService, IExtensionGalleryService, EXTENSION_IDENTIFIER_PATTERN, InstallOperation, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionTipsService, ExtensionRecommendationReason, IExtensionsConfigContent, RecommendationChangeNotification, IExtensionRecommendation, ExtensionRecommendationSource } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionTipsService, ExtensionRecommendationReason, IExtensionsConfigContent, RecommendationChangeNotification, IExtensionRecommendation, ExtensionRecommendationSource, IExtensionEnablementService, EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IModelService } from 'vs/editor/common/services/modelService';
import { ITextModel } from 'vs/editor/common/model';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
@@ -101,6 +101,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
@IModelService private readonly _modelService: IModelService,
@IStorageService private readonly storageService: IStorageService,
@IExtensionManagementService private readonly extensionsService: IExtensionManagementService,
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IFileService private readonly fileService: IFileService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@@ -433,6 +434,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
}
this.extensionsService.getInstalled(ExtensionType.User).then(local => {
local = local.filter(l => this.extensionEnablementService.getEnablementState(l) !== EnablementState.DisabledByExtensionKind); // Filter extensions disabled by kind
const recommendations = filteredRecs.filter(({ extensionId }) => local.every(local => !areSameExtensions({ id: extensionId }, local.identifier)));
if (!recommendations.length) {

View File

@@ -44,6 +44,8 @@ import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedPr
import { ExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/electron-browser/extensionManagementServerService';
import { IProductService } from 'vs/platform/product/common/product';
import { ILabelService } from 'vs/platform/label/common/label';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
suite('ExtensionsListView Tests', () => {
@@ -93,6 +95,7 @@ suite('ExtensionsListView Tests', () => {
instantiationService.stub(IExtensionManagementService, 'onUninstallExtension', uninstallEvent.event);
instantiationService.stub(IExtensionManagementService, 'onDidUninstallExtension', didUninstallEvent.event);
instantiationService.stub(IRemoteAgentService, RemoteAgentService);
instantiationService.stub(IContextKeyService, MockContextKeyService);
instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService {
private _localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', authority: 'vscode-local' };

View File

@@ -25,6 +25,7 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/
import { ILabelService } from 'vs/platform/label/common/label';
import { Schemas } from 'vs/base/common/network';
import { isWeb } from 'vs/base/common/platform';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
export class EmptyView extends ViewletPanel {
@@ -44,9 +45,10 @@ export class EmptyView extends ViewletPanel {
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IConfigurationService configurationService: IConfigurationService,
@IWorkbenchEnvironmentService private environmentService: IWorkbenchEnvironmentService,
@ILabelService private labelService: ILabelService
@ILabelService private labelService: ILabelService,
@IContextKeyService contextKeyService: IContextKeyService
) {
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService);
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this._register(this.contextService.onDidChangeWorkbenchState(() => this.setLabels()));
this._register(this.labelService.onDidChangeFormatters(() => this.setLabels()));
}

View File

@@ -90,7 +90,7 @@ export class ExplorerView extends ViewletPanel {
@IClipboardService private clipboardService: IClipboardService,
@IFileService private readonly fileService: IFileService
) {
super({ ...(options as IViewletPanelOptions), id: ExplorerView.ID, ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService);
super({ ...(options as IViewletPanelOptions), id: ExplorerView.ID, ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.resourceContext = instantiationService.createInstance(ResourceContextKey);
this._register(this.resourceContext);

View File

@@ -80,7 +80,7 @@ export class OpenEditorsView extends ViewletPanel {
super({
...(options as IViewletPanelOptions),
ariaHeaderLabel: nls.localize({ key: 'openEditosrSection', comment: ['Open is an adjective'] }, "Open Editors Section"),
}, keybindingService, contextMenuService, configurationService);
}, keybindingService, contextMenuService, configurationService, contextKeyService);
this.structuralRefreshDelay = 0;
this.listRefreshScheduler = new RunOnceScheduler(() => {

View File

@@ -159,6 +159,7 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem {
toggleLayout(small: boolean) {
if (this.container) {
DOM.toggleClass(this.container, 'small', small);
this.adjustInputBox();
}
}
@@ -247,7 +248,7 @@ export class MarkersFilterActionViewItem extends BaseActionViewItem {
}
private adjustInputBox(): void {
this.filterInputBox.inputElement.style.paddingRight = (DOM.getTotalWidth(this.controlsContainer) || 20) + 'px';
this.filterInputBox.inputElement.style.paddingRight = DOM.hasClass(this.container, 'small') || DOM.hasClass(this.filterBadge, 'hidden') ? '25px' : '150px';
}
// Action toolbar is swallowing some keys for action items which should not be for an input box

View File

@@ -266,7 +266,7 @@ export class OutlinePanel extends ViewletPanel {
@IContextKeyService contextKeyService: IContextKeyService,
@IContextMenuService contextMenuService: IContextMenuService,
) {
super(options, keybindingService, contextMenuService, configurationService);
super(options, keybindingService, contextMenuService, configurationService, contextKeyService);
this._outlineViewState.restore(this._storageService);
this._contextKeyFocused = OutlineViewFocused.bindTo(contextKeyService);
this._contextKeyFiltered = OutlineViewFiltered.bindTo(contextKeyService);

View File

@@ -135,6 +135,7 @@ export class SettingsEditor2 extends BaseEditor {
private tocFocusedElement: SettingsTreeGroupElement | null;
private settingsTreeScrollTop = 0;
private dimension: DOM.Dimension;
constructor(
@ITelemetryService telemetryService: ITelemetryService,
@@ -287,10 +288,11 @@ export class SettingsEditor2 extends BaseEditor {
}
layout(dimension: DOM.Dimension): void {
this.dimension = dimension;
this.layoutTrees(dimension);
const innerWidth = dimension.width - 24 * 2; // 24px padding on left and right
const monacoWidth = (innerWidth > 1000 ? 1000 : innerWidth) - 10;
const innerWidth = Math.min(1000, dimension.width) - 24 * 2; // 24px padding on left and right;
const monacoWidth = innerWidth - 10 - this.countElement.clientWidth - 12; // minus padding inside inputbox, countElement width, extra padding before countElement
this.searchWidget.layout({ height: 20, width: monacoWidth });
DOM.toggleClass(this.rootElement, 'mid-width', dimension.width < 1000 && dimension.width >= 600);
@@ -1239,7 +1241,11 @@ export class SettingsEditor2 extends BaseEditor {
: 'none';
if (!this.searchResultModel) {
this.countElement.style.display = 'none';
if (this.countElement.style.display !== 'none') {
this.countElement.style.display = 'none';
this.layout(this.dimension);
}
DOM.removeClass(this.rootElement, 'no-results');
return;
}
@@ -1252,7 +1258,10 @@ export class SettingsEditor2 extends BaseEditor {
default: this.countElement.innerText = localize('moreThanOneResult', "{0} Settings Found", count);
}
this.countElement.style.display = 'block';
if (this.countElement.style.display !== 'block') {
this.countElement.style.display = 'block';
this.layout(this.dimension);
}
DOM.toggleClass(this.rootElement, 'no-results', count === 0);
}
}

View File

@@ -73,6 +73,8 @@ export class RemoteWindowActiveIndicator extends Disposable implements IWorkbenc
this._register(CommandsRegistry.registerCommand(CLOSE_REMOTE_COMMAND_ID, _ => this.remoteAuthority && windowService.openNewWindow({ reuseWindow: true })));
this.remoteAuthority = environmentService.configuration.remoteAuthority;
Deprecated_RemoteAuthorityContext.bindTo(this.contextKeyService).set(this.remoteAuthority || '');
if (this.remoteAuthority) {
// Pending entry until extensions are ready
this.renderWindowIndicator(nls.localize('host.open', "$(sync~spin) Opening Remote..."), undefined, WINDOW_ACTIONS_COMMAND_ID);
@@ -121,7 +123,7 @@ export class RemoteWindowActiveIndicator extends Disposable implements IWorkbenc
if (this.connectionState !== newState) {
this.connectionState = newState;
RemoteConnectionState.bindTo(this.contextKeyService).set(this.connectionState);
Deprecated_RemoteAuthorityContext.bindTo(this.contextKeyService).set(isDisconnected ? 'disconnected/${this.remoteAuthority!}' : this.remoteAuthority!);
Deprecated_RemoteAuthorityContext.bindTo(this.contextKeyService).set(isDisconnected ? `disconnected/${this.remoteAuthority!}` : this.remoteAuthority!);
this.updateWindowIndicator();
}
}

View File

@@ -234,7 +234,7 @@ export class MainPanel extends ViewletPanel {
@IMenuService private readonly menuService: IMenuService,
@IConfigurationService configurationService: IConfigurationService
) {
super(options, keybindingService, contextMenuService, configurationService);
super(options, keybindingService, contextMenuService, configurationService, contextKeyService);
}
protected renderBody(container: HTMLElement): void {
@@ -324,7 +324,7 @@ export class MainPanel extends ViewletPanel {
}
private onListSelectionChange(e: IListEvent<ISCMRepository>): void {
if (e.elements.length > 0 && e.browserEvent) {
if (e.elements.length > 0) {
const scrollTop = this.list.scrollTop;
this.viewModel.setVisibleRepositories(e.elements);
this.list.scrollTop = scrollTop;
@@ -495,6 +495,7 @@ class ResourceRenderer implements IListRenderer<ISCMResource, ResourceTemplate>
const icon = theme.type === LIGHT ? resource.decorations.icon : resource.decorations.iconDark;
template.fileLabel.setFile(resource.sourceUri, { fileDecorations: { colors: false, badges: !icon, data: resource.decorations } });
template.actionBar.clear();
template.actionBar.context = resource;
const disposables = new DisposableStore();
@@ -733,7 +734,7 @@ export class RepositoryPanel extends ViewletPanel {
@IContextKeyService contextKeyService: IContextKeyService,
@IMenuService protected menuService: IMenuService
) {
super(options, keybindingService, contextMenuService, configurationService);
super(options, keybindingService, contextMenuService, configurationService, contextKeyService);
this.menus = instantiationService.createInstance(SCMMenus, this.repository.provider);
this._register(this.menus);

View File

@@ -154,7 +154,7 @@ export class SearchView extends ViewletPanel {
@IKeybindingService keybindingService: IKeybindingService,
@IStorageService storageService: IStorageService,
) {
super({ ...(options as IViewletPanelOptions), id: VIEW_ID, ariaHeaderLabel: nls.localize('searchView', "Search") }, keybindingService, contextMenuService, configurationService);
super({ ...(options as IViewletPanelOptions), id: VIEW_ID, ariaHeaderLabel: nls.localize('searchView', "Search") }, keybindingService, contextMenuService, configurationService, contextKeyService);
this.viewletVisible = Constants.SearchViewVisibleKey.bindTo(contextKeyService);
this.viewletFocused = Constants.SearchViewFocusedKey.bindTo(contextKeyService);

View File

@@ -81,10 +81,10 @@ class PartsSplash {
const layoutInfo = !this._shouldSaveLayoutInfo() ? undefined : {
sideBarSide: this._layoutService.getSideBarPosition() === Position.RIGHT ? 'right' : 'left',
editorPartMinWidth: DEFAULT_EDITOR_MIN_DIMENSIONS.width,
titleBarHeight: getTotalHeight(this._layoutService.getContainer(Parts.TITLEBAR_PART)),
activityBarWidth: getTotalWidth(this._layoutService.getContainer(Parts.ACTIVITYBAR_PART)),
sideBarWidth: getTotalWidth(this._layoutService.getContainer(Parts.SIDEBAR_PART)),
statusBarHeight: getTotalHeight(this._layoutService.getContainer(Parts.STATUSBAR_PART)),
titleBarHeight: this._layoutService.isVisible(Parts.TITLEBAR_PART) ? getTotalHeight(this._layoutService.getContainer(Parts.TITLEBAR_PART)) : 0,
activityBarWidth: this._layoutService.isVisible(Parts.ACTIVITYBAR_PART) ? getTotalWidth(this._layoutService.getContainer(Parts.ACTIVITYBAR_PART)) : 0,
sideBarWidth: this._layoutService.isVisible(Parts.SIDEBAR_PART) ? getTotalWidth(this._layoutService.getContainer(Parts.SIDEBAR_PART)) : 0,
statusBarHeight: this._layoutService.isVisible(Parts.STATUSBAR_PART) ? getTotalHeight(this._layoutService.getContainer(Parts.STATUSBAR_PART)) : 0,
};
this._textFileService.write(
URI.file(join(this._envService.userDataPath, 'rapid_render.json')),

View File

@@ -29,6 +29,12 @@ const dotnetBuild: TaskEntry = {
'\t\t\t"label": "build",',
'\t\t\t"command": "dotnet build",',
'\t\t\t"type": "shell",',
'\t\t\t"args": [',
'\t\t\t\t// Ask dotnet build to generate full paths for file names.',
'\t\t\t\t"/property:GenerateFullPaths=true",',
'\t\t\t\t// Do not generate summary otherwise it leads to duplicate errors in Problems panel',
'\t\t\t\t"/consoleloggerparameters:NoSummary"',
'\t\t\t],',
'\t\t\t"group": "build",',
'\t\t\t"presentation": {',
'\t\t\t\t"reveal": "silent"',
@@ -58,7 +64,9 @@ const msbuild: TaskEntry = {
'\t\t\t"args": [',
'\t\t\t\t// Ask msbuild to generate full paths for file names.',
'\t\t\t\t"/property:GenerateFullPaths=true",',
'\t\t\t\t"/t:build"',
'\t\t\t\t"/t:build",',
'\t\t\t\t// Do not generate summary otherwise it leads to duplicate errors in Problems panel',
'\t\t\t\t"/consoleloggerparameters:NoSummary"',
'\t\t\t],',
'\t\t\t"group": "build",',
'\t\t\t"presentation": {',

View File

@@ -211,7 +211,15 @@ export class TerminalProcessManager implements ITerminalProcessManager {
}
}
const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, this._environmentService.userHome, activeWorkspaceRootUri, this._configHelper.config.cwd);
const initialCwd = terminalEnvironment.getCwd(
shellLaunchConfig,
this._environmentService.userHome,
lastActiveWorkspace ? lastActiveWorkspace : undefined,
this._configurationResolverService,
activeWorkspaceRootUri,
this._configHelper.config.cwd,
this._logService
);
const envFromConfigValue = this._workspaceConfigurationService.inspect<ITerminalEnvironment | undefined>(`terminal.integrated.env.${platformKey}`);
const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions();
this._configHelper.showRecommendations(shellLaunchConfig);

View File

@@ -10,6 +10,7 @@ import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { IShellLaunchConfig, ITerminalEnvironment } from 'vs/workbench/contrib/terminal/common/terminal';
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
import { sanitizeProcessEnvironment } from 'vs/base/common/processes';
import { ILogService } from 'vs/platform/log/common/log';
/**
* This module contains utility functions related to the environment, cwd and paths.
@@ -119,18 +120,37 @@ function _getLangEnvVariable(locale?: string) {
return parts.join('_') + '.UTF-8';
}
export function getCwd(shell: IShellLaunchConfig, userHome: string, root?: Uri, customCwd?: string): string {
export function getCwd(
shell: IShellLaunchConfig,
userHome: string,
lastActiveWorkspace: IWorkspaceFolder | undefined,
configurationResolverService: IConfigurationResolverService | undefined,
root: Uri | undefined,
customCwd: string | undefined,
logService?: ILogService
): string {
if (shell.cwd) {
return (typeof shell.cwd === 'object') ? shell.cwd.fsPath : shell.cwd;
}
let cwd: string | undefined;
// TODO: Handle non-existent customCwd
if (!shell.ignoreConfigurationCwd && customCwd) {
if (path.isAbsolute(customCwd)) {
if (configurationResolverService) {
try {
cwd = configurationResolverService.resolve(lastActiveWorkspace, customCwd);
} catch (e) {
// There was an issue resolving a variable, just use the unresolved customCwd which
// which will fail, and log the error in the console.
cwd = customCwd;
if (logService) {
logService.error('Resolving terminal.integrated.cwd', e);
}
}
}
if (path.isAbsolute(customCwd) && !cwd) {
cwd = customCwd;
} else if (root) {
} else if (root && !cwd) {
cwd = path.join(root.fsPath, customCwd);
}
}

View File

@@ -101,31 +101,31 @@ suite('Workbench - TerminalEnvironment', () => {
}
test('should default to userHome for an empty workspace', () => {
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined), '/userHome/');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, undefined), '/userHome/');
});
test('should use to the workspace if it exists', () => {
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/foo'), undefined), '/foo');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/foo'), undefined), '/foo');
});
test('should use an absolute custom cwd as is', () => {
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, '/foo'), '/foo');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, '/foo'), '/foo');
});
test('should normalize a relative custom cwd against the workspace path', () => {
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/bar'), 'foo'), '/bar/foo');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/bar'), './foo'), '/bar/foo');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/bar'), '../foo'), '/foo');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/bar'), 'foo'), '/bar/foo');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/bar'), './foo'), '/bar/foo');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/bar'), '../foo'), '/foo');
});
test('should fall back for relative a custom cwd that doesn\'t have a workspace', () => {
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, 'foo'), '/userHome/');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, './foo'), '/userHome/');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, '../foo'), '/userHome/');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, 'foo'), '/userHome/');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, './foo'), '/userHome/');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, '../foo'), '/userHome/');
});
test('should ignore custom cwd when told to ignore', () => {
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [], ignoreConfigurationCwd: true }, '/userHome/', Uri.file('/bar'), '/foo'), '/bar');
assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [], ignoreConfigurationCwd: true }, '/userHome/', undefined, undefined, Uri.file('/bar'), '/foo'), '/bar');
});
});
});