search.contribution.ts 25.0 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 } 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
import { IFileService } from 'vs/platform/files/common/files';
50
import { distinct } from 'vs/base/common/arrays';
51
import { getMultiSelectedResources } from 'vs/workbench/parts/files/browser/files';
52
import { Schemas } from 'vs/base/common/network';
I
isidor 已提交
53
import { PanelRegistry, Extensions as PanelExtensions, PanelDescriptor } from 'vs/workbench/browser/panel';
54
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
55
import { openSearchView, getSearchView, ReplaceAllInFolderAction, ReplaceAllAction, CloseReplaceAction, FocusNextSearchResultAction, FocusPreviousSearchResultAction, ReplaceInFilesAction, FindInFilesAction, toggleCaseSensitiveCommand, toggleRegexCommand, CollapseDeepestExpandedLevelAction, toggleWholeWordCommand, RemoveAction, ReplaceAction, ClearSearchResultsAction, copyPathCommand, copyMatchCommand, copyAllCommand, clearHistoryCommand, FocusNextInputAction, FocusPreviousInputAction } from 'vs/workbench/parts/search/browser/searchActions';
56
import { VIEW_ID, ISearchConfigurationProperties } from 'vs/platform/search/common/search';
57 58 59
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';
60
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
61
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
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),
86
	primary: KeyMod.CtrlCmd | KeyCode.UpArrow,
S
Sandeep Somavarapu 已提交
87
	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 183 184 185
KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: FocusNextInputAction.ID,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.InputBoxFocusedKey),
186
	primary: KeyMod.CtrlCmd | KeyCode.DownArrow,
187 188 189 190 191 192 193 194 195
	handler: (accessor, args: any) => {
		accessor.get(IInstantiationService).createInstance(FocusNextInputAction, FocusNextInputAction.ID, '').run();
	}
});

KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: FocusPreviousInputAction.ID,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.InputBoxFocusedKey, Constants.SearchInputBoxFocusedKey.toNegated()),
196
	primary: KeyMod.CtrlCmd | KeyCode.UpArrow,
197 198 199 200 201
	handler: (accessor, args: any) => {
		accessor.get(IInstantiationService).createInstance(FocusPreviousInputAction, FocusPreviousInputAction.ID, '').run();
	}
});

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(IEditorService));
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

455 456 457
// Show Search and Find in Files are redundant, but we can't break keybindings by removing one. So it's the same action, same keybinding, registered to different IDs
registry.registerWorkbenchAction(new SyncActionDescriptor(FindInFilesAction, VIEW_ID, nls.localize('showSearchViewl', "Show Search"), { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_F }), 'View: Show Search', nls.localize('view', "View"));
registry.registerWorkbenchAction(new SyncActionDescriptor(FindInFilesAction, Constants.FindInFilesActionId, nls.localize('findInFiles', "Find in Files"), { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_F }), 'Find in Files', category);
458

459 460
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);
461

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

R
Rob Lourens 已提交
464
KeybindingsRegistry.registerCommandAndKeybindingRule(objects.assign({
R
Rob Lourens 已提交
465
	id: Constants.ToggleCaseSensitiveCommandId,
R
Rob Lourens 已提交
466
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
467
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.SearchInputBoxFocusedKey),
468
	handler: toggleCaseSensitiveCommand
R
Rob Lourens 已提交
469 470 471
}, ToggleCaseSensitiveKeybinding));

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

KeybindingsRegistry.registerCommandAndKeybindingRule(objects.assign({
R
Rob Lourens 已提交
479
	id: Constants.ToggleRegexCommandId,
R
Rob Lourens 已提交
480
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
I
isidor 已提交
481
	when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.SearchInputBoxFocusedKey),
482
	handler: toggleRegexCommand
R
Rob Lourens 已提交
483
}, ToggleRegexKeybinding));
S
Sandeep Somavarapu 已提交
484

485
registry.registerWorkbenchAction(new SyncActionDescriptor(CollapseDeepestExpandedLevelAction, CollapseDeepestExpandedLevelAction.ID, CollapseDeepestExpandedLevelAction.LABEL), 'Search: Collapse All', category);
486 487
registry.registerWorkbenchAction(new SyncActionDescriptor(ShowAllSymbolsAction, ShowAllSymbolsAction.ID, ShowAllSymbolsAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_T }), 'Go to Symbol in Workspace...');

