未验证 提交 0684f8e3 编写于 作者: R Rob Lourens 提交者: GitHub

Merge pull request #46311 from Microsoft/roblou/searchContextMenu

Add context menu to search tree
......@@ -59,6 +59,7 @@ export class MenuId {
static readonly ViewTitle = new MenuId();
static readonly ViewItemContext = new MenuId();
static readonly TouchBarContext = new MenuId();
static readonly SearchContext = new MenuId();
readonly id: string = String(MenuId.ID++);
}
......
......@@ -474,8 +474,10 @@ export abstract class AbstractSearchAndReplaceAction extends Action {
export class RemoveAction extends AbstractSearchAndReplaceAction {
public static LABEL = nls.localize('RemoveAction.label', "Dismiss");
constructor(private viewer: ITree, private element: RenderableMatch) {
super('remove', nls.localize('RemoveAction.label', "Dismiss"), 'action-remove');
super('remove', RemoveAction.LABEL, 'action-remove');
}
public run(): TPromise<any> {
......@@ -508,9 +510,11 @@ export class RemoveAction extends AbstractSearchAndReplaceAction {
export class ReplaceAllAction extends AbstractSearchAndReplaceAction {
public static readonly LABEL = nls.localize('file.replaceAll.label', "Replace All");
constructor(private viewer: ITree, private fileMatch: FileMatch, private viewlet: SearchView,
@IKeybindingService keyBindingService: IKeybindingService) {
super(Constants.ReplaceAllInFileActionId, appendKeyBindingLabel(nls.localize('file.replaceAll.label', "Replace All"), keyBindingService.lookupKeybinding(Constants.ReplaceAllInFileActionId), keyBindingService), 'action-replace-all');
super(Constants.ReplaceAllInFileActionId, appendKeyBindingLabel(ReplaceAllAction.LABEL, keyBindingService.lookupKeybinding(Constants.ReplaceAllInFileActionId), keyBindingService), 'action-replace-all');
}
public run(): TPromise<any> {
......@@ -527,10 +531,12 @@ export class ReplaceAllAction extends AbstractSearchAndReplaceAction {
export class ReplaceAllInFolderAction extends AbstractSearchAndReplaceAction {
public static readonly LABEL = nls.localize('file.replaceAll.label', "Replace All");
constructor(private viewer: ITree, private folderMatch: FolderMatch,
@IKeybindingService keyBindingService: IKeybindingService
) {
super(Constants.ReplaceAllInFolderActionId, appendKeyBindingLabel(nls.localize('file.replaceAll.label', "Replace All"), keyBindingService.lookupKeybinding(Constants.ReplaceAllInFolderActionId), keyBindingService), 'action-replace-all');
super(Constants.ReplaceAllInFolderActionId, appendKeyBindingLabel(ReplaceAllInFolderAction.LABEL, keyBindingService.lookupKeybinding(Constants.ReplaceAllInFolderActionId), keyBindingService), 'action-replace-all');
}
public async run(): TPromise<any> {
......@@ -546,11 +552,13 @@ export class ReplaceAllInFolderAction extends AbstractSearchAndReplaceAction {
export class ReplaceAction extends AbstractSearchAndReplaceAction {
public static readonly LABEL = nls.localize('match.replace.label', "Replace");
constructor(private viewer: ITree, private element: Match, private viewlet: SearchView,
@IReplaceService private replaceService: IReplaceService,
@IKeybindingService keyBindingService: IKeybindingService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService) {
super(Constants.ReplaceActionId, appendKeyBindingLabel(nls.localize('match.replace.label', "Replace"), keyBindingService.lookupKeybinding(Constants.ReplaceActionId), keyBindingService), 'action-replace');
super(Constants.ReplaceActionId, appendKeyBindingLabel(ReplaceAction.LABEL, keyBindingService.lookupKeybinding(Constants.ReplaceActionId), keyBindingService), 'action-replace');
}
public run(): TPromise<any> {
......
......@@ -12,7 +12,7 @@ import { IAction, IActionRunner } from 'vs/base/common/actions';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
import { FileLabel } from 'vs/workbench/browser/labels';
import { ITree, IDataSource, ISorter, IAccessibilityProvider, IFilter, IRenderer } from 'vs/base/parts/tree/browser/tree';
import { ITree, IDataSource, ISorter, IAccessibilityProvider, IFilter, IRenderer, ContextMenuEvent } from 'vs/base/parts/tree/browser/tree';
import { Match, SearchResult, FileMatch, FileMatchOrMatch, SearchModel, FolderMatch } from 'vs/workbench/parts/search/common/searchModel';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { Range } from 'vs/editor/common/core/range';
......@@ -23,6 +23,11 @@ import { attachBadgeStyler } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { getPathLabel } from 'vs/base/common/labels';
import { FileKind } from 'vs/platform/files/common/files';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions';
import { WorkbenchTreeController, WorkbenchTree } from 'vs/platform/list/browser/listService';
import { fillInActions } from 'vs/platform/actions/browser/menuItemActionItem';
export class SearchDataSource implements IDataSource {
......@@ -354,3 +359,37 @@ export class SearchFilter implements IFilter {
return !(element instanceof FileMatch || element instanceof FolderMatch) || element.matches().length > 0;
}
}
export class SearchTreeController extends WorkbenchTreeController {
private contextMenu: IMenu;
constructor(
@IContextMenuService private contextMenuService: IContextMenuService,
@IMenuService private menuService: IMenuService,
@IConfigurationService configurationService: IConfigurationService
) {
super({}, configurationService);
}
public onContextMenu(tree: WorkbenchTree, element: any, event: ContextMenuEvent): boolean {
if (!this.contextMenu) {
this.contextMenu = this.menuService.createMenu(MenuId.SearchContext, tree.contextKeyService);
}
tree.setFocus(element);
const anchor = { x: event.posx, y: event.posy };
this.contextMenuService.showContextMenu({
getAnchor: () => anchor,
getActions: () => {
const actions: IAction[] = [];
fillInActions(this.contextMenu, { shouldForwardArgs: true }, actions, this.contextMenuService);
return TPromise.as(actions);
},
// getActionsContext: () => element instanceof OpenEditor ? { groupId: element.group.id, editorIndex: element.editorIndex } : { groupId: element.id }
});
return true;
}
}
......@@ -41,7 +41,7 @@ import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/c
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { KeyCode } from 'vs/base/common/keyCodes';
import { PatternInputWidget, ExcludePatternInputWidget } from 'vs/workbench/parts/search/browser/patternInputWidget';
import { SearchRenderer, SearchDataSource, SearchSorter, SearchAccessibilityProvider, SearchFilter } from 'vs/workbench/parts/search/browser/searchResultsView';
import { SearchRenderer, SearchDataSource, SearchSorter, SearchAccessibilityProvider, SearchFilter, SearchTreeController } from 'vs/workbench/parts/search/browser/searchResultsView';
import { SearchWidget, ISearchWidgetOptions } from 'vs/workbench/parts/search/browser/searchWidget';
import { RefreshAction, CollapseDeepestExpandedLevelAction, ClearSearchResultsAction, CancelSearchAction } from 'vs/workbench/parts/search/browser/searchActions';
import { IReplaceService } from 'vs/workbench/parts/search/common/replace';
......@@ -83,6 +83,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
private folderMatchFocused: IContextKey<boolean>;
private matchFocused: IContextKey<boolean>;
private hasSearchResultsKey: IContextKey<boolean>;
private searchSubmitted: boolean;
private searching: boolean;
......@@ -493,6 +494,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
renderer: renderer,
sorter: new SearchSorter(),
filter: new SearchFilter(),
controller: this.instantiationService.createInstance(SearchTreeController),
accessibilityProvider: this.instantiationService.createInstance(SearchAccessibilityProvider),
dnd
}, {
......@@ -526,7 +528,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
if (treeHasFocus) {
const focus = e.focus;
this.firstMatchFocused.set(this.tree.getNavigator().first() === focus);
this.fileMatchOrMatchFocused.set(true);
this.fileMatchOrMatchFocused.set(!!focus);
this.fileMatchFocused.set(focus instanceof FileMatch);
this.folderMatchFocused.set(focus instanceof FolderMatch);
this.matchFocused.set(focus instanceof Match);
......
......@@ -20,6 +20,8 @@ export const ToggleCaseSensitiveCommandId = 'toggleSearchCaseSensitive';
export const ToggleWholeWordCommandId = 'toggleSearchWholeWord';
export const ToggleRegexCommandId = 'toggleSearchRegex';
export const ToggleSearchViewPositionCommandId = 'search.action.toggleSearchViewPosition';
export const SearchViewVisibleKey = new RawContextKey<boolean>('searchViewletVisible', true);
export const InputBoxFocusedKey = new RawContextKey<boolean>('inputBoxFocus', false);
export const SearchInputBoxFocusedKey = new RawContextKey<boolean>('searchInputBoxFocus', false);
......
......@@ -54,10 +54,11 @@ import { Schemas } from 'vs/base/common/network';
import { PanelRegistry, Extensions as PanelExtensions, PanelDescriptor } from 'vs/workbench/browser/panel';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { openSearchView, getSearchView, ReplaceAllInFolderAction, ReplaceAllAction, CloseReplaceAction, FocusNextInputAction, FocusPreviousInputAction, FocusNextSearchResultAction, FocusPreviousSearchResultAction, ReplaceInFilesAction, FindInFilesAction, FocusActiveEditorCommand, toggleCaseSensitiveCommand, ShowNextSearchTermAction, ShowPreviousSearchTermAction, toggleRegexCommand, ShowPreviousSearchIncludeAction, ShowNextSearchIncludeAction, CollapseDeepestExpandedLevelAction, toggleWholeWordCommand, RemoveAction, ReplaceAction, ClearSearchResultsAction } from 'vs/workbench/parts/search/browser/searchActions';
import { VIEW_ID } from 'vs/platform/search/common/search';
import { VIEW_ID, ISearchConfigurationProperties } from 'vs/platform/search/common/search';
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';
import { IConfigurationService } from '../../../../platform/configuration/common/configuration';
registerSingleton(ISearchWorkbenchService, SearchWorkbenchService);
replaceContributions();
......@@ -193,6 +194,68 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
}
});
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
});
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");
MenuRegistry.appendMenuItem(MenuId.SearchContext, {
command: {
id: Constants.ToggleSearchViewPositionCommandId,
title: toggleSearchViewPositionLabel
},
when: Constants.SearchViewVisibleKey,
group: 'search',
order: 3
});
const FIND_IN_FOLDER_ID = 'filesExplorer.findInFolder';
CommandsRegistry.registerCommand({
id: FIND_IN_FOLDER_ID,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册