search.contribution.ts 28.1 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6 7 8
/*---------------------------------------------------------------------------------------------
 *  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 'vs/css!./media/search.contribution';
9
import { Registry } from 'vs/platform/registry/common/platform';
S
Sandeep Somavarapu 已提交
10
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
11
import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor } from 'vs/workbench/browser/viewlet';
S
Sandeep Somavarapu 已提交
12
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
13
import * as nls from 'vs/nls';
14
import { TPromise } from 'vs/base/common/winjs.base';
I
isidor 已提交
15
import { Action } from 'vs/base/common/actions';
R
Rob Lourens 已提交
16
import * as objects from 'vs/base/common/objects';
17
import * as platform from 'vs/base/common/platform';
I
isidor 已提交
18
import { ExplorerFolderContext, ExplorerRootContext } from 'vs/workbench/parts/files/common/files';
19
import { SyncActionDescriptor, MenuRegistry, MenuId, ICommandAction } from 'vs/platform/actions/common/actions';
B
Benjamin Pasero 已提交
20
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
O
Oleg Mihailik 已提交
21
import { QuickOpenHandlerDescriptor, IQuickOpenRegistry, Extensions as QuickOpenExtensions } from 'vs/workbench/browser/quickopen';
J
Johannes Rieken 已提交
22 23
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
J
Johannes Rieken 已提交
24
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
25
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
26
import { getSelectionSearchString } from 'vs/editor/contrib/find/findController';
B
Benjamin Pasero 已提交
27
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
J
Johannes Rieken 已提交
28
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
S
Sandeep Somavarapu 已提交
29
import { ITree } from 'vs/base/parts/tree/browser/tree';
30
import * as Constants from 'vs/workbench/parts/search/common/constants';
31 32
import { registerContributions as replaceContributions } from 'vs/workbench/parts/search/browser/replaceContributions';
import { registerContributions as searchWidgetContributions } from 'vs/workbench/parts/search/browser/searchWidget';
33
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
34
import { ToggleCaseSensitiveKeybinding, ToggleRegexKeybinding, ToggleWholeWordKeybinding, ShowPreviousFindTermKeybinding, ShowNextFindTermKeybinding } from 'vs/editor/contrib/find/findModel';
S
Sandeep Somavarapu 已提交
35
import { ISearchWorkbenchService, SearchWorkbenchService } from 'vs/workbench/parts/search/common/searchModel';
36
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
I
isidor 已提交
37
import { SearchView } from 'vs/workbench/parts/search/browser/searchView';
B
Benjamin Pasero 已提交
38
import { defaultQuickOpenContextKey } from 'vs/workbench/browser/parts/quickopen/quickopen';
39 40
import { OpenSymbolHandler } from 'vs/workbench/parts/search/browser/openSymbolHandler';
import { OpenAnythingHandler } from 'vs/workbench/parts/search/browser/openAnythingHandler';
41
import { registerLanguageCommand } from 'vs/editor/browser/editorExtensions';
42
import { getWorkspaceSymbols } from 'vs/workbench/parts/search/common/search';
I
isidor 已提交
43
import { illegalArgument } from 'vs/base/common/errors';
I
isidor 已提交
44 45 46 47 48
import { WorkbenchListFocusContextKey, IListService } from 'vs/platform/list/browser/listService';
import URI from 'vs/base/common/uri';
import { relative } from 'path';
import { dirname } from 'vs/base/common/resources';
import { ResourceContextKey } from 'vs/workbench/common/resources';
I
isidor 已提交
49 50
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IFileService } from 'vs/platform/files/common/files';
51
import { distinct } from 'vs/base/common/arrays';
52
import { getMultiSelectedResources } from 'vs/workbench/parts/files/browser/files';
53
import { Schemas } from 'vs/base/common/network';
I
isidor 已提交
54
import { PanelRegistry, Extensions as PanelExtensions, PanelDescriptor } from 'vs/workbench/browser/panel';
55
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
56
import { openSearchView, getSearchView, ReplaceAllInFolderAction, ReplaceAllAction, CloseReplaceAction, FocusNextInputAction, FocusPreviousInputAction, FocusNextSearchResultAction, FocusPreviousSearchResultAction, ReplaceInFilesAction, FindInFilesAction, FocusActiveEditorCommand, toggleCaseSensitiveCommand, ShowNextSearchTermAction, ShowPreviousSearchTermAction, toggleRegexCommand, ShowPreviousSearchIncludeAction, ShowNextSearchIncludeAction, CollapseDeepestExpandedLevelAction, toggleWholeWordCommand, RemoveAction, ReplaceAction, ClearSearchResultsAction, copyPathCommand, copyMatchCommand, copyAllCommand, ShowNextSearchExcludeAction, ShowPreviousSearchExcludeAction, clearHistoryCommand, ShowNextReplaceTermAction, ShowPreviousReplaceTermAction } from 'vs/workbench/parts/search/browser/searchActions';
57
import { VIEW_ID, ISearchConfigurationProperties } from 'vs/platform/search/common/search';
58 59 60
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { SearchViewLocationUpdater } from 'vs/workbench/parts/search/browser/searchViewLocationUpdater';
61
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
62

S
Sandeep Somavarapu 已提交
63
registerSingleton(ISearchWorkbenchService, SearchWorkbenchService);
64 65
replaceContributions();
searchWidgetContributions();
E
Erich Gamma 已提交
66

67 68
const category = nls.localize('search', "Search");

A
Alex Dima 已提交
69
KeybindingsRegistry.registerCommandAndKeybindingRule({
E
Erich Gamma 已提交
70 71
	id: 'workbench.action.search.toggleQueryDetails',
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
72
	when: Constants.SearchViewVisibleKey,
E
Erich Gamma 已提交
73
	primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_J,
74
	handler: accessor => {
75 76 77 78
		const searchView = getSearchView(accessor.get(IViewletService), accessor.get(IPanelService));
		if (searchView) {
			searchView.toggleQueryDetails();
		}
E
Erich Gamma 已提交
79 80 81
	}
});

S
Sandeep Somavarapu 已提交
82 83 84
KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: Constants.FocusSearchFromResults,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
85
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.FirstMatchFocusKey),
S
Sandeep Somavarapu 已提交
86 87
	primary: KeyCode.UpArrow,
	handler: (accessor, args: any) => {
88
		const searchView = getSearchView(accessor.get(IViewletService), accessor.get(IPanelService));
89
		searchView.focusPreviousInputBox();
S
Sandeep Somavarapu 已提交
90 91 92 93 94 95
	}
});

KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: Constants.OpenMatchToSide,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
96
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.FileMatchOrMatchFocusKey),
S
Sandeep Somavarapu 已提交
97 98 99 100 101
	primary: KeyMod.CtrlCmd | KeyCode.Enter,
	mac: {
		primary: KeyMod.WinCtrl | KeyCode.Enter
	},
	handler: (accessor, args: any) => {
102
		const searchView = getSearchView(accessor.get(IViewletService), accessor.get(IPanelService));
103 104
		const tree: ITree = searchView.getControl();
		searchView.open(tree.getFocus(), false, true, true);
S
Sandeep Somavarapu 已提交
105 106 107 108 109 110
	}
});

KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: Constants.CancelActionId,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
111
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, WorkbenchListFocusContextKey),
S
Sandeep Somavarapu 已提交
112 113
	primary: KeyCode.Escape,
	handler: (accessor, args: any) => {
114
		const searchView = getSearchView(accessor.get(IViewletService), accessor.get(IPanelService));
115
		searchView.cancelSearch();
S
Sandeep Somavarapu 已提交
116 117 118 119 120 121
	}
});

KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: Constants.RemoveActionId,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
122
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.FileMatchOrMatchFocusKey),
S
Sandeep Somavarapu 已提交
123 124 125 126 127
	primary: KeyCode.Delete,
	mac: {
		primary: KeyMod.CtrlCmd | KeyCode.Backspace,
	},
	handler: (accessor, args: any) => {
128
		const searchView = getSearchView(accessor.get(IViewletService), accessor.get(IPanelService));
129
		const tree: ITree = searchView.getControl();
130
		accessor.get(IInstantiationService).createInstance(RemoveAction, tree, tree.getFocus(), searchView).run();
S
Sandeep Somavarapu 已提交
131 132 133 134 135 136
	}
});

KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: Constants.ReplaceActionId,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
137
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.ReplaceActiveKey, Constants.MatchFocusKey),
138
	primary: KeyMod.Shift | KeyMod.CtrlCmd | KeyCode.KEY_1,
S
Sandeep Somavarapu 已提交
139
	handler: (accessor, args: any) => {
140
		const searchView = getSearchView(accessor.get(IViewletService), accessor.get(IPanelService));
141
		const tree: ITree = searchView.getControl();
142
		accessor.get(IInstantiationService).createInstance(ReplaceAction, tree, tree.getFocus(), searchView).run();
S
Sandeep Somavarapu 已提交
143 144 145 146 147 148
	}
});

KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: Constants.ReplaceAllInFileActionId,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
149
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.ReplaceActiveKey, Constants.FileFocusKey),
150 151
	primary: KeyMod.Shift | KeyMod.CtrlCmd | KeyCode.KEY_1,
	secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter],
S
Sandeep Somavarapu 已提交
152
	handler: (accessor, args: any) => {
153
		const searchView = getSearchView(accessor.get(IViewletService), accessor.get(IPanelService));
154
		const tree: ITree = searchView.getControl();
155
		accessor.get(IInstantiationService).createInstance(ReplaceAllAction, tree, tree.getFocus(), searchView).run();
S
Sandeep Somavarapu 已提交
156 157 158
	}
});

159 160 161
KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: Constants.ReplaceAllInFolderActionId,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
162
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.ReplaceActiveKey, Constants.FolderFocusKey),
163 164
	primary: KeyMod.Shift | KeyMod.CtrlCmd | KeyCode.KEY_1,
	secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter],
165
	handler: (accessor, args: any) => {
166
		const searchView = getSearchView(accessor.get(IViewletService), accessor.get(IPanelService));
167
		const tree: ITree = searchView.getControl();
168
		accessor.get(IInstantiationService).createInstance(ReplaceAllInFolderAction, tree, tree.getFocus()).run();
169 170 171
	}
});

S
Sandeep Somavarapu 已提交
172 173 174
KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: Constants.CloseReplaceWidgetActionId,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
175
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.ReplaceInputBoxFocusedKey),
S
Sandeep Somavarapu 已提交
176 177
	primary: KeyCode.Escape,
	handler: (accessor, args: any) => {
178
		accessor.get(IInstantiationService).createInstance(CloseReplaceAction, Constants.CloseReplaceWidgetActionId, '').run();
S
Sandeep Somavarapu 已提交
179 180 181 182
	}
});

KeybindingsRegistry.registerCommandAndKeybindingRule({
183
	id: FocusNextInputAction.ID,
S
Sandeep Somavarapu 已提交
184
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
185
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.InputBoxFocusedKey),
S
Sandeep Somavarapu 已提交
186 187
	primary: KeyCode.DownArrow,
	handler: (accessor, args: any) => {
188
		accessor.get(IInstantiationService).createInstance(FocusNextInputAction, FocusNextInputAction.ID, '').run();
S
Sandeep Somavarapu 已提交
189 190 191 192
	}
});

KeybindingsRegistry.registerCommandAndKeybindingRule({
193
	id: FocusPreviousInputAction.ID,
S
Sandeep Somavarapu 已提交
194
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
195
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.InputBoxFocusedKey, Constants.SearchInputBoxFocusedKey.toNegated()),
S
Sandeep Somavarapu 已提交
196 197
	primary: KeyCode.UpArrow,
	handler: (accessor, args: any) => {
198
		accessor.get(IInstantiationService).createInstance(FocusPreviousInputAction, FocusPreviousInputAction.ID, '').run();
S
Sandeep Somavarapu 已提交
199 200 201
	}
});

R
Rob Lourens 已提交
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
MenuRegistry.appendMenuItem(MenuId.SearchContext, {
	command: {
		id: Constants.ReplaceActionId,
		title: ReplaceAction.LABEL
	},
	when: ContextKeyExpr.and(Constants.ReplaceActiveKey, Constants.MatchFocusKey),
	group: 'search',
	order: 1
});

MenuRegistry.appendMenuItem(MenuId.SearchContext, {
	command: {
		id: Constants.ReplaceAllInFolderActionId,
		title: ReplaceAllInFolderAction.LABEL
	},
	when: ContextKeyExpr.and(Constants.ReplaceActiveKey, Constants.FolderFocusKey),
	group: 'search',
	order: 1
});

MenuRegistry.appendMenuItem(MenuId.SearchContext, {
	command: {
		id: Constants.ReplaceAllInFileActionId,
		title: ReplaceAllAction.LABEL
	},
	when: ContextKeyExpr.and(Constants.ReplaceActiveKey, Constants.FileFocusKey),
	group: 'search',
	order: 1
});

MenuRegistry.appendMenuItem(MenuId.SearchContext, {
	command: {
		id: Constants.RemoveActionId,
		title: RemoveAction.LABEL
	},
	when: Constants.FileMatchOrMatchFocusKey,
	group: 'search',
	order: 2
});

R
Rob Lourens 已提交
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: Constants.CopyMatchCommandId,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
	when: Constants.FileMatchOrMatchFocusKey,
	primary: KeyMod.CtrlCmd | KeyCode.KEY_C,
	handler: copyMatchCommand
});

MenuRegistry.appendMenuItem(MenuId.SearchContext, {
	command: {
		id: Constants.CopyMatchCommandId,
		title: nls.localize('copyMatchLabel', "Copy")
	},
	when: Constants.FileMatchOrMatchFocusKey,
	group: 'search_2',
R
Rob Lourens 已提交
257
	order: 1
R
Rob Lourens 已提交
258 259
});

260 261 262
KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: Constants.CopyPathCommandId,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
263
	when: Constants.FileMatchOrFolderMatchFocusKey,
264 265 266 267 268 269 270 271 272 273 274 275
	primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_C,
	win: {
		primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_C
	},
	handler: copyPathCommand
});

MenuRegistry.appendMenuItem(MenuId.SearchContext, {
	command: {
		id: Constants.CopyPathCommandId,
		title: nls.localize('copyPathLabel', "Copy Path")
	},
276
	when: Constants.FileMatchOrFolderMatchFocusKey,
R
Rob Lourens 已提交
277
	group: 'search_2',
R
Rob Lourens 已提交
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
	order: 2
});

MenuRegistry.appendMenuItem(MenuId.SearchContext, {
	command: {
		id: Constants.CopyAllCommandId,
		title: nls.localize('copyAllLabel', "Copy All")
	},
	when: Constants.HasSearchResults,
	group: 'search_2',
	order: 3
});

CommandsRegistry.registerCommand({
	id: Constants.CopyAllCommandId,
	handler: copyAllCommand
294 295
});

296 297 298 299 300 301 302 303 304 305 306 307 308
CommandsRegistry.registerCommand({
	id: Constants.ClearSearchHistoryCommandId,
	handler: clearHistoryCommand
});

const clearSearchHistoryLabel = nls.localize('clearSearchHistoryLabel', "Clear Search History");
const ClearSearchHistoryCommand: ICommandAction = {
	id: Constants.ClearSearchHistoryCommandId,
	title: clearSearchHistoryLabel,
	category
};
MenuRegistry.addCommand(ClearSearchHistoryCommand);

309 310 311 312 313 314 315 316 317 318 319 320
CommandsRegistry.registerCommand({
	id: Constants.ToggleSearchViewPositionCommandId,
	handler: (accessor) => {
		const configurationService = accessor.get(IConfigurationService);
		const currentValue = configurationService.getValue<ISearchConfigurationProperties>('search').location;
		const toggleValue = currentValue === 'sidebar' ? 'panel' : 'sidebar';

		configurationService.updateValue('search.location', toggleValue);
	}
});

const toggleSearchViewPositionLabel = nls.localize('toggleSearchViewPositionLabel', "Toggle Search View Position");
321 322 323 324 325 326
const ToggleSearchViewPositionCommand: ICommandAction = {
	id: Constants.ToggleSearchViewPositionCommandId,
	title: toggleSearchViewPositionLabel,
	category
};
MenuRegistry.addCommand(ToggleSearchViewPositionCommand);
327
MenuRegistry.appendMenuItem(MenuId.SearchContext, {
328
	command: ToggleSearchViewPositionCommand,
329
	when: Constants.SearchViewVisibleKey,
R
Rob Lourens 已提交
330
	group: 'search_9',
331
	order: 1
332 333
});

I
isidor 已提交
334 335 336 337 338 339
const FIND_IN_FOLDER_ID = 'filesExplorer.findInFolder';
CommandsRegistry.registerCommand({
	id: FIND_IN_FOLDER_ID,
	handler: (accessor, resource?: URI) => {
		const listService = accessor.get(IListService);
		const viewletService = accessor.get(IViewletService);
340
		const panelService = accessor.get(IPanelService);
I
isidor 已提交
341
		const fileService = accessor.get(IFileService);
342
		const resources = getMultiSelectedResources(resource, listService, accessor.get(IWorkbenchEditorService));
I
isidor 已提交
343

344
		return openSearchView(viewletService, panelService, true).then(searchView => {
345 346 347 348 349 350 351 352 353 354
			if (resources && resources.length) {
				return fileService.resolveFiles(resources.map(resource => ({ resource }))).then(results => {
					const folders: URI[] = [];

					results.forEach(result => {
						if (result.success) {
							folders.push(result.stat.isDirectory ? result.stat.resource : dirname(result.stat.resource));
						}
					});

355
					searchView.searchInFolders(distinct(folders, folder => folder.toString()), (from, to) => relative(from, to));
356
				});
357
			}
358 359

			return void 0;
I
isidor 已提交
360
		});
I
isidor 已提交
361 362
	}
});
E
Erich Gamma 已提交
363

R
Rob Lourens 已提交
364 365 366 367 368 369 370
CommandsRegistry.registerCommand({
	id: ClearSearchResultsAction.ID,
	handler: (accessor, args: any) => {
		accessor.get(IInstantiationService).createInstance(ClearSearchResultsAction, ClearSearchResultsAction.ID, '').run();
	}
});

I
isidor 已提交
371 372 373
const FIND_IN_WORKSPACE_ID = 'filesExplorer.findInWorkspace';
CommandsRegistry.registerCommand({
	id: FIND_IN_WORKSPACE_ID,
I
isidor 已提交
374
	handler: (accessor) => {
375 376
		return openSearchView(accessor.get(IViewletService), accessor.get(IPanelService), true).then(searchView => {
			searchView.searchInFolders(null, (from, to) => relative(from, to));
I
isidor 已提交
377 378 379
		});
	}
});
E
Erich Gamma 已提交
380

I
isidor 已提交
381
MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
I
isidor 已提交
382 383
	group: '4_search',
	order: 10,
I
isidor 已提交
384 385 386 387
	command: {
		id: FIND_IN_FOLDER_ID,
		title: nls.localize('findInFolder', "Find in Folder...")
	},
388
	when: ContextKeyExpr.and(ExplorerFolderContext, ResourceContextKey.Scheme.isEqualTo(Schemas.file)) // todo@remote
I
isidor 已提交
389
});
E
Erich Gamma 已提交
390

I
isidor 已提交
391
MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
I
isidor 已提交
392 393
	group: '4_search',
	order: 10,
I
isidor 已提交
394 395 396 397 398 399
	command: {
		id: FIND_IN_WORKSPACE_ID,
		title: nls.localize('findInWorkspace', "Find in Workspace...")
	},
	when: ContextKeyExpr.and(ExplorerRootContext, ExplorerFolderContext.toNegated())
});
E
Erich Gamma 已提交
400 401


402
class ShowAllSymbolsAction extends Action {
403 404 405
	static readonly ID = 'workbench.action.showAllSymbols';
	static readonly LABEL = nls.localize('showTriggerActions', "Go to Symbol in Workspace...");
	static readonly ALL_SYMBOLS_PREFIX = '#';
E
Erich Gamma 已提交
406

407 408 409 410 411 412 413 414 415 416
	constructor(
		actionId: string, actionLabel: string,
		@IQuickOpenService private quickOpenService: IQuickOpenService,
		@ICodeEditorService private editorService: ICodeEditorService) {
		super(actionId, actionLabel);
		this.enabled = !!this.quickOpenService;
	}

	public run(context?: any): TPromise<void> {

417
		let prefix = ShowAllSymbolsAction.ALL_SYMBOLS_PREFIX;
418
		let inputSelection: { start: number; end: number; } = void 0;
419 420
		let editor = this.editorService.getFocusedCodeEditor();
		const word = editor && getSelectionSearchString(editor);
421 422 423 424
		if (word) {
			prefix = prefix + word;
			inputSelection = { start: 1, end: word.length + 1 };
		}
E
Erich Gamma 已提交
425

426 427 428
		this.quickOpenService.show(prefix, { inputSelection });

		return TPromise.as(null);
E
Erich Gamma 已提交
429 430 431
	}
}

432
// Register View in Viewlet and Panel area
433 434
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(new ViewletDescriptor(
	SearchView,
435
	VIEW_ID,
436 437
	nls.localize('name', "Search"),
	'search',
438
	1
439
));
I
isidor 已提交
440 441

Registry.as<PanelRegistry>(PanelExtensions.Panels).registerPanel(new PanelDescriptor(
442
	SearchView,
443
	VIEW_ID,
E
Erich Gamma 已提交
444 445 446 447 448
	nls.localize('name', "Search"),
	'search',
	10
));

449
// Register view location updater
450
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(SearchViewLocationUpdater, LifecyclePhase.Restoring);
451

S
Sandeep Somavarapu 已提交
452
// Actions
B
Benjamin Pasero 已提交
453
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
E
Erich Gamma 已提交
454

I
isidor 已提交
455 456
registry.registerWorkbenchAction(new SyncActionDescriptor(FindInFilesAction, VIEW_ID, nls.localize('showSearchViewl', "Show Search"), { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_F },
	Constants.SearchViewVisibleKey.toNegated()), 'View: Show Search', nls.localize('view', "View"));
457
registry.registerWorkbenchAction(new SyncActionDescriptor(FindInFilesAction, Constants.FindInFilesActionId, nls.localize('findInFiles', "Find in Files"), { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_F },
R
Rob Lourens 已提交
458
	Constants.SearchInputBoxFocusedKey.toNegated()), 'Find in Files', category);
S
Sandeep Somavarapu 已提交
459

460 461 462
KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: Constants.FocusActiveEditorCommandId,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
463
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.SearchInputBoxFocusedKey),
464
	handler: FocusActiveEditorCommand,
465 466 467
	primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_F
});

468 469
registry.registerWorkbenchAction(new SyncActionDescriptor(FocusNextSearchResultAction, FocusNextSearchResultAction.ID, FocusNextSearchResultAction.LABEL, { primary: KeyCode.F4 }, ContextKeyExpr.and(Constants.HasSearchResults)), 'Focus Next Search Result', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(FocusPreviousSearchResultAction, FocusPreviousSearchResultAction.ID, FocusPreviousSearchResultAction.LABEL, { primary: KeyMod.Shift | KeyCode.F4 }, ContextKeyExpr.and(Constants.HasSearchResults)), 'Focus Previous Search Result', category);
470

471
registry.registerWorkbenchAction(new SyncActionDescriptor(ReplaceInFilesAction, ReplaceInFilesAction.ID, ReplaceInFilesAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_H }), 'Replace in Files', category);
S
Sandeep Somavarapu 已提交
472

R
Rob Lourens 已提交
473
KeybindingsRegistry.registerCommandAndKeybindingRule(objects.assign({
R
Rob Lourens 已提交
474
	id: Constants.ToggleCaseSensitiveCommandId,
R
Rob Lourens 已提交
475
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
476
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.SearchInputBoxFocusedKey),
477
	handler: toggleCaseSensitiveCommand
R
Rob Lourens 已提交
478 479 480
}, ToggleCaseSensitiveKeybinding));

KeybindingsRegistry.registerCommandAndKeybindingRule(objects.assign({
R
Rob Lourens 已提交
481
	id: Constants.ToggleWholeWordCommandId,
R
Rob Lourens 已提交
482
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
483
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.SearchInputBoxFocusedKey),
484
	handler: toggleWholeWordCommand
R
Rob Lourens 已提交
485 486 487
}, ToggleWholeWordKeybinding));

KeybindingsRegistry.registerCommandAndKeybindingRule(objects.assign({
R
Rob Lourens 已提交
488
	id: Constants.ToggleRegexCommandId,
R
Rob Lourens 已提交
489
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
490
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.SearchInputBoxFocusedKey),
491
	handler: toggleRegexCommand
R
Rob Lourens 已提交
492
}, ToggleRegexKeybinding));
S
Sandeep Somavarapu 已提交
493

S
Sandeep Somavarapu 已提交
494
// Terms navigation actions
495 496
registry.registerWorkbenchAction(new SyncActionDescriptor(ShowNextSearchTermAction, ShowNextSearchTermAction.ID, ShowNextSearchTermAction.LABEL, ShowNextFindTermKeybinding, ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.SearchInputBoxFocusedKey)), 'Search: Show Next Search Term', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(ShowPreviousSearchTermAction, ShowPreviousSearchTermAction.ID, ShowPreviousSearchTermAction.LABEL, ShowPreviousFindTermKeybinding, ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.SearchInputBoxFocusedKey)), 'Search: Show Previous Search Term', category);
S
Sandeep Somavarapu 已提交
497

498 499 500
registry.registerWorkbenchAction(new SyncActionDescriptor(ShowNextReplaceTermAction, ShowNextReplaceTermAction.ID, ShowNextReplaceTermAction.LABEL, ShowNextFindTermKeybinding, ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.ReplaceInputBoxFocusedKey)), 'Search: Show Next Search Replace Term', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(ShowPreviousReplaceTermAction, ShowPreviousReplaceTermAction.ID, ShowPreviousReplaceTermAction.LABEL, ShowPreviousFindTermKeybinding, ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.ReplaceInputBoxFocusedKey)), 'Search: Show Previous Search Replace Term', category);

501 502
registry.registerWorkbenchAction(new SyncActionDescriptor(ShowNextSearchIncludeAction, ShowNextSearchIncludeAction.ID, ShowNextSearchIncludeAction.LABEL, ShowNextFindTermKeybinding, ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.PatternIncludesFocusedKey)), 'Search: Show Next Search Include Pattern', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(ShowPreviousSearchIncludeAction, ShowPreviousSearchIncludeAction.ID, ShowPreviousSearchIncludeAction.LABEL, ShowPreviousFindTermKeybinding, ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.PatternIncludesFocusedKey)), 'Search: Show Previous Search Include Pattern', category);
S
Sandeep Somavarapu 已提交
503

504 505 506
registry.registerWorkbenchAction(new SyncActionDescriptor(ShowNextSearchExcludeAction, ShowNextSearchExcludeAction.ID, ShowNextSearchExcludeAction.LABEL, ShowNextFindTermKeybinding, ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.PatternExcludesFocusedKey)), 'Search: Show Next Search Exclude Pattern', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(ShowPreviousSearchExcludeAction, ShowPreviousSearchExcludeAction.ID, ShowPreviousSearchExcludeAction.LABEL, ShowPreviousFindTermKeybinding, ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.PatternExcludesFocusedKey)), 'Search: Show Previous Search Exclude Pattern', category);

507
registry.registerWorkbenchAction(new SyncActionDescriptor(CollapseDeepestExpandedLevelAction, CollapseDeepestExpandedLevelAction.ID, CollapseDeepestExpandedLevelAction.LABEL), 'Search: Collapse All', category);
508 509 510

registry.registerWorkbenchAction(new SyncActionDescriptor(ShowAllSymbolsAction, ShowAllSymbolsAction.ID, ShowAllSymbolsAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_T }), 'Go to Symbol in Workspace...');

S
Sandeep Somavarapu 已提交
511

E
Erich Gamma 已提交
512
// Register Quick Open Handler
B
Benjamin Pasero 已提交
513
Registry.as<IQuickOpenRegistry>(QuickOpenExtensions.Quickopen).registerDefaultQuickOpenHandler(
E
Erich Gamma 已提交
514
	new QuickOpenHandlerDescriptor(
515 516
		OpenAnythingHandler,
		OpenAnythingHandler.ID,
E
Erich Gamma 已提交
517
		'',
518
		defaultQuickOpenContextKey,
B
Benjamin Pasero 已提交
519
		nls.localize('openAnythingHandlerDescription', "Go to File")
E
Erich Gamma 已提交
520 521 522
	)
);

B
Benjamin Pasero 已提交
523
Registry.as<IQuickOpenRegistry>(QuickOpenExtensions.Quickopen).registerQuickOpenHandler(
524
	new QuickOpenHandlerDescriptor(
525 526
		OpenSymbolHandler,
		OpenSymbolHandler.ID,
527
		ShowAllSymbolsAction.ALL_SYMBOLS_PREFIX,
528
		'inWorkspaceSymbolsPicker',
529 530
		[
			{
531
				prefix: ShowAllSymbolsAction.ALL_SYMBOLS_PREFIX,
532
				needsEditor: false,
B
Benjamin Pasero 已提交
533
				description: nls.localize('openSymbolDescriptionNormal', "Go to Symbol in Workspace")
534 535 536 537 538
			}
		]
	)
);

E
Erich Gamma 已提交
539
// Configuration
B
Benjamin Pasero 已提交
540
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
E
Erich Gamma 已提交
541
configurationRegistry.registerConfiguration({
542 543 544 545 546
	id: 'search',
	order: 13,
	title: nls.localize('searchConfigurationTitle', "Search"),
	type: 'object',
	properties: {
E
Erich Gamma 已提交
547
		'search.exclude': {
548 549 550 551 552
			type: 'object',
			description: nls.localize('exclude', "Configure glob patterns for excluding files and folders in searches. Inherits all glob patterns from the files.exclude setting."),
			default: { '**/node_modules': true, '**/bower_components': true },
			additionalProperties: {
				anyOf: [
E
Erich Gamma 已提交
553
					{
554 555
						type: 'boolean',
						description: nls.localize('exclude.boolean', "The glob pattern to match file paths against. Set to true or false to enable or disable the pattern."),
E
Erich Gamma 已提交
556 557
					},
					{
558 559 560 561 562 563 564
						type: 'object',
						properties: {
							when: {
								type: 'string', // expression ({ "**/*.js": { "when": "$(basename).js" } })
								pattern: '\\w*\\$\\(basename\\)\\w*',
								default: '$(basename).ext',
								description: nls.localize('exclude.when', 'Additional check on the siblings of a matching file. Use $(basename) as variable for the matching file name.')
E
Erich Gamma 已提交
565 566 567 568
							}
						}
					}
				]
S
Sandeep Somavarapu 已提交
569
			},
