Skip to content

Commit

Permalink
#15361 Provide actions to select/copy from default settings
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 committed Nov 14, 2016
1 parent 18254d5 commit 91e2705
Show file tree
Hide file tree
Showing 12 changed files with 775 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/vs/workbench/electron-browser/workbench.main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import 'vs/workbench/browser/actions/toggleStatusbarVisibility';
import 'vs/workbench/browser/actions/toggleSidebarVisibility';
import 'vs/workbench/browser/actions/toggleSidebarPosition';
import 'vs/workbench/browser/actions/toggleEditorLayout';
import 'vs/workbench/browser/actions/openSettings';
import 'vs/workbench/parts/settings/browser/openSettings.contribution';
import 'vs/workbench/browser/actions/configureLocale';

import 'vs/workbench/parts/quickopen/browser/quickopen.contribution';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { InstallVSIXAction } from 'vs/workbench/parts/extensions/electron-browse
import { IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService, SortBy, SortOrder, IQueryOptions, LocalExtensionType } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensionsInput';
import { Query } from '../common/extensionQuery';
import { OpenGlobalSettingsAction } from 'vs/workbench/browser/actions/openSettings';
import { OpenGlobalSettingsAction } from 'vs/workbench/parts/settings/browser/openSettingsActions';
import { IProgressService } from 'vs/platform/progress/common/progress';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
Expand Down
10 changes: 3 additions & 7 deletions src/vs/workbench/parts/search/browser/searchActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import { SearchResult, Match, FileMatch, FileMatchOrMatch } from 'vs/workbench/p
import { IReplaceService } from 'vs/workbench/parts/search/common/replace';
import * as Constants from 'vs/workbench/parts/search/common/constants';
import { CollapseAllAction as TreeCollapseAction } from 'vs/base/parts/tree/browser/treeDefaults';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { OpenGlobalSettingsAction } from 'vs/workbench/browser/actions/openSettings';
import { IOpenSettingsService } from 'vs/workbench/parts/settings/common/openSettings';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
Expand Down Expand Up @@ -451,7 +450,7 @@ export class ReplaceAction extends AbstractSearchAndReplaceAction {

export class ConfigureGlobalExclusionsAction extends Action {

constructor( @IInstantiationService private instantiationService: IInstantiationService) {
constructor( @IOpenSettingsService private openSettingsService: IOpenSettingsService) {
super('configureGlobalExclusionsAction');

this.label = nls.localize('ConfigureGlobalExclusionsAction.label', "Open Settings");
Expand All @@ -460,9 +459,6 @@ export class ConfigureGlobalExclusionsAction extends Action {
}

public run(): TPromise<void> {
let action = this.instantiationService.createInstance(OpenGlobalSettingsAction, OpenGlobalSettingsAction.ID, OpenGlobalSettingsAction.LABEL);
action.run().done(() => action.dispose(), errors.onUnexpectedError);

return TPromise.as(null);
return this.openSettingsService.openGlobalSettings().then(null, errors.onUnexpectedError);
}
}
8 changes: 4 additions & 4 deletions src/vs/workbench/parts/search/browser/searchViewlet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { FindInput } from 'vs/base/browser/ui/findinput/findInput';
import { ITree } from 'vs/base/parts/tree/browser/tree';
import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
import { Scope } from 'vs/workbench/common/memento';
import { OpenGlobalSettingsAction } from 'vs/workbench/browser/actions/openSettings';
import { IOpenSettingsService } from 'vs/workbench/parts/settings/common/openSettings';
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
import { getOutOfWorkspaceEditorResources } from 'vs/workbench/common/editor';
import { FileChangeType, FileChangesEvent, EventType as FileEventType } from 'vs/platform/files/common/files';
Expand Down Expand Up @@ -103,7 +103,8 @@ export class SearchViewlet extends Viewlet {
@IContextKeyService private contextKeyService: IContextKeyService,
@IKeybindingService private keybindingService: IKeybindingService,
@IReplaceService private replaceService: IReplaceService,
@IUntitledEditorService private untitledEditorService: IUntitledEditorService
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
@IOpenSettingsService private openSettingsService: IOpenSettingsService
) {
super(Constants.VIEWLET_ID, telemetryService);

Expand Down Expand Up @@ -877,8 +878,7 @@ export class SearchViewlet extends Viewlet {
}).on(dom.EventType.CLICK, (e: MouseEvent) => {
dom.EventHelper.stop(e, false);

let action = this.instantiationService.createInstance(OpenGlobalSettingsAction, OpenGlobalSettingsAction.ID, OpenGlobalSettingsAction.LABEL);
action.run().done(() => action.dispose(), errors.onUnexpectedError);
this.openSettingsService.openWorkspaceSettings().done(() => null, errors.onUnexpectedError);
});
}
} else {
Expand Down
169 changes: 169 additions & 0 deletions src/vs/workbench/parts/settings/browser/defaultSettingsEditors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { TPromise } from 'vs/base/common/winjs.base';
import * as nls from 'vs/nls';
import URI from 'vs/base/common/uri';
import * as network from 'vs/base/common/network';
import * as strings from 'vs/base/common/strings';
import Event, { Emitter } from 'vs/base/common/event';
import { LinkedMap as Map } from 'vs/base/common/map';
import { EditorOptions, EditorInput, } from 'vs/workbench/common/editor';
import { StringEditorInput } from 'vs/workbench/common/editor/stringEditorInput';
import { ICommonCodeEditor, IEditorViewState } from 'vs/editor/common/editorCommon';
import { StringEditor } from 'vs/workbench/browser/parts/editor/stringEditor';
import { getDefaultValuesContent } from 'vs/platform/configuration/common/model';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IMessageService } from 'vs/platform/message/common/message';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IEventService } from 'vs/platform/event/common/event';
import { IThemeService } from 'vs/workbench/services/themes/common/themeService';
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IFoldingController, ID as FoldingContributionId } from 'vs/editor/contrib/folding/common/folding';

