提交 c409f85c 编写于 作者: J Joao Moreno

Merge remote-tracking branch 'origin/master'

...@@ -17,10 +17,10 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' ...@@ -17,10 +17,10 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
export const ILifecycleService = createDecorator<ILifecycleService>('lifecycleService'); export const ILifecycleService = createDecorator<ILifecycleService>('lifecycleService');
export enum UnloadReason { export enum UnloadReason {
CLOSE, CLOSE = 1,
QUIT, QUIT = 2,
RELOAD, RELOAD = 3,
LOAD LOAD = 4
} }
export interface ILifecycleService { export interface ILifecycleService {
......
...@@ -486,10 +486,11 @@ const editorConfiguration: IConfigurationNode = { ...@@ -486,10 +486,11 @@ const editorConfiguration: IConfigurationNode = {
'default': EDITOR_DEFAULTS.contribInfo.folding, 'default': EDITOR_DEFAULTS.contribInfo.folding,
'description': nls.localize('folding', "Controls whether the editor has code folding enabled") 'description': nls.localize('folding', "Controls whether the editor has code folding enabled")
}, },
'editor.hideFoldIcons': { 'editor.showFoldingControls': {
'type': 'boolean', 'type': 'string',
'default': EDITOR_DEFAULTS.contribInfo.hideFoldIcons, 'enum': ['always', 'mouseover'],
'description': nls.localize('hideFoldIcons', "Controls whether the fold icons on the gutter are automatically hidden.") 'default': EDITOR_DEFAULTS.contribInfo.showFoldingControls,
'description': nls.localize('showFoldingControls', "Controls whether the fold controls on the gutter are automatically hidden.")
}, },
'editor.matchBrackets': { 'editor.matchBrackets': {
'type': 'boolean', 'type': 'boolean',
......
...@@ -420,10 +420,10 @@ export interface IEditorOptions { ...@@ -420,10 +420,10 @@ export interface IEditorOptions {
*/ */
folding?: boolean; folding?: boolean;
/** /**
* Enable automatic hiding of non-collapsed fold icons in the gutter. * Controls whether the fold actions in the gutter stay always visible or hide unless the mouse is over the gutter.
* Defaults to true. * Defaults to 'mouseover'.
*/ */
hideFoldIcons?: boolean; showFoldingControls?: 'always' | 'mouseover';
/** /**
* Enable highlighting of matching brackets. * Enable highlighting of matching brackets.
* Defaults to true. * Defaults to true.
...@@ -736,7 +736,7 @@ export interface EditorContribOptions { ...@@ -736,7 +736,7 @@ export interface EditorContribOptions {
readonly occurrencesHighlight: boolean; readonly occurrencesHighlight: boolean;
readonly codeLens: boolean; readonly codeLens: boolean;
readonly folding: boolean; readonly folding: boolean;
readonly hideFoldIcons: boolean; readonly showFoldingControls: 'always' | 'mouseover';
readonly matchBrackets: boolean; readonly matchBrackets: boolean;
} }
...@@ -1045,7 +1045,7 @@ export class InternalEditorOptions { ...@@ -1045,7 +1045,7 @@ export class InternalEditorOptions {
&& a.occurrencesHighlight === b.occurrencesHighlight && a.occurrencesHighlight === b.occurrencesHighlight
&& a.codeLens === b.codeLens && a.codeLens === b.codeLens
&& a.folding === b.folding && a.folding === b.folding
&& a.hideFoldIcons === b.hideFoldIcons && a.showFoldingControls === b.showFoldingControls
&& a.matchBrackets === b.matchBrackets && a.matchBrackets === b.matchBrackets
); );
} }
...@@ -1542,7 +1542,7 @@ export class EditorOptionsValidator { ...@@ -1542,7 +1542,7 @@ export class EditorOptionsValidator {
occurrencesHighlight: _boolean(opts.occurrencesHighlight, defaults.occurrencesHighlight), occurrencesHighlight: _boolean(opts.occurrencesHighlight, defaults.occurrencesHighlight),
codeLens: _boolean(opts.codeLens, defaults.codeLens) && _boolean(opts.referenceInfos, true), codeLens: _boolean(opts.codeLens, defaults.codeLens) && _boolean(opts.referenceInfos, true),
folding: _boolean(opts.folding, defaults.folding), folding: _boolean(opts.folding, defaults.folding),
hideFoldIcons: _boolean(opts.hideFoldIcons, defaults.hideFoldIcons), showFoldingControls: _stringSet<'always' | 'mouseover'>(opts.showFoldingControls, defaults.showFoldingControls, ['always', 'mouseover']),
matchBrackets: _boolean(opts.matchBrackets, defaults.matchBrackets), matchBrackets: _boolean(opts.matchBrackets, defaults.matchBrackets),
}; };
} }
...@@ -1949,7 +1949,7 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = { ...@@ -1949,7 +1949,7 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = {
occurrencesHighlight: true, occurrencesHighlight: true,
codeLens: true, codeLens: true,
folding: true, folding: true,
hideFoldIcons: true, showFoldingControls: 'mouseover',
matchBrackets: true, matchBrackets: true,
}, },
}; };
...@@ -36,7 +36,7 @@ export class FoldingController implements IFoldingController { ...@@ -36,7 +36,7 @@ export class FoldingController implements IFoldingController {
private editor: ICodeEditor; private editor: ICodeEditor;
private _isEnabled: boolean; private _isEnabled: boolean;
private _hideFoldIcons: boolean; private _showFoldingControls: 'always' | 'mouseover';
private globalToDispose: IDisposable[]; private globalToDispose: IDisposable[];
private computeToken: number; private computeToken: number;
...@@ -49,7 +49,7 @@ export class FoldingController implements IFoldingController { ...@@ -49,7 +49,7 @@ export class FoldingController implements IFoldingController {
constructor(editor: ICodeEditor) { constructor(editor: ICodeEditor) {
this.editor = editor; this.editor = editor;
this._isEnabled = this.editor.getConfiguration().contribInfo.folding; this._isEnabled = this.editor.getConfiguration().contribInfo.folding;
this._hideFoldIcons = this.editor.getConfiguration().contribInfo.hideFoldIcons; this._showFoldingControls = this.editor.getConfiguration().contribInfo.showFoldingControls;
this.globalToDispose = []; this.globalToDispose = [];
this.localToDispose = []; this.localToDispose = [];
...@@ -63,9 +63,9 @@ export class FoldingController implements IFoldingController { ...@@ -63,9 +63,9 @@ export class FoldingController implements IFoldingController {
if (oldIsEnabled !== this._isEnabled) { if (oldIsEnabled !== this._isEnabled) {
this.onModelChanged(); this.onModelChanged();
} }
let oldHideFoldIcons = this._hideFoldIcons; let oldShowFoldingControls = this._showFoldingControls;
this._hideFoldIcons = this.editor.getConfiguration().contribInfo.hideFoldIcons; this._showFoldingControls = this.editor.getConfiguration().contribInfo.showFoldingControls;
if (oldHideFoldIcons !== this._hideFoldIcons) { if (oldShowFoldingControls !== this._showFoldingControls) {
this.updateHideFoldIconClass(); this.updateHideFoldIconClass();
} }
})); }));
...@@ -85,7 +85,7 @@ export class FoldingController implements IFoldingController { ...@@ -85,7 +85,7 @@ export class FoldingController implements IFoldingController {
private updateHideFoldIconClass(): void { private updateHideFoldIconClass(): void {
let domNode = this.editor.getDomNode(); let domNode = this.editor.getDomNode();
if (domNode) { if (domNode) {
dom.toggleClass(domNode, 'alwaysShowFoldIcons', this._hideFoldIcons === false); dom.toggleClass(domNode, 'alwaysShowFoldIcons', this._showFoldingControls === 'always');
} }
} }
......
...@@ -57,21 +57,24 @@ export class SnippetController2 { ...@@ -57,21 +57,24 @@ export class SnippetController2 {
overwriteBefore: number = 0, overwriteAfter: number = 0, overwriteBefore: number = 0, overwriteAfter: number = 0,
undoStopBefore: boolean = true, undoStopAfter: boolean = true undoStopBefore: boolean = true, undoStopAfter: boolean = true
): void { ): void {
if (this._snippet) {
this.cancel();
}
this._snippet = new SnippetSession(this._editor, template, overwriteBefore, overwriteAfter);
if (undoStopBefore) { if (undoStopBefore) {
this._editor.getModel().pushStackElement(); this._editor.getModel().pushStackElement();
} }
if (!this._snippet) {
// insert with new session
this._snippet = new SnippetSession(this._editor, template, overwriteBefore, overwriteAfter);
this._snippet.insert(); this._snippet.insert();
if (undoStopAfter) {
this._editor.getModel().pushStackElement();
}
this._snippetListener = [ this._snippetListener = [
this._editor.onDidChangeModel(() => this.cancel()), this._editor.onDidChangeModel(() => this.cancel()),
this._editor.onDidChangeCursorSelection(() => this._updateState()) this._editor.onDidChangeCursorSelection(() => this._updateState())
]; ];
} else {
// insert nested
this._snippet.insertNested(template, overwriteBefore, overwriteAfter);
}
if (undoStopAfter) {
this._editor.getModel().pushStackElement();
}
this._updateState(); this._updateState();
} }
......
...@@ -291,6 +291,18 @@ export class SnippetSession { ...@@ -291,6 +291,18 @@ export class SnippetSession {
this._editor.setSelections(newSelections); this._editor.setSelections(newSelections);
} }
insertNested(template: string, overwriteBefore: number = 0, overwriteAfter: number = 0): void {
const { edits } = SnippetSession.makeInsertEditsAndSnippets(
this._editor, template, overwriteBefore, overwriteAfter
);
const model = this._editor.getModel();
const selections = this._editor.getSelections();
const newSelections = model.pushEditOperations(selections, edits, () => {
return this._move(true);
});
this._editor.setSelections(newSelections);
}
next(): void { next(): void {
const newSelections = this._move(true); const newSelections = this._move(true);
this._editor.setSelections(newSelections); this._editor.setSelections(newSelections);
......
...@@ -2978,10 +2978,10 @@ declare module monaco.editor { ...@@ -2978,10 +2978,10 @@ declare module monaco.editor {
*/ */
folding?: boolean; folding?: boolean;
/** /**
* Enable automatic hiding of non-collapsed fold icons in the gutter. * Controls whether the fold actions in the gutter stay always visible or hide unless the mouse is over the gutter.
* Defaults to true. * Defaults to 'mouseover'.
*/ */
hideFoldIcons?: boolean; showFoldingControls?: 'always' | 'mouseover';
/** /**
* Enable highlighting of matching brackets. * Enable highlighting of matching brackets.
* Defaults to true. * Defaults to true.
...@@ -3239,7 +3239,7 @@ declare module monaco.editor { ...@@ -3239,7 +3239,7 @@ declare module monaco.editor {
readonly occurrencesHighlight: boolean; readonly occurrencesHighlight: boolean;
readonly codeLens: boolean; readonly codeLens: boolean;
readonly folding: boolean; readonly folding: boolean;
readonly hideFoldIcons: boolean; readonly showFoldingControls: 'always' | 'mouseover';
readonly matchBrackets: boolean; readonly matchBrackets: boolean;
} }
......
...@@ -26,16 +26,22 @@ export interface ShutdownEvent { ...@@ -26,16 +26,22 @@ export interface ShutdownEvent {
export enum ShutdownReason { export enum ShutdownReason {
/** Window is closed */ /** Window is closed */
CLOSE, CLOSE = 1,
/** Application is quit */ /** Application is quit */
QUIT, QUIT = 2,
/** Window is reloaded */ /** Window is reloaded */
RELOAD, RELOAD = 3,
/** Other configuration loaded into window */ /** Other configuration loaded into window */
LOAD LOAD = 4
}
export enum StartupKind {
NewWindow = 1,
ReloadedWindow = 3,
ReopenedWindow = 4,
} }
/** /**
...@@ -46,17 +52,22 @@ export interface ILifecycleService { ...@@ -46,17 +52,22 @@ export interface ILifecycleService {
_serviceBrand: any; _serviceBrand: any;
/**
* Value indicates how this window got loaded.
*/
readonly startupKind: StartupKind;
/** /**
* A flag indicating if the application is in the process of shutting down. This will be true * A flag indicating if the application is in the process of shutting down. This will be true
* before the onWillShutdown event is fired and false if the shutdown is being vetoed. * before the onWillShutdown event is fired and false if the shutdown is being vetoed.
*/ */
willShutdown: boolean; readonly willShutdown: boolean;
/** /**
* Fired before shutdown happens. Allows listeners to veto against the * Fired before shutdown happens. Allows listeners to veto against the
* shutdown. * shutdown.
*/ */
onWillShutdown: Event<ShutdownEvent>; readonly onWillShutdown: Event<ShutdownEvent>;
/** /**
* Fired when no client is preventing the shutdown from happening. Can be used to dispose heavy resources * Fired when no client is preventing the shutdown from happening. Can be used to dispose heavy resources
...@@ -64,11 +75,12 @@ export interface ILifecycleService { ...@@ -64,11 +75,12 @@ export interface ILifecycleService {
* *
* The event carries a shutdown reason that indicates how the shutdown was triggered. * The event carries a shutdown reason that indicates how the shutdown was triggered.
*/ */
onShutdown: Event<ShutdownReason>; readonly onShutdown: Event<ShutdownReason>;
} }
export const NullLifecycleService: ILifecycleService = { export const NullLifecycleService: ILifecycleService = {
_serviceBrand: null, _serviceBrand: null,
startupKind: StartupKind.NewWindow,
willShutdown: false, willShutdown: false,
onWillShutdown: () => ({ dispose() { } }), onWillShutdown: () => ({ dispose() { } }),
onShutdown: (reason) => ({ dispose() { } }) onShutdown: (reason) => ({ dispose() { } })
......
...@@ -177,6 +177,7 @@ export class UpdateService implements IUpdateService { ...@@ -177,6 +177,7 @@ export class UpdateService implements IUpdateService {
this._availableUpdate = data; this._availableUpdate = data;
this._onUpdateAvailable.fire({ url: update.url, version: update.version }); this._onUpdateAvailable.fire({ url: update.url, version: update.version });
this.state = State.UpdateAvailable; this.state = State.UpdateAvailable;
this.telemetryService.publicLog('update:available', { explicit, version: update.version, currentVersion: product.commit });
} else { } else {
const data: IUpdate = { const data: IUpdate = {
......
...@@ -132,6 +132,7 @@ export class WorkbenchShell { ...@@ -132,6 +132,7 @@ export class WorkbenchShell {
private windowIPCService: IWindowIPCService; private windowIPCService: IWindowIPCService;
private timerService: ITimerService; private timerService: ITimerService;
private themeService: WorkbenchThemeService; private themeService: WorkbenchThemeService;
private lifecycleService: ILifecycleService;
private container: HTMLElement; private container: HTMLElement;
private toUnbind: IDisposable[]; private toUnbind: IDisposable[];
...@@ -235,7 +236,10 @@ export class WorkbenchShell { ...@@ -235,7 +236,10 @@ export class WorkbenchShell {
theme: this.themeService.getColorTheme().id, theme: this.themeService.getColorTheme().id,
language: platform.language, language: platform.language,
experiments: this.telemetryService.getExperiments(), experiments: this.telemetryService.getExperiments(),
pinnedViewlets: info.pinnedViewlets pinnedViewlets: info.pinnedViewlets,
restoredViewlet: info.restoredViewlet,
restoredEditors: info.restoredEditors.length,
startupKind: this.lifecycleService.startupKind
}); });
// Telemetry: startup metrics // Telemetry: startup metrics
...@@ -355,6 +359,7 @@ export class WorkbenchShell { ...@@ -355,6 +359,7 @@ export class WorkbenchShell {
this.toUnbind.push(lifecycleService.onShutdown(reason => saveFontInfo(this.storageService))); this.toUnbind.push(lifecycleService.onShutdown(reason => saveFontInfo(this.storageService)));
serviceCollection.set(ILifecycleService, lifecycleService); serviceCollection.set(ILifecycleService, lifecycleService);
disposables.add(lifecycleTelemetry(this.telemetryService, lifecycleService)); disposables.add(lifecycleTelemetry(this.telemetryService, lifecycleService));
this.lifecycleService = lifecycleService;
const extensionManagementChannel = getDelayedChannel<IExtensionManagementChannel>(sharedProcess.then(c => c.getChannel('extensions'))); const extensionManagementChannel = getDelayedChannel<IExtensionManagementChannel>(sharedProcess.then(c => c.getChannel('extensions')));
serviceCollection.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementChannelClient, extensionManagementChannel)); serviceCollection.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementChannelClient, extensionManagementChannel));
......
...@@ -120,6 +120,8 @@ export interface IWorkbenchStartedInfo { ...@@ -120,6 +120,8 @@ export interface IWorkbenchStartedInfo {
restoreViewletDuration: number; restoreViewletDuration: number;
restoreEditorsDuration: number; restoreEditorsDuration: number;
pinnedViewlets: string[]; pinnedViewlets: string[];
restoredViewlet: string;
restoredEditors: string[];
} }
export interface IWorkbenchCallbacks { export interface IWorkbenchCallbacks {
...@@ -294,8 +296,8 @@ export class Workbench implements IPartService { ...@@ -294,8 +296,8 @@ export class Workbench implements IPartService {
// Restore last opened viewlet // Restore last opened viewlet
let viewletRestoreStopWatch: StopWatch; let viewletRestoreStopWatch: StopWatch;
if (!this.sideBarHidden) {
let viewletIdToRestore: string; let viewletIdToRestore: string;
if (!this.sideBarHidden) {
if (this.shouldRestoreLastOpenedViewlet()) { if (this.shouldRestoreLastOpenedViewlet()) {
viewletIdToRestore = this.storageService.get(SidebarPart.activeViewletSettingsKey, StorageScope.WORKSPACE); viewletIdToRestore = this.storageService.get(SidebarPart.activeViewletSettingsKey, StorageScope.WORKSPACE);
...@@ -321,6 +323,7 @@ export class Workbench implements IPartService { ...@@ -321,6 +323,7 @@ export class Workbench implements IPartService {
// Load Editors // Load Editors
const editorRestoreStopWatch = StopWatch.create(); const editorRestoreStopWatch = StopWatch.create();
const restoredEditors: string[] = [];
compositeAndEditorPromises.push(this.resolveEditorsToOpen().then(inputs => { compositeAndEditorPromises.push(this.resolveEditorsToOpen().then(inputs => {
let editorOpenPromise: TPromise<IEditor[]>; let editorOpenPromise: TPromise<IEditor[]>;
if (inputs.length) { if (inputs.length) {
...@@ -329,9 +332,16 @@ export class Workbench implements IPartService { ...@@ -329,9 +332,16 @@ export class Workbench implements IPartService {
editorOpenPromise = this.editorPart.restoreEditors(); editorOpenPromise = this.editorPart.restoreEditors();
} }
return editorOpenPromise.then(() => { return editorOpenPromise.then(editors => {
this.onEditorsChanged(); // make sure we show the proper background in the editor area this.onEditorsChanged(); // make sure we show the proper background in the editor area
editorRestoreStopWatch.stop(); editorRestoreStopWatch.stop();
for (const editor of editors) {
if (editor.input) {
restoredEditors.push(editor.input.getName());
} else {
restoredEditors.push(`other:${editor.getId()}`);
}
}
}); });
})); }));
...@@ -350,6 +360,8 @@ export class Workbench implements IPartService { ...@@ -350,6 +360,8 @@ export class Workbench implements IPartService {
restoreViewletDuration: viewletRestoreStopWatch ? Math.round(viewletRestoreStopWatch.elapsed()) : 0, restoreViewletDuration: viewletRestoreStopWatch ? Math.round(viewletRestoreStopWatch.elapsed()) : 0,
restoreEditorsDuration: Math.round(editorRestoreStopWatch.elapsed()), restoreEditorsDuration: Math.round(editorRestoreStopWatch.elapsed()),
pinnedViewlets: this.activitybarPart.getPinned(), pinnedViewlets: this.activitybarPart.getPinned(),
restoredViewlet: viewletIdToRestore,
restoredEditors
}); });
} }
......
...@@ -17,6 +17,7 @@ import { VIEWLET_ID } from 'vs/workbench/parts/scm/common/scm'; ...@@ -17,6 +17,7 @@ import { VIEWLET_ID } from 'vs/workbench/parts/scm/common/scm';
import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actionRegistry'; import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actionRegistry';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IExtensionsViewlet, VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/parts/extensions/common/extensions';
import { ISCMService } from 'vs/workbench/services/scm/common/scm'; import { ISCMService } from 'vs/workbench/services/scm/common/scm';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
...@@ -41,7 +42,8 @@ export class SwitchProvider extends Action { ...@@ -41,7 +42,8 @@ export class SwitchProvider extends Action {
id = SwitchProvider.ID, id = SwitchProvider.ID,
label = SwitchProvider.LABEL, label = SwitchProvider.LABEL,
@ISCMService private scmService: ISCMService, @ISCMService private scmService: ISCMService,
@IQuickOpenService private quickOpenService: IQuickOpenService @IQuickOpenService private quickOpenService: IQuickOpenService,
@IViewletService private viewletService: IViewletService
) { ) {
super('scm.switchprovider', 'Switch SCM Provider', '', true); super('scm.switchprovider', 'Switch SCM Provider', '', true);
} }
...@@ -51,6 +53,16 @@ export class SwitchProvider extends Action { ...@@ -51,6 +53,16 @@ export class SwitchProvider extends Action {
label: provider.label, label: provider.label,
run: () => this.scmService.activeProvider = provider run: () => this.scmService.activeProvider = provider
})); }));
picks.push({
label: localize('installAdditionalSCMProviders', "Install Additional SCM Providers..."), run: () => {
this.viewletService.openViewlet(EXTENSIONS_VIEWLET_ID, true).then(viewlet => viewlet as IExtensionsViewlet)
.then(viewlet => {
viewlet.search('category:"SCM Providers" @sort:installs');
viewlet.focus();
});
return this.scmService.activeProvider;
}
});
return this.quickOpenService.pick(picks); return this.quickOpenService.pick(picks);
} }
......
...@@ -16,6 +16,8 @@ import { IAction, Action } from 'vs/base/common/actions'; ...@@ -16,6 +16,8 @@ import { IAction, Action } from 'vs/base/common/actions';
import { fillInActions } from 'vs/platform/actions/browser/menuItemActionItem'; import { fillInActions } from 'vs/platform/actions/browser/menuItemActionItem';
import { ContextSubMenu } from 'vs/platform/contextview/browser/contextView'; import { ContextSubMenu } from 'vs/platform/contextview/browser/contextView';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IExtensionsViewlet, VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/parts/extensions/common/extensions';
import { ISCMService, ISCMProvider, ISCMResource, ISCMResourceGroup } from 'vs/workbench/services/scm/common/scm'; import { ISCMService, ISCMProvider, ISCMResource, ISCMResourceGroup } from 'vs/workbench/services/scm/common/scm';
import { getSCMResourceContextKey } from './scmUtil'; import { getSCMResourceContextKey } from './scmUtil';
...@@ -38,6 +40,21 @@ class SwitchProviderAction extends Action { ...@@ -38,6 +40,21 @@ class SwitchProviderAction extends Action {
} }
} }
class InstallAdditionalSCMProviders extends Action {
constructor(private viewletService: IViewletService) {
super('scm.installAdditionalSCMProviders', localize('installAdditionalSCMProviders', "Install Additional SCM Providers..."), '', true);
}
run(): TPromise<void> {
return this.viewletService.openViewlet(EXTENSIONS_VIEWLET_ID, true).then(viewlet => viewlet as IExtensionsViewlet)
.then(viewlet => {
viewlet.search('category:"SCM Providers" @sort:installs');
viewlet.focus();
});
}
}
export class SCMMenus implements IDisposable { export class SCMMenus implements IDisposable {
private disposables: IDisposable[] = []; private disposables: IDisposable[] = [];
...@@ -52,7 +69,8 @@ export class SCMMenus implements IDisposable { ...@@ -52,7 +69,8 @@ export class SCMMenus implements IDisposable {
constructor( constructor(
@IContextKeyService private contextKeyService: IContextKeyService, @IContextKeyService private contextKeyService: IContextKeyService,
@ISCMService private scmService: ISCMService, @ISCMService private scmService: ISCMService,
@IMenuService private menuService: IMenuService @IMenuService private menuService: IMenuService,
@IViewletService private viewletService: IViewletService
) { ) {
this.setActiveProvider(this.scmService.activeProvider); this.setActiveProvider(this.scmService.activeProvider);
this.scmService.onDidChangeProvider(this.setActiveProvider, this, this.disposables); this.scmService.onDidChangeProvider(this.setActiveProvider, this, this.disposables);
...@@ -92,7 +110,7 @@ export class SCMMenus implements IDisposable { ...@@ -92,7 +110,7 @@ export class SCMMenus implements IDisposable {
} }
getTitleSecondaryActions(): IAction[] { getTitleSecondaryActions(): IAction[] {
const providerSwitchActions = this.scmService.providers const providerSwitchActions: IAction[] = this.scmService.providers
.map(p => new SwitchProviderAction(p, this.scmService)); .map(p => new SwitchProviderAction(p, this.scmService));
let result = []; let result = [];
...@@ -100,14 +118,16 @@ export class SCMMenus implements IDisposable { ...@@ -100,14 +118,16 @@ export class SCMMenus implements IDisposable {
if (this.titleSecondaryActions.length > 0) { if (this.titleSecondaryActions.length > 0) {
result = result.concat(this.titleSecondaryActions); result = result.concat(this.titleSecondaryActions);
} }
if (providerSwitchActions.length > 0) {
providerSwitchActions.push(new Separator());
}
providerSwitchActions.push(new InstallAdditionalSCMProviders(this.viewletService));
if (result.length > 0 && providerSwitchActions.length > 0) { if (result.length > 0) {
result.push(new Separator()); result.push(new Separator());
} }
if (providerSwitchActions.length > 0) {
result.push(new ContextSubMenu(localize('switch provider', "Switch SCM Provider..."), providerSwitchActions)); result.push(new ContextSubMenu(localize('switch provider', "Switch SCM Provider..."), providerSwitchActions));
}
return result; return result;
} }
......
...@@ -7,26 +7,46 @@ ...@@ -7,26 +7,46 @@
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import Severity from 'vs/base/common/severity'; import Severity from 'vs/base/common/severity';
import { toErrorMessage } from 'vs/base/common/errorMessage'; import { toErrorMessage } from 'vs/base/common/errorMessage';
import { ILifecycleService, ShutdownEvent, ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle'; import { ILifecycleService, ShutdownEvent, ShutdownReason, StartupKind } from 'vs/platform/lifecycle/common/lifecycle';
import { IMessageService } from 'vs/platform/message/common/message'; import { IMessageService } from 'vs/platform/message/common/message';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IWindowIPCService } from 'vs/workbench/services/window/electron-browser/windowService'; import { IWindowIPCService } from 'vs/workbench/services/window/electron-browser/windowService';
import { ipcRenderer as ipc } from 'electron'; import { ipcRenderer as ipc } from 'electron';
import Event, { Emitter } from 'vs/base/common/event'; import Event, { Emitter } from 'vs/base/common/event';
export class LifecycleService implements ILifecycleService { export class LifecycleService implements ILifecycleService {
private static readonly _lastShutdownReasonKey = 'lifecyle.lastShutdownReason';
public _serviceBrand: any; public _serviceBrand: any;
private _onWillShutdown = new Emitter<ShutdownEvent>(); private readonly _onWillShutdown = new Emitter<ShutdownEvent>();
private _onShutdown = new Emitter<ShutdownReason>(); private readonly _onShutdown = new Emitter<ShutdownReason>();
private readonly _startupKind: StartupKind;
private _willShutdown: boolean; private _willShutdown: boolean;
constructor( constructor(
@IMessageService private messageService: IMessageService, @IMessageService private _messageService: IMessageService,
@IWindowIPCService private windowService: IWindowIPCService @IWindowIPCService private _windowService: IWindowIPCService,
@IStorageService private _storageService: IStorageService
) { ) {
this.registerListeners(); this._registerListeners();
const lastShutdownReason = this._storageService.getInteger(LifecycleService._lastShutdownReasonKey, StorageScope.WORKSPACE);
this._storageService.remove(LifecycleService._lastShutdownReasonKey, StorageScope.WORKSPACE);
if (lastShutdownReason === ShutdownReason.RELOAD) {
this._startupKind = StartupKind.ReloadedWindow;
} else if (lastShutdownReason === ShutdownReason.LOAD) {
this._startupKind = StartupKind.ReopenedWindow;
} else {
this._startupKind = StartupKind.NewWindow;
}
console.log(this.startupKind);
}
public get startupKind(): StartupKind {
return this._startupKind;
} }
public get willShutdown(): boolean { public get willShutdown(): boolean {
...@@ -41,16 +61,18 @@ export class LifecycleService implements ILifecycleService { ...@@ -41,16 +61,18 @@ export class LifecycleService implements ILifecycleService {
return this._onShutdown.event; return this._onShutdown.event;
} }
private registerListeners(): void { private _registerListeners(): void {
const windowId = this.windowService.getWindowId(); const windowId = this._windowService.getWindowId();
// Main side indicates that window is about to unload, check for vetos // Main side indicates that window is about to unload, check for vetos
ipc.on('vscode:beforeUnload', (event, reply: { okChannel: string, cancelChannel: string, reason: ShutdownReason }) => { ipc.on('vscode:beforeUnload', (event, reply: { okChannel: string, cancelChannel: string, reason: ShutdownReason }) => {
this._willShutdown = true; this._willShutdown = true;
this._storageService.store(LifecycleService._lastShutdownReasonKey, JSON.stringify(reply.reason), StorageScope.WORKSPACE);
// trigger onWillShutdown events and veto collecting // trigger onWillShutdown events and veto collecting
this.onBeforeUnload(reply.reason).done(veto => { this.onBeforeUnload(reply.reason).done(veto => {
if (veto) { if (veto) {
this._storageService.remove(LifecycleService._lastShutdownReasonKey, StorageScope.WORKSPACE);
this._willShutdown = false; // reset this flag since the shutdown has been vetoed! this._willShutdown = false; // reset this flag since the shutdown has been vetoed!
ipc.send(reply.cancelChannel, windowId); ipc.send(reply.cancelChannel, windowId);
} else { } else {
...@@ -92,7 +114,7 @@ export class LifecycleService implements ILifecycleService { ...@@ -92,7 +114,7 @@ export class LifecycleService implements ILifecycleService {
} }
}, err => { }, err => {
// error, treated like a veto, done // error, treated like a veto, done
this.messageService.show(Severity.Error, toErrorMessage(err)); this._messageService.show(Severity.Error, toErrorMessage(err));
lazyValue = true; lazyValue = true;
})); }));
} }
......
...@@ -28,7 +28,7 @@ import { IEditorInput, IEditorOptions, Position, Direction, IEditor, IResourceIn ...@@ -28,7 +28,7 @@ import { IEditorInput, IEditorOptions, Position, Direction, IEditor, IResourceIn
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { IMessageService, IConfirmation } from 'vs/platform/message/common/message'; import { IMessageService, IConfirmation } from 'vs/platform/message/common/message';
import { IWorkspace, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IWorkspace, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { ILifecycleService, ShutdownEvent, ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle'; import { ILifecycleService, ShutdownEvent, ShutdownReason, StartupKind } from 'vs/platform/lifecycle/common/lifecycle';
import { EditorStacksModel } from 'vs/workbench/common/editor/editorStacksModel'; import { EditorStacksModel } from 'vs/workbench/common/editor/editorStacksModel';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
...@@ -855,6 +855,7 @@ export class TestLifecycleService implements ILifecycleService { ...@@ -855,6 +855,7 @@ export class TestLifecycleService implements ILifecycleService {
public _serviceBrand: any; public _serviceBrand: any;
public willShutdown: boolean; public willShutdown: boolean;
public startupKind: StartupKind;
private _onWillShutdown = new Emitter<ShutdownEvent>(); private _onWillShutdown = new Emitter<ShutdownEvent>();
private _onShutdown = new Emitter<ShutdownReason>(); private _onShutdown = new Emitter<ShutdownReason>();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册