提交 bdbf134d 编写于 作者: S Sandeep Somavarapu

Fix #12645

上级 eb45d355
......@@ -83,6 +83,9 @@ export class FindInput extends Widget {
private _onCaseSensitiveKeyDown = this._register(new Emitter<IKeyboardEvent>());
public readonly onCaseSensitiveKeyDown: Event<IKeyboardEvent> = this._onCaseSensitiveKeyDown.event;
private _onRegexKeyDown = this._register(new Emitter<IKeyboardEvent>());
public readonly onRegexKeyDown: Event<IKeyboardEvent> = this._onRegexKeyDown.event;
constructor(parent: HTMLElement, contextViewProvider: IContextViewProvider, options?: IFindInputOptions) {
super();
this.contextViewProvider = contextViewProvider;
......@@ -248,6 +251,10 @@ export class FindInput extends Widget {
this.caseSensitive.focus();
}
public focusOnRegex(): void {
this.regex.focus();
}
private _lastHighlightFindOptions: number = 0;
public highlightFindOptions(): void {
dom.removeClass(this.domNode, 'highlight-' + (this._lastHighlightFindOptions));
......@@ -294,6 +301,9 @@ export class FindInput extends Widget {
this.setInputWidth();
this.validate();
},
onKeyDown: (e) => {
this._onRegexKeyDown.fire(e);
},
inputActiveOptionBorder: this.inputActiveOptionBorder
}));
this.wholeWords = this._register(new WholeWordsCheckbox({
......
......@@ -5,7 +5,7 @@
'use strict';
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { KeyCode } from 'vs/base/common/keyCodes';
import { ContextKeyDefinedExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { HistoryInputBoxContext } from 'vs/platform/widget/browser/input';
import { HistoryInputBox } from 'vs/base/browser/ui/inputbox/inputbox';
......@@ -14,7 +14,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'input.action.historyPrevious',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: new ContextKeyDefinedExpr(HistoryInputBoxContext),
primary: KeyMod.Alt | KeyCode.UpArrow,
primary: KeyCode.UpArrow,
handler: (accessor, arg2) => {
const historyInputBox: HistoryInputBox = accessor.get(IContextKeyService).getContext(document.activeElement).getValue(HistoryInputBoxContext);
historyInputBox.showPreviousValue();
......@@ -25,7 +25,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
id: 'input.action.historyNext',
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: new ContextKeyDefinedExpr(HistoryInputBoxContext),
primary: KeyMod.Alt | KeyCode.DownArrow,
primary: KeyCode.DownArrow,
handler: (accessor, arg2) => {
const historyInputBox: HistoryInputBox = accessor.get(IContextKeyService).getContext(document.activeElement).getValue(HistoryInputBoxContext);
historyInputBox.showNextValue();
......
......@@ -251,42 +251,6 @@ export class ShowPreviousReplaceTermAction extends Action {
}
}
export class FocusNextInputAction extends Action {
public static readonly ID = 'search.focus.nextInputBox';
constructor(id: string, label: string,
@IViewletService private viewletService: IViewletService,
@IPanelService private panelService: IPanelService
) {
super(id, label);
}
public run(): TPromise<any> {
const searchView = getSearchView(this.viewletService, this.panelService);
searchView.focusNextInputBox();
return TPromise.as(null);
}
}
export class FocusPreviousInputAction extends Action {
public static readonly ID = 'search.focus.previousInputBox';
constructor(id: string, label: string,
@IViewletService private viewletService: IViewletService,
@IPanelService private panelService: IPanelService
) {
super(id, label);
}
public run(): TPromise<any> {
const searchView = getSearchView(this.viewletService, this.panelService);
searchView.focusPreviousInputBox();
return TPromise.as(null);
}
}
export const FocusActiveEditorCommand = (accessor: ServicesAccessor) => {
const editorService = accessor.get(IEditorService);
const activeControl = editorService.activeControl;
......
......@@ -15,7 +15,7 @@ import { IAction } from 'vs/base/common/actions';
import { Delayer } from 'vs/base/common/async';
import * as errors from 'vs/base/common/errors';
import { debounceEvent, Emitter } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import * as paths from 'vs/base/common/paths';
import * as env from 'vs/base/common/platform';
import * as strings from 'vs/base/common/strings';
......@@ -98,6 +98,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
private searchWidget: SearchWidget;
private size: dom.Dimension;
private queryDetails: HTMLElement;
private toggleQueryDetailsButton: HTMLElement;
private inputPatternExcludes: ExcludePatternInputWidget;
private inputPatternIncludes: PatternInputWidget;
private results: Builder;
......@@ -222,7 +223,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
}
this.queryDetails = this.searchWidgetsContainer.div({ 'class': ['query-details'] }, (builder) => {
builder.div({ 'class': 'more', 'tabindex': 0, 'role': 'button', 'title': nls.localize('moreSearch', "Toggle Search Details") })
this.toggleQueryDetailsButton = builder.div({ 'class': 'more', 'tabindex': 0, 'role': 'button', 'title': nls.localize('moreSearch', "Toggle Search Details") })
.on(dom.EventType.CLICK, (e) => {
dom.EventHelper.stop(e);
this.toggleQueryDetails();
......@@ -233,7 +234,18 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
dom.EventHelper.stop(e);
this.toggleQueryDetails(false);
}
});
}).on(dom.EventType.KEY_DOWN, (e: KeyboardEvent) => {
let event = new StandardKeyboardEvent(e);
if (event.equals(KeyMod.Shift | KeyCode.Tab)) {
if (this.searchWidget.isReplaceActive()) {
this.searchWidget.focusReplaceAllAction();
} else {
this.searchWidget.focusRegexAction();
}
dom.EventHelper.stop(e);
}
}).getHTMLElement();
//folder includes list
builder.div({ 'class': 'file-types includes' }, (builder) => {
......@@ -360,6 +372,10 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
this.delayedRefresh.trigger(() => this.tree.refresh());
}));
this.toUnbind.push(this.searchWidget.onBlur(() => {
this.toggleQueryDetailsButton.focus();
}));
this.toUnbind.push(this.searchWidget.onReplaceAll(() => this.replaceAll()));
this.trackInputBox(this.searchWidget.searchInputFocusTracker);
this.trackInputBox(this.searchWidget.replaceInputFocusTracker);
......
......@@ -116,20 +116,23 @@ export class SearchWidget extends Widget {
private _onReplaceAll = this._register(new Emitter<void>());
public readonly onReplaceAll: Event<void> = this._onReplaceAll.event;
private _onBlur = this._register(new Emitter<void>());
public readonly onBlur: Event<void> = this._onBlur.event;
constructor(
container: Builder,
options: ISearchWidgetOptions,
@IContextViewService private contextViewService: IContextViewService,
@IThemeService private themeService: IThemeService,
@IContextKeyService private keyBindingService: IContextKeyService,
@IKeybindingService private keyBindingService2: IKeybindingService,
@IContextKeyService private contextKeyService: IContextKeyService,
@IKeybindingService private keyBindingService: IKeybindingService,
@IClipboardService private clipboardServce: IClipboardService,
@IConfigurationService private configurationService: IConfigurationService
) {
super();
this.replaceActive = Constants.ReplaceActiveKey.bindTo(this.keyBindingService);
this.searchInputBoxFocused = Constants.SearchInputBoxFocusedKey.bindTo(this.keyBindingService);
this.replaceInputBoxFocused = Constants.ReplaceInputBoxFocusedKey.bindTo(this.keyBindingService);
this.replaceActive = Constants.ReplaceActiveKey.bindTo(this.contextKeyService);
this.searchInputBoxFocused = Constants.SearchInputBoxFocusedKey.bindTo(this.contextKeyService);
this.replaceInputBoxFocused = Constants.ReplaceInputBoxFocusedKey.bindTo(this.contextKeyService);
this.render(container, options);
}
......@@ -164,6 +167,10 @@ export class SearchWidget extends Widget {
return !dom.hasClass(this.replaceContainer, 'disabled');
}
isReplaceActive(): boolean {
return this.replaceActive.get();
}
public getReplaceValue(): string {
return this.replaceInput.value;
}
......@@ -210,6 +217,14 @@ export class SearchWidget extends Widget {
return this.replaceInput.hasFocus();
}
public focusReplaceAllAction(): void {
this.replaceActionBar.focus(true);
}
public focusRegexAction(): void {
this.searchInput.focusOnRegex();
}
private render(container: Builder, options: ISearchWidgetOptions): void {
this.domNode = container.div({ 'class': 'search-widget' }).style({ position: 'relative' }).getHTMLElement();
this.renderToggleReplaceButton(this.domNode);
......@@ -237,16 +252,16 @@ export class SearchWidget extends Widget {
label: nls.localize('label.Search', 'Search: Type Search Term and press Enter to search or Escape to cancel'),
validation: (value: string) => this.validateSearchInput(value),
placeholder: nls.localize('search.placeHolder', "Search"),
appendCaseSensitiveLabel: appendKeyBindingLabel('', this.keyBindingService2.lookupKeybinding(Constants.ToggleCaseSensitiveCommandId), this.keyBindingService2),
appendWholeWordsLabel: appendKeyBindingLabel('', this.keyBindingService2.lookupKeybinding(Constants.ToggleWholeWordCommandId), this.keyBindingService2),
appendRegexLabel: appendKeyBindingLabel('', this.keyBindingService2.lookupKeybinding(Constants.ToggleRegexCommandId), this.keyBindingService2),
appendCaseSensitiveLabel: appendKeyBindingLabel('', this.keyBindingService.lookupKeybinding(Constants.ToggleCaseSensitiveCommandId), this.keyBindingService),
appendWholeWordsLabel: appendKeyBindingLabel('', this.keyBindingService.lookupKeybinding(Constants.ToggleWholeWordCommandId), this.keyBindingService),
appendRegexLabel: appendKeyBindingLabel('', this.keyBindingService.lookupKeybinding(Constants.ToggleRegexCommandId), this.keyBindingService),
history: options.searchHistory
};
let searchInputContainer = dom.append(parent, dom.$('.search-container.input-box'));
this.searchInput = this._register(new ContextScopedFindInput(searchInputContainer, this.contextViewService, inputOptions, this.keyBindingService));
this.searchInput = this._register(new ContextScopedFindInput(searchInputContainer, this.contextViewService, inputOptions, this.contextKeyService));
this._register(attachFindInputBoxStyler(this.searchInput, this.themeService));
this.searchInput.onKeyUp((keyboardEvent: IKeyboardEvent) => this.onSearchInputKeyUp(keyboardEvent));
this.searchInput.onKeyDown((keyboardEvent: IKeyboardEvent) => this.onSearchInputKeyDown(keyboardEvent));
this.searchInput.setValue(options.value || '');
this.searchInput.setRegex(!!options.isRegex);
this.searchInput.setCaseSensitive(!!options.isCaseSensitive);
......@@ -254,6 +269,8 @@ export class SearchWidget extends Widget {
this._register(this.onSearchSubmit(() => {
this.searchInput.inputBox.addToHistory(this.searchInput.getValue());
}));
this.searchInput.onCaseSensitiveKeyDown((keyboardEvent: IKeyboardEvent) => this.onCaseSensitiveKeyDown(keyboardEvent));
this.searchInput.onRegexKeyDown((keyboardEvent: IKeyboardEvent) => this.onRegexKeyDown(keyboardEvent));
this._register(this.onReplaceValueChanged(() => {
this.replaceInput.addToHistory(this.replaceInput.value);
......@@ -287,9 +304,9 @@ export class SearchWidget extends Widget {
ariaLabel: nls.localize('label.Replace', 'Replace: Type replace term and press Enter to preview or Escape to cancel'),
placeholder: nls.localize('search.replace.placeHolder', "Replace"),
history: options.replaceHistory || []
}, this.keyBindingService));
}, this.contextKeyService));
this._register(attachInputBoxStyler(this.replaceInput, this.themeService));
this.onkeyup(this.replaceInput.inputElement, (keyboardEvent) => this.onReplaceInputKeyUp(keyboardEvent));
this.onkeydown(this.replaceInput.inputElement, (keyboardEvent) => this.onReplaceInputKeyDown(keyboardEvent));
this.replaceInput.onDidChange(() => this._onReplaceValueChanged.fire());
this.searchInput.inputBox.onDidChange(() => this.onSearchInputChanged());
......@@ -320,15 +337,11 @@ export class SearchWidget extends Widget {
public setReplaceAllActionState(enabled: boolean): void {
if (this.replaceAllAction.enabled !== enabled) {
this.replaceAllAction.enabled = enabled;
this.replaceAllAction.label = enabled ? SearchWidget.REPLACE_ALL_ENABLED_LABEL(this.keyBindingService2) : SearchWidget.REPLACE_ALL_DISABLED_LABEL;
this.replaceAllAction.label = enabled ? SearchWidget.REPLACE_ALL_ENABLED_LABEL(this.keyBindingService) : SearchWidget.REPLACE_ALL_DISABLED_LABEL;
this.updateReplaceActiveState();
}
}
private isReplaceActive(): boolean {
return this.replaceActive.get();
}
private updateReplaceActiveState(): void {
let currentState = this.isReplaceActive();
let newState = this.isReplaceShown() && this.replaceAllAction.enabled;
......@@ -366,26 +379,61 @@ export class SearchWidget extends Widget {
this.setReplaceAllActionState(false);
}
private onSearchInputKeyUp(keyboardEvent: IKeyboardEvent) {
switch (keyboardEvent.keyCode) {
case KeyCode.Enter:
this.submitSearch();
return;
case KeyCode.Escape:
this._onSearchCancel.fire();
return;
default:
return;
private onSearchInputKeyDown(keyboardEvent: IKeyboardEvent) {
if (keyboardEvent.equals(KeyCode.Enter)) {
this.submitSearch();
keyboardEvent.preventDefault();
}
else if (keyboardEvent.equals(KeyCode.Escape)) {
this._onSearchCancel.fire();
keyboardEvent.preventDefault();
}
else if (keyboardEvent.equals(KeyCode.Tab)) {
if (this.isReplaceShown()) {
this.replaceInput.focus();
} else {
this.searchInput.focusOnCaseSensitive();
}
keyboardEvent.preventDefault();
}
}
private onCaseSensitiveKeyDown(keyboardEvent: IKeyboardEvent) {
if (keyboardEvent.equals(KeyMod.Shift | KeyCode.Tab)) {
if (this.isReplaceShown()) {
this.replaceInput.focus();
keyboardEvent.preventDefault();
}
}
}
private onRegexKeyDown(keyboardEvent: IKeyboardEvent) {
if (keyboardEvent.equals(KeyCode.Tab)) {
if (this.isReplaceActive()) {
this.focusReplaceAllAction();
} else {
this._onBlur.fire();
}
keyboardEvent.preventDefault();
}
}
private onReplaceInputKeyUp(keyboardEvent: IKeyboardEvent) {
switch (keyboardEvent.keyCode) {
case KeyCode.Enter:
this.submitSearch();
return;
default:
return;
private onReplaceInputKeyDown(keyboardEvent: IKeyboardEvent) {
if (keyboardEvent.equals(KeyCode.Enter)) {
this.submitSearch();
keyboardEvent.preventDefault();
}
else if (keyboardEvent.equals(KeyCode.Tab)) {
this.searchInput.focusOnCaseSensitive();
keyboardEvent.preventDefault();
}
else if (keyboardEvent.equals(KeyMod.Shift | KeyCode.Tab)) {
this.searchInput.focus();
keyboardEvent.preventDefault();
}
}
......
......@@ -52,7 +52,7 @@ import { getMultiSelectedResources } from 'vs/workbench/parts/files/browser/file
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, copyPathCommand, copyMatchCommand, copyAllCommand, ShowNextSearchExcludeAction, ShowPreviousSearchExcludeAction, clearHistoryCommand, ShowNextReplaceTermAction, ShowPreviousReplaceTermAction } from 'vs/workbench/parts/search/browser/searchActions';
import { openSearchView, getSearchView, ReplaceAllInFolderAction, ReplaceAllAction, CloseReplaceAction, 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';
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';
......@@ -179,26 +179,6 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: FocusNextInputAction.ID,
weight: KeybindingsRegistry.WEIGHT.workbenchContrib(),
when: ContextKeyExpr.and(Constants.SearchViewVisibleKey, Constants.InputBoxFocusedKey),
primary: KeyCode.DownArrow,
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()),
primary: KeyCode.UpArrow,
handler: (accessor, args: any) => {
accessor.get(IInstantiationService).createInstance(FocusPreviousInputAction, FocusPreviousInputAction.ID, '').run();
}
});
MenuRegistry.appendMenuItem(MenuId.SearchContext, {
command: {
id: Constants.ReplaceActionId,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册