export class AbstractSettingsInput extends StringEditorInput {

private _willDispose = new Emitter<void>();
public willDispose: Event<void> = this._willDispose.event;

public get resource(): URI {
return this.getResource();
}

public dispose() {
this._willDispose.fire();
this._willDispose.dispose();
super.dispose();
}
}

export class DefaultSettingsInput extends AbstractSettingsInput {
static uri: URI = URI.from({ scheme: network.Schemas.vscode, authority: 'defaultsettings', path: '/settings.json' }); // URI is used to register JSON schema support
private static INSTANCE: DefaultSettingsInput;

public static getInstance(instantiationService: IInstantiationService, configurationService: IWorkspaceConfigurationService): DefaultSettingsInput {
if (!DefaultSettingsInput.INSTANCE) {
const editorConfig = configurationService.getConfiguration<any>();
const defaults = getDefaultValuesContent(editorConfig.editor.insertSpaces ? strings.repeat(' ', editorConfig.editor.tabSize) : '\t');

let defaultsHeader = '// ' + nls.localize('defaultSettingsHeader', "Overwrite settings by placing them into your settings file.");
defaultsHeader += '\n// ' + nls.localize('defaultSettingsHeader2', "See http://go.microsoft.com/fwlink/?LinkId=808995 for the most commonly used settings.");
DefaultSettingsInput.INSTANCE = instantiationService.createInstance(DefaultSettingsInput, nls.localize('defaultName', "Default Settings"), null, defaultsHeader + '\n' + defaults, 'application/json', false);
}

return DefaultSettingsInput.INSTANCE;
}

protected getResource(): URI {
return DefaultSettingsInput.uri;
}
}

