"Find" jumps to nth match (#146110)

* MVP jump on index from findWidget

* Improved styling and moved action to Enter key

* Removed unnecessary commented code

* tweak 💄

Co-authored-by: rebornix <penn.lv@gmail.com>
This commit is contained in:
Leonardo Montini 2022-12-15 22:01:11 +01:00 committed by GitHub
parent 99c0000cbd
commit 38811cc9ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 0 deletions

View file

@ -24,6 +24,7 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { IThemeService } from 'vs/platform/theme/common/themeService';
@ -368,6 +369,14 @@ export class CommonFindController extends Disposable implements IEditorContribut
return false;
}
public goToMatch(index: number): boolean {
if (this._model) {
this._model.moveToMatch(index);
return true;
}
return false;
}
public replace(): boolean {
if (this._model) {
this._model.replace();
@ -732,6 +741,55 @@ export class PreviousMatchFindAction extends MatchFindAction {
}
}
export class MoveToMatchFindAction extends EditorAction {
constructor() {
super({
id: FIND_IDS.GoToMatchFindAction,
label: nls.localize('findMatchAction.goToMatch', "Go to Match..."),
alias: 'Go to Match...',
precondition: CONTEXT_FIND_WIDGET_VISIBLE
});
}
public run(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void | Promise<void> {
const controller = CommonFindController.get(editor);
if (!controller) {
return;
}
const quickInputService = accessor.get(IQuickInputService);
const inputBox = quickInputService.createInputBox();
inputBox.placeholder = nls.localize('findMatchAction.inputPlaceHolder', "Type a number to go to a specific match (between 1 and {0})", controller.getState().matchesCount);
inputBox.onDidChangeValue(value => {
const index = parseInt(value);
if (!isNaN(index) && index > 0 && index <= controller.getState().matchesCount) {
// valid
inputBox.validationMessage = undefined;
} else {
inputBox.validationMessage = nls.localize('findMatchAction.inputValidationMessage', "Please type a number between 1 and {0}", controller.getState().matchesCount);
}
});
inputBox.onDidAccept(() => {
const index = parseInt(inputBox.value);
if (!isNaN(index) && index > 0 && index <= controller.getState().matchesCount) {
controller.goToMatch(index - 1);
inputBox.hide();
} else {
inputBox.validationMessage = nls.localize('findMatchAction.inputValidationMessage', "Please type a number between 1 and {0}", controller.getState().matchesCount);
}
});
inputBox.onDidHide(() => {
inputBox.dispose();
});
inputBox.show();
}
}
export abstract class SelectionMatchFindAction extends EditorAction {
public async run(accessor: ServicesAccessor | null, editor: ICodeEditor): Promise<void> {
const controller = CommonFindController.get(editor);
@ -871,6 +929,7 @@ registerEditorAction(StartFindWithArgsAction);
registerEditorAction(StartFindWithSelectionAction);
registerEditorAction(NextMatchFindAction);
registerEditorAction(PreviousMatchFindAction);
registerEditorAction(MoveToMatchFindAction);
registerEditorAction(NextSelectionMatchFindAction);
registerEditorAction(PreviousSelectionMatchFindAction);

View file

@ -91,6 +91,14 @@ export class FindDecorations implements IDisposable {
return 1;
}
public getDecorationRangeAt(index: number): Range | null {
const decorationId = index < this._decorations.length ? this._decorations[index] : null;
if (decorationId) {
return this._editor.getModel().getDecorationRange(decorationId);
}
return null;
}
public getCurrentMatchesPosition(desiredRange: Range): number {
const candidates = this._editor.getModel().getDecorationsInRange(desiredRange);
for (const candidate of candidates) {

View file

@ -58,6 +58,7 @@ export const FIND_IDS = {
StartFindWithArgs: 'editor.actions.findWithArgs',
NextMatchFindAction: 'editor.action.nextMatchFindAction',
PreviousMatchFindAction: 'editor.action.previousMatchFindAction',
GoToMatchFindAction: 'editor.action.goToMatchFindAction',
NextSelectionMatchFindAction: 'editor.action.nextSelectionMatchFindAction',
PreviousSelectionMatchFindAction: 'editor.action.previousSelectionMatchFindAction',
StartFindReplaceAction: 'editor.action.startFindReplaceAction',
@ -449,6 +450,17 @@ export class FindModelBoundToEditorModel {
this._moveToNextMatch(this._editor.getSelection().getEndPosition());
}
private _moveToMatch(index: number): void {
const decorationRange = this._decorations.getDecorationRangeAt(index);
if (decorationRange) {
this._setCurrentFindMatch(decorationRange);
}
}
public moveToMatch(index: number): void {
this._moveToMatch(index);
}
private _getReplacePattern(): ReplacePattern {
if (this._state.isRegex) {
return parseReplaceString(this._state.replaceString);