570
			scope: ConfigurationScope.RESOURCE
571
		},
572
		'search.useRipgrep': {
573 574 575
			type: 'boolean',
			description: nls.localize('useRipgrep', "Controls whether to use ripgrep in text and file search"),
			default: true
576
		},
577
		'search.useIgnoreFiles': {
578 579 580 581
			type: 'boolean',
			description: nls.localize('useIgnoreFiles', "Controls whether to use .gitignore and .ignore files when searching for files."),
			default: true,
			scope: ConfigurationScope.RESOURCE
582
		},
583
		'search.quickOpen.includeSymbols': {
584 585 586
			type: 'boolean',
			description: nls.localize('search.quickOpen.includeSymbols', "Configure to include results from a global symbol search in the file results for Quick Open."),
			default: false
587 588
		},
		'search.followSymlinks': {
589 590 591
			type: 'boolean',
			description: nls.localize('search.followSymlinks', "Controls whether to follow symlinks while searching."),
			default: true
592 593
		},
		'search.smartCase': {
594 595 596
			type: 'boolean',
			description: nls.localize('search.smartCase', "Searches case-insensitively if the pattern is all lowercase, otherwise, searches case-sensitively"),
			default: false
597 598
		},
		'search.globalFindClipboard': {
599 600
			type: 'boolean',
			default: false,
B
Benjamin Pasero 已提交
601
			description: nls.localize('search.globalFindClipboard', "Controls if the search view should read or modify the shared find clipboard on macOS"),
602 603 604
			included: platform.isMacintosh
		},
		'search.location': {
605
			type: 'string',
606 607
			enum: ['sidebar', 'panel'],
			default: 'sidebar',
608
			description: nls.localize('search.location', "Controls if the search will be shown as a view in the sidebar or as a panel in the panel area for more horizontal space."),
609
		}
E
Erich Gamma 已提交
610
	}
J
Johannes Rieken 已提交
611
});
612

613
registerLanguageCommand('_executeWorkspaceSymbolProvider', function (accessor, args: { query: string; }) {
614 615 616 617 618 619
	let { query } = args;
	if (typeof query !== 'string') {
		throw illegalArgument();
	}
	return getWorkspaceSymbols(query);
});