diff --git a/src/vs/base/browser/ui/findinput/replaceInput.ts b/src/vs/base/browser/ui/findinput/replaceInput.ts index cdf5d65798d..901049b8134 100644 --- a/src/vs/base/browser/ui/findinput/replaceInput.ts +++ b/src/vs/base/browser/ui/findinput/replaceInput.ts @@ -28,6 +28,7 @@ export interface IReplaceInputOptions extends IReplaceInputStyles { readonly flexibleWidth?: boolean; readonly flexibleMaxHeight?: number; + readonly appendPreserveCaseLabel?: string; readonly history?: string[]; } @@ -128,6 +129,7 @@ export class ReplaceInput extends Widget { this.inputValidationErrorBackground = options.inputValidationErrorBackground; this.inputValidationErrorForeground = options.inputValidationErrorForeground; + const appendPreserveCaseLabel = options.appendPreserveCaseLabel || ''; const history = options.history || []; const flexibleHeight = !!options.flexibleHeight; const flexibleWidth = !!options.flexibleWidth; @@ -161,7 +163,7 @@ export class ReplaceInput extends Widget { })); this.preserveCase = this._register(new PreserveCaseCheckbox({ - appendTitle: '', + appendTitle: appendPreserveCaseLabel, isChecked: false, inputActiveOptionBorder: this.inputActiveOptionBorder, inputActiveOptionForeground: this.inputActiveOptionForeground, diff --git a/src/vs/editor/contrib/find/findController.ts b/src/vs/editor/contrib/find/findController.ts index 7e452f6a6cd..80ae3f7644e 100644 --- a/src/vs/editor/contrib/find/findController.ts +++ b/src/vs/editor/contrib/find/findController.ts @@ -12,7 +12,7 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, EditorCommand, ServicesAccessor, registerEditorAction, registerEditorCommand, registerEditorContribution, MultiEditorAction, registerMultiEditorAction } from 'vs/editor/browser/editorExtensions'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; -import { CONTEXT_FIND_INPUT_FOCUSED, CONTEXT_FIND_WIDGET_VISIBLE, FIND_IDS, FindModelBoundToEditorModel, ToggleCaseSensitiveKeybinding, ToggleRegexKeybinding, ToggleSearchScopeKeybinding, ToggleWholeWordKeybinding, CONTEXT_REPLACE_INPUT_FOCUSED } from 'vs/editor/contrib/find/findModel'; +import { CONTEXT_FIND_INPUT_FOCUSED, CONTEXT_FIND_WIDGET_VISIBLE, FIND_IDS, FindModelBoundToEditorModel, ToggleCaseSensitiveKeybinding, TogglePreserveCaseKeybinding, ToggleRegexKeybinding, ToggleSearchScopeKeybinding, ToggleWholeWordKeybinding, CONTEXT_REPLACE_INPUT_FOCUSED } from 'vs/editor/contrib/find/findModel'; import { FindOptionsWidget } from 'vs/editor/contrib/find/findOptionsWidget'; import { FindReplaceState, FindReplaceStateChangedEvent, INewFindReplaceState } from 'vs/editor/contrib/find/findState'; import { FindWidget, IFindController } from 'vs/editor/contrib/find/findWidget'; @@ -224,7 +224,9 @@ export class CommonFindController extends Disposable implements IEditorContribut public togglePreserveCase(): void { this._state.change({ preserveCase: !this._state.preserveCase }, false); - this.highlightFindOptions(); + if (!this._state.isRevealed) { + this.highlightFindOptions(); + } } public toggleSearchScope(): void { @@ -858,6 +860,20 @@ registerEditorCommand(new FindCommand({ } })); +registerEditorCommand(new FindCommand({ + id: FIND_IDS.TogglePreserveCaseCommand, + precondition: undefined, + handler: x => x.togglePreserveCase(), + kbOpts: { + weight: KeybindingWeight.EditorContrib + 5, + kbExpr: EditorContextKeys.focus, + primary: TogglePreserveCaseKeybinding.primary, + mac: TogglePreserveCaseKeybinding.mac, + win: TogglePreserveCaseKeybinding.win, + linux: TogglePreserveCaseKeybinding.linux + } +})); + registerEditorCommand(new FindCommand({ id: FIND_IDS.ReplaceOneAction, precondition: CONTEXT_FIND_WIDGET_VISIBLE, diff --git a/src/vs/editor/contrib/find/findModel.ts b/src/vs/editor/contrib/find/findModel.ts index a902f36c6d0..11ec1c63505 100644 --- a/src/vs/editor/contrib/find/findModel.ts +++ b/src/vs/editor/contrib/find/findModel.ts @@ -47,6 +47,10 @@ export const ToggleSearchScopeKeybinding: IKeybindings = { primary: KeyMod.Alt | KeyCode.KEY_L, mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_L } }; +export const TogglePreserveCaseKeybinding: IKeybindings = { + primary: KeyMod.Alt | KeyCode.KEY_P, + mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_P } +}; export const FIND_IDS = { StartFindAction: 'actions.find', diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index 71864ba97f7..21fbb0060e0 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -353,6 +353,9 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL if (e.matchCase) { this._findInput.setCaseSensitive(this._state.matchCase); } + if (e.preserveCase) { + this._replaceInput.setPreserveCase(this._state.preserveCase); + } if (e.searchScope) { if (this._state.searchScope) { this._toggleSelectionFind.checked = true; @@ -1087,6 +1090,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL this._replaceInput = this._register(new ContextScopedReplaceInput(null, undefined, { label: NLS_REPLACE_INPUT_LABEL, placeholder: NLS_REPLACE_INPUT_PLACEHOLDER, + appendPreserveCaseLabel: this._keybindingLabelFor(FIND_IDS.TogglePreserveCaseCommand), history: [], flexibleHeight, flexibleWidth, diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindReplaceWidget.ts b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindReplaceWidget.ts index ad05b40ac5b..9b8cf7a37b9 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindReplaceWidget.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindReplaceWidget.ts @@ -140,6 +140,7 @@ export abstract class SimpleFindReplaceWidget extends Widget { this._findInput.setRegex(this._state.isRegex); this._findInput.setWholeWords(this._state.wholeWord); this._findInput.setCaseSensitive(this._state.matchCase); + this._replaceInput.setPreserveCase(this._state.preserveCase); this.findFirst(); })); diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index 70b5e881f3e..c0b8a580b54 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -10,7 +10,7 @@ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import * as platform from 'vs/base/common/platform'; import { dirname } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; -import { ToggleCaseSensitiveKeybinding, ToggleRegexKeybinding, ToggleWholeWordKeybinding } from 'vs/editor/contrib/find/findModel'; +import { ToggleCaseSensitiveKeybinding, TogglePreserveCaseKeybinding, ToggleRegexKeybinding, ToggleWholeWordKeybinding } from 'vs/editor/contrib/find/findModel'; import * as nls from 'vs/nls'; import { ICommandAction, MenuId, MenuRegistry, SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { CommandsRegistry, ICommandHandler } from 'vs/platform/commands/common/commands'; @@ -31,7 +31,7 @@ import { Extensions as ViewExtensions, IViewsRegistry, IViewContainersRegistry, import { getMultiSelectedResources } from 'vs/workbench/contrib/files/browser/files'; import { ExplorerFolderContext, ExplorerRootContext, FilesExplorerFocusCondition, IExplorerService, VIEWLET_ID as VIEWLET_ID_FILES } from 'vs/workbench/contrib/files/common/files'; import { registerContributions as replaceContributions } from 'vs/workbench/contrib/search/browser/replaceContributions'; -import { clearHistoryCommand, ClearSearchResultsAction, CloseReplaceAction, CollapseDeepestExpandedLevelAction, copyAllCommand, copyMatchCommand, copyPathCommand, FocusNextInputAction, FocusNextSearchResultAction, FocusPreviousInputAction, FocusPreviousSearchResultAction, focusSearchListCommand, getSearchView, openSearchView, OpenSearchViewletAction, RefreshAction, RemoveAction, ReplaceAction, ReplaceAllAction, ReplaceAllInFolderAction, ReplaceInFilesAction, toggleCaseSensitiveCommand, toggleRegexCommand, toggleWholeWordCommand, FindInFilesCommand, ToggleSearchOnTypeAction, ExpandAllAction } from 'vs/workbench/contrib/search/browser/searchActions'; +import { clearHistoryCommand, ClearSearchResultsAction, CloseReplaceAction, CollapseDeepestExpandedLevelAction, copyAllCommand, copyMatchCommand, copyPathCommand, FocusNextInputAction, FocusNextSearchResultAction, FocusPreviousInputAction, FocusPreviousSearchResultAction, focusSearchListCommand, getSearchView, openSearchView, OpenSearchViewletAction, RefreshAction, RemoveAction, ReplaceAction, ReplaceAllAction, ReplaceAllInFolderAction, ReplaceInFilesAction, toggleCaseSensitiveCommand, togglePreserveCaseCommand, toggleRegexCommand, toggleWholeWordCommand, FindInFilesCommand, ToggleSearchOnTypeAction, ExpandAllAction } from 'vs/workbench/contrib/search/browser/searchActions'; import { SearchView } from 'vs/workbench/contrib/search/browser/searchView'; import { registerContributions as searchWidgetContributions } from 'vs/workbench/contrib/search/browser/searchWidget'; import * as Constants from 'vs/workbench/contrib/search/common/constants'; @@ -642,6 +642,13 @@ KeybindingsRegistry.registerCommandAndKeybindingRule(Object.assign({ handler: toggleRegexCommand }, ToggleRegexKeybinding)); +KeybindingsRegistry.registerCommandAndKeybindingRule(Object.assign({ + id: Constants.TogglePreserveCaseId, + weight: KeybindingWeight.WorkbenchContrib, + when: Constants.SearchViewFocusedKey, + handler: togglePreserveCaseCommand +}, TogglePreserveCaseKeybinding)); + KeybindingsRegistry.registerCommandAndKeybindingRule({ id: Constants.AddCursorsAtSearchResults, weight: KeybindingWeight.WorkbenchContrib, diff --git a/src/vs/workbench/contrib/search/browser/searchActions.ts b/src/vs/workbench/contrib/search/browser/searchActions.ts index 3c7b305bd0f..23c915b19f6 100644 --- a/src/vs/workbench/contrib/search/browser/searchActions.ts +++ b/src/vs/workbench/contrib/search/browser/searchActions.ts @@ -82,6 +82,13 @@ export const toggleRegexCommand = (accessor: ServicesAccessor) => { } }; +export const togglePreserveCaseCommand = (accessor: ServicesAccessor) => { + const searchView = getSearchView(accessor.get(IViewsService)); + if (searchView) { + searchView.togglePreserveCase(); + } +}; + export class FocusNextInputAction extends Action { static readonly ID = 'search.focus.nextInputBox'; diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index 96c89d5f2c2..e123c8bb3af 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -1160,6 +1160,11 @@ export class SearchView extends ViewPane { this.triggerQueryChange(); } + togglePreserveCase(): void { + this.searchWidget.replaceInput.setPreserveCase(!this.searchWidget.replaceInput.getPreserveCase()); + this.triggerQueryChange(); + } + setSearchParameters(args: IFindInFilesArgs = {}): void { if (typeof args.isCaseSensitive === 'boolean') { this.searchWidget.searchInput.setCaseSensitive(args.isCaseSensitive); diff --git a/src/vs/workbench/contrib/search/browser/searchWidget.ts b/src/vs/workbench/contrib/search/browser/searchWidget.ts index 78d6587b423..d633afe199f 100644 --- a/src/vs/workbench/contrib/search/browser/searchWidget.ts +++ b/src/vs/workbench/contrib/search/browser/searchWidget.ts @@ -393,6 +393,7 @@ export class SearchWidget extends Widget { this.replaceInput = this._register(new ContextScopedReplaceInput(replaceBox, this.contextViewService, { label: nls.localize('label.Replace', 'Replace: Type replace term and press Enter to preview or Escape to cancel'), placeholder: nls.localize('search.replace.placeHolder', "Replace"), + appendPreserveCaseLabel: appendKeyBindingLabel('', this.keyBindingService.lookupKeybinding(Constants.TogglePreserveCaseId), this.keyBindingService), history: options.replaceHistory, flexibleHeight: true, flexibleMaxHeight: SearchWidget.INPUT_MAX_HEIGHT diff --git a/src/vs/workbench/contrib/search/common/constants.ts b/src/vs/workbench/contrib/search/common/constants.ts index f1e6975f788..38e04a3de24 100644 --- a/src/vs/workbench/contrib/search/common/constants.ts +++ b/src/vs/workbench/contrib/search/common/constants.ts @@ -26,6 +26,7 @@ export const CloseReplaceWidgetActionId = 'closeReplaceInFilesWidget'; export const ToggleCaseSensitiveCommandId = 'toggleSearchCaseSensitive'; export const ToggleWholeWordCommandId = 'toggleSearchWholeWord'; export const ToggleRegexCommandId = 'toggleSearchRegex'; +export const TogglePreserveCaseId = 'toggleSearchPreserveCase'; export const AddCursorsAtSearchResults = 'addCursorsAtSearchResults'; export const RevealInSideBarForSearchResults = 'search.action.revealInSideBar';