export class DefaultKeybindingsInput extends AbstractSettingsInput {
private static INSTANCE: DefaultKeybindingsInput;

public static getInstance(instantiationService: IInstantiationService, keybindingService: IKeybindingService): DefaultKeybindingsInput {
if (!DefaultKeybindingsInput.INSTANCE) {
const defaultsHeader = '// ' + nls.localize('defaultKeybindingsHeader', "Overwrite key bindings by placing them into your key bindings file.");
const defaultContents = keybindingService.getDefaultKeybindings();

DefaultKeybindingsInput.INSTANCE = instantiationService.createInstance(DefaultKeybindingsInput, nls.localize('defaultKeybindings', "Default Keyboard Shortcuts"), null, defaultsHeader + '\n' + defaultContents, 'application/json', false);
}

return DefaultKeybindingsInput.INSTANCE;
}

protected getResource(): URI {
return URI.from({ scheme: network.Schemas.vscode, authority: 'defaultsettings', path: '/keybindings.json' }); // URI is used to register JSON schema support
}
}

export class DefaultSettingsEditor extends StringEditor {

public static ID = 'workbench.editors.defaultSettingsEditor';

private static VIEW_STATE: Map<URI, IEditorViewState> = new Map<URI, IEditorViewState>();

private inputDisposeListener;

constructor(
@ITelemetryService telemetryService: ITelemetryService,
@IInstantiationService instantiationService: IInstantiationService,
@IWorkspaceContextService contextService: IWorkspaceContextService,
@IStorageService storageService: IStorageService,
@IMessageService messageService: IMessageService,
@IConfigurationService configurationService: IConfigurationService,
@IEventService eventService: IEventService,
@IWorkbenchEditorService editorService: IWorkbenchEditorService,
@IThemeService themeService: IThemeService,
@ICommandService private commandService: ICommandService,
@IUntitledEditorService untitledEditorService: IUntitledEditorService
) {
super(telemetryService, instantiationService, contextService, storageService,
messageService, configurationService, eventService, editorService, themeService, untitledEditorService);
}

public getId(): string {
return DefaultSettingsEditor.ID;
}

public setInput(input: EditorInput, options: EditorOptions): TPromise<void> {
this.listenToInput(input);
return super.setInput(input, options);
}

public clearInput(): void {
this.saveState(<AbstractSettingsInput>this.input);
if (this.inputDisposeListener) {
this.inputDisposeListener.dispose();
}
super.clearInput();
}

protected restoreViewState(input: EditorInput) {
const viewState = DefaultSettingsEditor.VIEW_STATE.get(this.getResource(<AbstractSettingsInput>input));
if (viewState) {
this.getControl().restoreViewState(viewState);
} else if (input instanceof DefaultSettingsInput) {
this.foldAll();
}
}

private saveState(input: AbstractSettingsInput) {
const state = this.getControl().saveViewState();
if (state) {
const resource = this.getResource(input);
if (DefaultSettingsEditor.VIEW_STATE.has(resource)) {
DefaultSettingsEditor.VIEW_STATE.delete(resource);
}
DefaultSettingsEditor.VIEW_STATE.set(resource, state);
}
}

private getResource(input: AbstractSettingsInput): URI {
return input.resource;
}

private foldAll() {
const foldingController = (<ICommonCodeEditor>this.getControl()).getContribution<IFoldingController>(FoldingContributionId);
foldingController.foldAll();
}

private listenToInput(input: EditorInput) {
if (this.inputDisposeListener) {
this.inputDisposeListener.dispose();
}
if (input instanceof AbstractSettingsInput) {
this.inputDisposeListener = (<AbstractSettingsInput>input).willDispose(() => this.saveState(<AbstractSettingsInput>input));
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/vs/workbench/parts/settings/browser/media/ellipsis.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions src/vs/workbench/parts/settings/browser/media/openSettings.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

.monaco-editor .view-line :not(.inline-folded).copySetting:after {
cursor: pointer;
content:"⍈";
margin-left: 1em;
display:inline-block;
position: absolute;
height:16px;
width:16px;
}

.monaco-editor .view-line :not(.inline-folded).copySetting.select:after {
content:" ";
background-image: url('ellipsis.svg');
}

.vs-dark .monaco-editor .view-line :not(.inline-folded).copySetting.select:after {
background-image: url('ellipsis-inverse.svg');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';

import * as nls from 'vs/nls';
import { Registry } from 'vs/platform/platform';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actionRegistry';
import { IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/common/editor';
import { EditorDescriptor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { DefaultSettingsEditor, DefaultSettingsInput, DefaultKeybindingsInput } from 'vs/workbench/parts/settings/browser/defaultSettingsEditors';
import { OpenGlobalSettingsAction, OpenGlobalKeybindingsAction, OpenWorkspaceSettingsAction } from 'vs/workbench/parts/settings/browser/openSettingsActions';
import { IOpenSettingsService } from 'vs/workbench/parts/settings/common/openSettings';
import { OpenSettingsService } from 'vs/workbench/parts/settings/browser/openSettingsService';

registerSingleton(IOpenSettingsService, OpenSettingsService);

(<IEditorRegistry>Registry.as(EditorExtensions.Editors)).registerEditor(
new EditorDescriptor(
DefaultSettingsEditor.ID,
nls.localize('defaultSettingsEditor', "Default Settings Editor"),
'vs/workbench/parts/settings/browser/defaultSettingsEditors',
'DefaultSettingsEditor'
),
[
new SyncDescriptor(DefaultSettingsInput),
new SyncDescriptor(DefaultKeybindingsInput)
]
);

// Contribute Global Actions
const category = nls.localize('preferences', "Preferences");
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenGlobalSettingsAction, OpenGlobalSettingsAction.ID, OpenGlobalSettingsAction.LABEL, {
primary: null,
mac: { primary: KeyMod.CtrlCmd | KeyCode.US_COMMA }
}), 'Preferences: Open User Settings', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenGlobalKeybindingsAction, OpenGlobalKeybindingsAction.ID, OpenGlobalKeybindingsAction.LABEL), 'Preferences: Open Keyboard Shortcuts', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenWorkspaceSettingsAction, OpenWorkspaceSettingsAction.ID, OpenWorkspaceSettingsAction.LABEL), 'Preferences: Open Workspace Settings', category);
64 changes: 64 additions & 0 deletions src/vs/workbench/parts/settings/browser/openSettingsActions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';

import { TPromise } from 'vs/base/common/winjs.base';
import * as nls from 'vs/nls';
import { Action } from 'vs/base/common/actions';
import { IOpenSettingsService } from 'vs/workbench/parts/settings/common/openSettings';

export class OpenGlobalSettingsAction extends Action {

public static ID = 'workbench.action.openGlobalSettings';
public static LABEL = nls.localize('openGlobalSettings', "Open User Settings");

constructor(
id: string,
label: string,
@IOpenSettingsService private openSettingsService: IOpenSettingsService
) {
super(id, label);
}

public run(event?: any): TPromise<void> {
return this.openSettingsService.openGlobalSettings();
}
}

export class OpenGlobalKeybindingsAction extends Action {

public static ID = 'workbench.action.openGlobalKeybindings';
public static LABEL = nls.localize('openGlobalKeybindings', "Open Keyboard Shortcuts");

constructor(
id: string,
label: string,
@IOpenSettingsService private openSettingsService: IOpenSettingsService
) {
super(id, label);
}

public run(event?: any): TPromise<any> {
return this.openSettingsService.openGlobalKeybindingSettings();
}
}

export class OpenWorkspaceSettingsAction extends Action {

public static ID = 'workbench.action.openWorkspaceSettings';
public static LABEL = nls.localize('openWorkspaceSettings', "Open Workspace Settings");

constructor(
id: string,
label: string,
@IOpenSettingsService private openSettingsService: IOpenSettingsService
) {
super(id, label);
}

public run(event?: any): TPromise<void> {
return this.openSettingsService.openWorkspaceSettings();
}
}
Loading

0 comments on commit 91e2705

Please sign in to comment.