search.contribution.ts 28.2 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
		openSearchView(accessor.get(IViewletService), accessor.get(IPanelService), true)
			.then(view => view.toggleQueryDetails());
E
Erich Gamma 已提交
77 78 79
	}
});

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

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

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

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

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

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

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

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

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

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

R
Rob Lourens 已提交
200 201 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
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 已提交
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
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 已提交
255
	order: 1
R
Rob Lourens 已提交
256 257
});

258 259 260
KeybindingsRegistry.registerCommandAndKeybindingRule({
	id: Constants.CopyPathCommandId,
	weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
261
	when: Constants.FileMatchOrFolderMatchFocusKey,
262 263 264 265 266 267 268 269 270 271 272 273
	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")
	},
274
	when: Constants.FileMatchOrFolderMatchFocusKey,
R
Rob Lourens 已提交
275
	group: 'search_2',
R
Rob Lourens 已提交
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
	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
292 293
});

294 295 296 297 298 299 300 301 302 303 304 305 306
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);

307 308 309 310 311 312 313 314 315 316 317 318
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");
319 320 321 322 323 324
const ToggleSearchViewPositionCommand: ICommandAction = {
	id: Constants.ToggleSearchViewPositionCommandId,
	title: toggleSearchViewPositionLabel,
	category
};
MenuRegistry.addCommand(ToggleSearchViewPositionCommand);
325
MenuRegistry.appendMenuItem(MenuId.SearchContext, {
326
	command: ToggleSearchViewPositionCommand,
327
	when: Constants.SearchViewVisibleKey,
R
Rob Lourens 已提交
328
	group: 'search_9',
329
	order: 1
330 331
});

I
isidor 已提交
332 333 334 335 336 337
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);
338
		const panelService = accessor.get(IPanelService);
I
isidor 已提交
339
		const fileService = accessor.get(IFileService);
340
		const resources = getMultiSelectedResources(resource, listService, accessor.get(IWorkbenchEditorService));
I
isidor 已提交
341

342
		return openSearchView(viewletService, panelService, true).then(searchView => {
343 344 345 346 347 348 349 350 351 352
			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));
						}
					});

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

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

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

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

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

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


400
class ShowAllSymbolsAction extends Action {
401 402 403
	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 已提交
404

405 406 407 408 409 410 411 412 413 414
	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> {

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

424 425 426
		this.quickOpenService.show(prefix, { inputSelection });

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

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

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

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

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

I
isidor 已提交
453 454
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"));
455
registry.registerWorkbenchAction(new SyncActionDescriptor(FindInFilesAction, Constants.FindInFilesActionId, nls.localize('findInFiles', "Find in Files"), { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_F },
R
Rob Lourens 已提交
456
	Constants.SearchInputBoxFocusedKey.toNegated()), 'Find in Files', category);
S
Sandeep Somavarapu 已提交
457

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

466 467
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);
468

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

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

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

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

S
Sandeep Somavarapu 已提交
492
// Terms navigation actions
493 494
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 已提交
495

496 497 498
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);

499 500
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 已提交
501

502 503 504
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);

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

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

S
Sandeep Somavarapu 已提交
509

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

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

E
Erich Gamma 已提交
537
// Configuration
B
Benjamin Pasero 已提交
538
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
E
Erich Gamma 已提交
539
configurationRegistry.registerConfiguration({
540 541 542 543 544
	id: 'search',
	order: 13,
	title: nls.localize('searchConfigurationTitle', "Search"),
	type: 'object',
	properties: {
E
Erich Gamma 已提交
545
		'search.exclude': {
546 547 548 549 550
			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 已提交
551
					{
552 553
						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 已提交
554 555
					},
					{
556 557 558 559 560 561 562
						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 已提交
563 564 565 566
							}
						}
					}
				]
S
Sandeep Somavarapu 已提交
567
			},
568
			scope: ConfigurationScope.RESOURCE
569
		},
570
		'search.useRipgrep': {
571 572 573
			type: 'boolean',
			description: nls.localize('useRipgrep', "Controls whether to use ripgrep in text and file search"),
			default: true
574
		},
575
		'search.useIgnoreFiles': {
576 577 578 579
			type: 'boolean',
			description: nls.localize('useIgnoreFiles', "Controls whether to use .gitignore and .ignore files when searching for files."),
			default: true,
			scope: ConfigurationScope.RESOURCE
580
		},
581
		'search.quickOpen.includeSymbols': {
582 583 584
			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
585 586
		},
		'search.followSymlinks': {
587 588 589
			type: 'boolean',
			description: nls.localize('search.followSymlinks', "Controls whether to follow symlinks while searching."),
			default: true
590 591
		},
		'search.smartCase': {
592 593 594
			type: 'boolean',
			description: nls.localize('search.smartCase', "Searches case-insensitively if the pattern is all lowercase, otherwise, searches case-sensitively"),
			default: false
595 596
		},
		'search.globalFindClipboard': {
597 598
			type: 'boolean',
			default: false,
B
Benjamin Pasero 已提交
599
			description: nls.localize('search.globalFindClipboard', "Controls if the search view should read or modify the shared find clipboard on macOS"),
600 601 602
			included: platform.isMacintosh
		},
		'search.location': {
603
			type: 'string',
604 605
			enum: ['sidebar', 'panel'],
			default: 'sidebar',
606
			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. Next release search in panel will have improved horizontal layout and this will no longer be a preview."),
607
		}
E
Erich Gamma 已提交
608
	}
J
Johannes Rieken 已提交
609
});
610

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