quickCommand.ts 4.3 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

A
Alex Dima 已提交
7
import * as nls from 'vs/nls';
A
Alex Dima 已提交
8 9 10 11 12 13 14 15
import {IAction} from 'vs/base/common/actions';
import {onUnexpectedError} from 'vs/base/common/errors';
import {matchesFuzzy} from 'vs/base/common/filters';
import * as strings from 'vs/base/common/strings';
import {TPromise} from 'vs/base/common/winjs.base';
import {IContext, IHighlight, QuickOpenEntryGroup, QuickOpenModel} from 'vs/base/parts/quickopen/browser/quickOpenModel';
import {IAutoFocus, Mode} from 'vs/base/parts/quickopen/common/quickOpen';
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
A
Alex Dima 已提交
16 17
import {EditorAction} from 'vs/editor/common/editorAction';
import {Behaviour} from 'vs/editor/common/editorActionEnablement';
A
Alex Dima 已提交
18 19
import {ICommonCodeEditor, IEditor, IEditorActionDescriptorData} from 'vs/editor/common/editorCommon';
import {BaseEditorQuickOpenAction} from './editorQuickOpen';
E
Erich Gamma 已提交
20

A
Alex Dima 已提交
21
export class EditorActionCommandEntry extends QuickOpenEntryGroup {
22
	private key: string;
A
Alex Dima 已提交
23 24
	private action: IAction;
	private editor: IEditor;
E
Erich Gamma 已提交
25

A
Alex Dima 已提交
26
	constructor(key: string, highlights: IHighlight[], action: IAction, editor: IEditor) {
E
Erich Gamma 已提交
27 28 29 30 31 32 33 34
		super();

		this.key = key;
		this.setHighlights(highlights);
		this.action = action;
		this.editor = editor;
	}

35
	public getLabel(): string {
E
Erich Gamma 已提交
36 37 38
		return this.action.label;
	}

39 40 41 42 43
	public getAriaLabel(): string {
		return nls.localize('ariaLabelEntry', "{0}, commands", this.getLabel());
	}

	public getGroupLabel(): string {
E
Erich Gamma 已提交
44 45 46
		return this.key;
	}

A
Alex Dima 已提交
47 48
	public run(mode: Mode, context: IContext): boolean {
		if (mode === Mode.OPEN) {
E
Erich Gamma 已提交
49 50

			// Use a timeout to give the quick open widget a chance to close itself first
51
			TPromise.timeout(50).done(() => {
E
Erich Gamma 已提交
52 53 54 55 56 57

				// Some actions are enabled only when editor has focus
				this.editor.focus();

				if (this.action.enabled) {
					try {
58
						let promise = this.action.run() || TPromise.as(null);
A
Alex Dima 已提交
59
						promise.done(null, onUnexpectedError);
E
Erich Gamma 已提交
60
					} catch (error) {
A
Alex Dima 已提交
61
						onUnexpectedError(error);
E
Erich Gamma 已提交
62 63
					}
				}
A
Alex Dima 已提交
64
			}, onUnexpectedError);
E
Erich Gamma 已提交
65 66 67 68 69 70 71 72

			return true;
		}

		return false;
	}
}

A
Alex Dima 已提交
73
export class QuickCommandAction extends BaseEditorQuickOpenAction {
E
Erich Gamma 已提交
74 75 76 77 78

	public static ID = 'editor.action.quickCommand';

	private _keybindingService: IKeybindingService;

A
Alex Dima 已提交
79
	constructor(descriptor: IEditorActionDescriptorData, editor: ICommonCodeEditor, @IKeybindingService keybindingService: IKeybindingService) {
E
Erich Gamma 已提交
80 81 82 83
		super(descriptor, editor, nls.localize('QuickCommandAction.label', "Command Palette"), Behaviour.WidgetFocus | Behaviour.ShowInContextMenu);
		this._keybindingService = keybindingService;
	}

A
Alex Dima 已提交
84 85
	_getModel(value: string): QuickOpenModel {
		return new QuickOpenModel(this._editorActionsToEntries(this.editor.getActions(), value));
E
Erich Gamma 已提交
86 87 88 89 90 91
	}

	public getGroupId(): string {
		return '4_tools/1_commands';
	}

A
Alex Dima 已提交
92
	_sort(elementA: QuickOpenEntryGroup, elementB: QuickOpenEntryGroup): number {
93 94
		let elementAName = elementA.getLabel().toLowerCase();
		let elementBName = elementB.getLabel().toLowerCase();
E
Erich Gamma 已提交
95

A
Alex Dima 已提交
96
		return strings.localeCompare(elementAName, elementBName);
E
Erich Gamma 已提交
97 98
	}

A
Alex Dima 已提交
99
	_editorActionsToEntries(actions: IAction[], searchValue: string): EditorActionCommandEntry[] {
100
		let entries: EditorActionCommandEntry[] = [];
E
Erich Gamma 已提交
101

102 103
		for (let i = 0; i < actions.length; i++) {
			let action = actions[i];
E
Erich Gamma 已提交
104

105
			let editorAction = <EditorAction>action;
E
Erich Gamma 已提交
106 107 108 109 110

			if (!editorAction.isSupported()) {
				continue; // do not show actions that are not supported in this context
			}

111
			let keys = this._keybindingService.lookupKeybindings(editorAction.id).map(k => this._keybindingService.getLabelFor(k));
E
Erich Gamma 已提交
112 113

			if (action.label) {
A
Alex Dima 已提交
114
				let highlights = matchesFuzzy(searchValue, action.label);
E
Erich Gamma 已提交
115 116 117 118 119 120 121 122 123 124 125 126
				if (highlights) {
					entries.push(new EditorActionCommandEntry(keys.length > 0 ? keys.join(', ') : '', highlights, action, this.editor));
				}
			}
		}

		// Sort by name
		entries = entries.sort(this._sort);

		return entries;
	}

A
Alex Dima 已提交
127
	_getAutoFocus(searchValue: string): IAutoFocus {
E
Erich Gamma 已提交
128 129 130 131 132 133 134 135 136 137
		return {
			autoFocusFirstEntry: true,
			autoFocusPrefixMatch: searchValue
		};
	}

	_getInputAriaLabel(): string {
		return nls.localize('quickCommandActionInput', "Type the name of an action you want to execute");
	}
}