diff --git a/src/vs/workbench/parts/extensions/common/extensions.ts b/src/vs/workbench/parts/extensions/common/extensions.ts index 106fa829b9a..eaf8b9c72ca 100644 --- a/src/vs/workbench/parts/extensions/common/extensions.ts +++ b/src/vs/workbench/parts/extensions/common/extensions.ts @@ -59,5 +59,5 @@ export var IExtensionTipsService = createDecorator('exten export interface IExtensionTipsService { serviceId: ServiceIdentifier; tips: IExtension[]; - onDidChangeTips: Event; + onDidChangeTips: Event; } \ No newline at end of file diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts index 97b09ff3143..fd0cbd68c53 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts @@ -68,7 +68,7 @@ export class ExtensionTipsService implements IExtensionTipsService { serviceId: any; - private _onDidChangeTips: Emitter = new Emitter(); + private _onDidChangeTips: Emitter = new Emitter(); private _tips: { [id: string]: ExtensionTip } = Object.create(null); private _toDispose: IDisposable[] = []; private _availableExtensions: Promise; @@ -81,7 +81,7 @@ export class ExtensionTipsService implements IExtensionTipsService { ) { configurationService.loadConfiguration('extensions').then(value => { - if (value && value.enableSuggestions) { + if (value && value.experimentalSuggestions === true) { this._init(); } }, onUnexpectedError); @@ -91,7 +91,7 @@ export class ExtensionTipsService implements IExtensionTipsService { this._toDispose = disposeAll(this._toDispose); } - get onDidChangeTips(): Event { + get onDidChangeTips(): Event { return this._onDidChangeTips.event; } @@ -112,8 +112,12 @@ export class ExtensionTipsService implements IExtensionTipsService { // don't suggest what got installed this._toDispose.push(this._extensionService.onDidInstallExtension(ext => { const id = `${ext.publisher}.${ext.name}`; + let change = false; if (delete this._tips[id]) { - this._onDidChangeTips.fire(void 0); + change = true; + } + if (change) { + this._onDidChangeTips.fire(this.tips); } this._availableExtensions = this._getAvailableExtensions(); })); @@ -189,19 +193,19 @@ export class ExtensionTipsService implements IExtensionTipsService { }); if (change) { - this._onDidChangeTips.fire(undefined); + this._onDidChangeTips.fire(this.tips); } }, onUnexpectedError); } private static _extensionByPattern: { [pattern: string]: string } = { 'jrieken.vscode-omnisharp': '{**/*.cs,**/project.json,**/global.json,**/*.csproj,**/*.sln}', - 'eg2.tslint': '**/*.ts', - 'dbaeumer.vscode-eslint': '{**/*.js,**/*.es6}', - 'mkaufman.HTMLHint': '{**/*.html,**/*.htm}', - 'seanmcbreen.Spell': '**/*.md', - 'ms-vscode.jscs': '{**/*.js,**/*.es6}', - 'ms-vscode.wordcount': '**/*.md', - 'Ionide.Ionide-fsharp': '{**/*.fsx,**/*.fsi,**/*.fs,**/*.ml,**/*.mli}' + 'msjsdiag.debugger-for-chrome': '{**/*.ts,**/*.tsx**/*.js,**/*.jsx,**/*.es6}', + 'lukehoban.Go': '**/*.go', + 'ms-vscode.PowerShell': '{**/*.ps,**/*.ps1}', + 'austin.code-gnu-global': '{**/*.c,**/*.cpp,**/*.h}', + 'Ionide.Ionide-fsharp': '{**/*.fsx,**/*.fsi,**/*.fs,**/*.ml,**/*.mli}', + 'dbaeumer.vscode-eslint': '{**/*.js,**/*.jsx,**/*.es6}', + 'eg2.tslint': '{**/*.ts,**/*.tsx}' } } diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts index 892ea370c05..b5072bd315e 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts @@ -6,7 +6,7 @@ import platform = require('vs/platform/platform'); import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import statusbar = require('vs/workbench/browser/parts/statusbar/statusbar'); -import { ExtensionsStatusbarItem } from 'vs/workbench/parts/extensions/electron-browser/extensionsWidgets'; +import { ExtensionsStatusbarItem, ExtensionTipsStatusbarItem } from 'vs/workbench/parts/extensions/electron-browser/extensionsWidgets'; import { IGalleryService } from 'vs/workbench/parts/extensions/common/extensions'; import { GalleryService } from 'vs/workbench/parts/extensions/node/vsoGalleryService'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; @@ -25,4 +25,11 @@ registerSingleton(IGalleryService, GalleryService); ExtensionsStatusbarItem, statusbar.StatusbarAlignment.LEFT, 10 /* Low Priority */ +)); + +// Register Statusbar item +(platform.Registry.as(statusbar.Extensions.Statusbar)).registerStatusbarItem(new statusbar.StatusbarItemDescriptor( + ExtensionTipsStatusbarItem, + statusbar.StatusbarAlignment.LEFT, + 9 /* Low Priority */ )); \ No newline at end of file diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts index e76cd6b9f47..1461cf9046a 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts @@ -15,7 +15,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IMessageService, CloseAction } from 'vs/platform/message/common/message'; import { UninstallAction } from 'vs/workbench/parts/extensions/electron-browser/extensionsActions'; import { IQuickOpenService } from 'vs/workbench/services/quickopen/common/quickOpenService'; -import { IExtensionsService, IGalleryService, IExtension } from 'vs/workbench/parts/extensions/common/extensions'; +import { IExtensionsService, IGalleryService, IExtension, IExtensionTipsService } from 'vs/workbench/parts/extensions/common/extensions'; +import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel'; var $ = dom.emmet; @@ -83,3 +84,49 @@ export class ExtensionsStatusbarItem implements statusbar.IStatusbarItem { }; } } + +export class ExtensionTipsStatusbarItem implements statusbar.IStatusbarItem { + + private _domNode: HTMLElement; + private _label: OcticonLabel; + private _prevTips: IExtension[] = []; + + constructor( + @IQuickOpenService private _quickOpenService: IQuickOpenService, + @IExtensionTipsService private _extensionTipsService: IExtensionTipsService + ) { + + this._extensionTipsService.onDidChangeTips(tips => { + // check for new tips + let hasNewTips = false; + for (let tip of tips) { + if (this._prevTips.indexOf(tip) < 0) { + this._prevTips.push(tip); + hasNewTips = true; + } + } + if (hasNewTips) { + dom.addClass(this._domNode, 'active'); + } + // only keep 10 tips + while (this._prevTips.length > 10) { + this._prevTips.shift(); + } + }); + } + + public render(container: HTMLElement): lifecycle.IDisposable { + + this._domNode = document.createElement('a'); + this._domNode.className = 'extensions-suggestions'; + this._label = new OcticonLabel(this._domNode); + this._label.text = '$(light-bulb) extension tips'; + container.appendChild(this._domNode); + + return dom.addDisposableListener(this._domNode, 'click', event => this._onClick(event)); + } + + private _onClick(event: MouseEvent): void { + this._quickOpenService.show('ext tips ').then(() => dom.removeClass(this._domNode, 'active')); + } +} \ No newline at end of file diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/extensions.css b/src/vs/workbench/parts/extensions/electron-browser/media/extensions.css index 1367d8b40e2..0868c599fca 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/extensions.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/extensions.css @@ -132,3 +132,19 @@ background-size: 14px; background-position: 4px 50%; } + +.monaco-shell .extensions-suggestions { + visibility: hidden; + padding: 0 5px 0 5px; + -webkit-transition: visibility 250ms cubic-bezier(0.175, 0.885, 0.32, 1.275); + transition: visibility 250ms cubic-bezier(0.175, 0.885, 0.32, 1.275); +} + +.monaco-shell .extensions-suggestions.active { + visibility: inherit; + background-color: rgba(76, 119, 76, 0.9); +} + +.monaco-shell .extensions-suggestions > .octicon { + font-size: 14px; +}