S
Sandeep Somavarapu 已提交
488

E
Erich Gamma 已提交
489
// Register Quick Open Handler
B
Benjamin Pasero 已提交
490
Registry.as<IQuickOpenRegistry>(QuickOpenExtensions.Quickopen).registerDefaultQuickOpenHandler(
E
Erich Gamma 已提交
491
	new QuickOpenHandlerDescriptor(
492 493
		OpenAnythingHandler,
		OpenAnythingHandler.ID,
E
Erich Gamma 已提交
494
		'',
495
		defaultQuickOpenContextKey,
B
Benjamin Pasero 已提交
496
		nls.localize('openAnythingHandlerDescription', "Go to File")
E
Erich Gamma 已提交
497 498 499
	)
);

B
Benjamin Pasero 已提交
500
Registry.as<IQuickOpenRegistry>(QuickOpenExtensions.Quickopen).registerQuickOpenHandler(
501
	new QuickOpenHandlerDescriptor(
502 503
		OpenSymbolHandler,
		OpenSymbolHandler.ID,
504
		ShowAllSymbolsAction.ALL_SYMBOLS_PREFIX,
505
		'inWorkspaceSymbolsPicker',
506 507
		[
			{
508
				prefix: ShowAllSymbolsAction.ALL_SYMBOLS_PREFIX,
509
				needsEditor: false,
B
Benjamin Pasero 已提交
510
				description: nls.localize('openSymbolDescriptionNormal', "Go to Symbol in Workspace")
511 512 513 514 515
			}
		]
	)
);

E
Erich Gamma 已提交
516
// Configuration
B
Benjamin Pasero 已提交
517
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
E
Erich Gamma 已提交
518
configurationRegistry.registerConfiguration({
519 520 521 522 523
	id: 'search',
	order: 13,
	title: nls.localize('searchConfigurationTitle', "Search"),
	type: 'object',
	properties: {
E
Erich Gamma 已提交
524
		'search.exclude': {
525 526 527 528 529
			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 已提交
530
					{
531 532
						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 已提交
533 534
					},
					{
535 536 537 538 539 540 541
						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 已提交
542 543 544 545
							}
						}
					}
				]
S
Sandeep Somavarapu 已提交
546
			},
547
			scope: ConfigurationScope.RESOURCE
548
		},
549
		'search.useRipgrep': {
550 551 552
			type: 'boolean',
			description: nls.localize('useRipgrep', "Controls whether to use ripgrep in text and file search"),
			default: true
553
		},
554
		'search.useIgnoreFiles': {
555 556 557 558
			type: 'boolean',
			description: nls.localize('useIgnoreFiles', "Controls whether to use .gitignore and .ignore files when searching for files."),
			default: true,
			scope: ConfigurationScope.RESOURCE
559
		},
560
		'search.quickOpen.includeSymbols': {
561 562 563
			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
564 565
		},
		'search.followSymlinks': {
566 567 568
			type: 'boolean',
			description: nls.localize('search.followSymlinks', "Controls whether to follow symlinks while searching."),
			default: true
569 570
		},
		'search.smartCase': {
571 572 573
			type: 'boolean',
			description: nls.localize('search.smartCase', "Searches case-insensitively if the pattern is all lowercase, otherwise, searches case-sensitively"),
			default: false
574 575
		},
		'search.globalFindClipboard': {
576 577
			type: 'boolean',
			default: false,
B
Benjamin Pasero 已提交
578
			description: nls.localize('search.globalFindClipboard', "Controls if the search view should read or modify the shared find clipboard on macOS"),
579 580 581
			included: platform.isMacintosh
		},
		'search.location': {
582
			type: 'string',
583 584
			enum: ['sidebar', 'panel'],
			default: 'sidebar',
585
			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."),
586
		}
E
Erich Gamma 已提交
587
	}
J
Johannes Rieken 已提交
588
});
589

590
registerLanguageCommand('_executeWorkspaceSymbolProvider', function (accessor, args: { query: string; }) {
591 592 593 594 595 596
	let { query } = args;
	if (typeof query !== 'string') {
		throw illegalArgument();
	}
	return getWorkspaceSymbols(query);
});