Skip to content

[Draft] Improve % motion by using vscode editor.jumpToBracket #9378

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions src/actions/motion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1798,12 +1798,12 @@ class MoveToMatchingBracket extends BaseMovement {
if (pairing) {
// We found an opening char, now move to the matching closing char
return (
PairMatcher.nextPairedChar(
(await PairMatcher.nextPairedChar(
new Position(position.line, col),
lineText[col],
vimState,
false,
) || failure
)) || failure
);
}
}
Expand Down Expand Up @@ -1885,7 +1885,7 @@ export abstract class MoveInsideCharacter extends ExpandingSelection {
const [selStart, selEnd] = sorted(vimState.cursorStartPosition, position);

// First, search backwards for the opening character of the sequence
let openPos = PairMatcher.nextPairedChar(selStart, closingChar, vimState, true);
let openPos = await PairMatcher.nextPairedChar(selStart, closingChar, vimState, true);
if (openPos === undefined) {
// If opening character not found, search forwards
let lineNum = selStart.line;
Expand All @@ -1905,7 +1905,7 @@ export abstract class MoveInsideCharacter extends ExpandingSelection {
}

// Next, search forwards for the closing character which matches
let closePos = PairMatcher.nextPairedChar(openPos, this.charToMatch, vimState, true);
let closePos = await PairMatcher.nextPairedChar(openPos, this.charToMatch, vimState, true);
if (closePos === undefined) {
return failedMovement(vimState);
}
Expand All @@ -1917,9 +1917,9 @@ export abstract class MoveInsideCharacter extends ExpandingSelection {
selEnd.getRightThroughLineBreaks(false).isAfterOrEqual(closePos)
) {
// Special case: inner, with all inner content already selected
const outerOpenPos = PairMatcher.nextPairedChar(openPos, closingChar, vimState, false);
const outerOpenPos = await PairMatcher.nextPairedChar(openPos, closingChar, vimState, false);
const outerClosePos = outerOpenPos
? PairMatcher.nextPairedChar(outerOpenPos, this.charToMatch, vimState, false)
? await PairMatcher.nextPairedChar(outerOpenPos, this.charToMatch, vimState, false)
: undefined;

if (outerOpenPos && outerClosePos) {
Expand Down Expand Up @@ -2276,7 +2276,7 @@ class MoveToUnclosedRoundBracketBackward extends MoveToMatchingBracket {
vimState: VimState,
): Promise<Position | IMovement> {
const charToMatch = ')';
const result = PairMatcher.nextPairedChar(position, charToMatch, vimState, false);
const result = await PairMatcher.nextPairedChar(position, charToMatch, vimState, false);

if (!result) {
return failedMovement(vimState);
Expand All @@ -2294,7 +2294,7 @@ class MoveToUnclosedRoundBracketForward extends MoveToMatchingBracket {
vimState: VimState,
): Promise<Position | IMovement> {
const charToMatch = '(';
const result = PairMatcher.nextPairedChar(position, charToMatch, vimState, false);
const result = await PairMatcher.nextPairedChar(position, charToMatch, vimState, false);

if (!result) {
return failedMovement(vimState);
Expand All @@ -2321,7 +2321,7 @@ class MoveToUnclosedCurlyBracketBackward extends MoveToMatchingBracket {
vimState: VimState,
): Promise<Position | IMovement> {
const charToMatch = '}';
const result = PairMatcher.nextPairedChar(position, charToMatch, vimState, false);
const result = await PairMatcher.nextPairedChar(position, charToMatch, vimState, false);

if (!result) {
return failedMovement(vimState);
Expand All @@ -2339,7 +2339,7 @@ class MoveToUnclosedCurlyBracketForward extends MoveToMatchingBracket {
vimState: VimState,
): Promise<Position | IMovement> {
const charToMatch = '{';
const result = PairMatcher.nextPairedChar(position, charToMatch, vimState, false);
const result = await PairMatcher.nextPairedChar(position, charToMatch, vimState, false);

if (!result) {
return failedMovement(vimState);
Expand Down
24 changes: 22 additions & 2 deletions src/common/matching/matcher.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as vscode from 'vscode';

import { VimState } from '../../state/vimState';
import { Position } from 'vscode';
import { configuration } from '../../configuration/configuration';
Expand Down Expand Up @@ -135,12 +137,12 @@ export class PairMatcher {
return undefined;
}

static nextPairedChar(
static async nextPairedChar(
position: Position,
charToMatch: string,
vimState: VimState,
allowCurrentPosition: boolean,
): Position | undefined {
): Promise<Position | undefined> {
/**
* We do a fairly basic implementation that only tracks the state of the type of
* character you're over and its pair (e.g. "[" and "]"). This is similar to
Expand All @@ -152,6 +154,24 @@ export class PairMatcher {
* PRs welcomed! (TODO)
* Though ideally VSC implements https://github.com/Microsoft/vscode/issues/7177
*/

// VSCode ctrl+shift+p Go to Bracket
if (charToMatch === '{' || charToMatch === '}') {
// vscode.window.showInformationMessage("try nextpairedchar jumpt to bracket");
const editor = vscode.window.activeTextEditor;
const oldSelection = editor?.selection;
if (oldSelection && oldSelection.isEmpty) {
await vscode.commands.executeCommand('editor.action.jumpToBracket');

// return new cursor position
return editor?.selection.active;
} else {
// If there is a selection, editor.action.jumpToBracket doesn't move and clear the selection
// We need to save the selection anchor and active, move the cursor, and re-apply the correct selection.
// If we try to do it here, vscode cursor and vim cursor are conflicting
}
}

const pairing = this.pairings[charToMatch];

if (pairing === undefined || pairing.directionless) {
Expand Down
8 changes: 4 additions & 4 deletions src/mode/modeHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,7 @@ export class ModeHandler implements vscode.Disposable, IModeHandler {

ranRepeatableAction =
(ranRepeatableAction && this.vimState.currentMode === Mode.Normal) ||
this.createUndoPointForBrackets();
(await this.createUndoPointForBrackets());

// We don't want to record a repeatable action when exiting from these modes
// by pressing <Esc>
Expand Down Expand Up @@ -1748,7 +1748,7 @@ export class ModeHandler implements vscode.Disposable, IModeHandler {
}

// Return true if a new undo point should be created based on brackets and parentheses
private createUndoPointForBrackets(): boolean {
private async createUndoPointForBrackets(): Promise<boolean> {
// }])> keys all start a new undo state when directly next to an {[(< opening character
const key =
this.vimState.recordedState.actionKeys[this.vimState.recordedState.actionKeys.length - 1];
Expand All @@ -1759,7 +1759,7 @@ export class ModeHandler implements vscode.Disposable, IModeHandler {

if (this.vimState.currentMode === Mode.Insert) {
// Check if the keypress is a closing bracket to a corresponding opening bracket right next to it
let result = PairMatcher.nextPairedChar(
let result = await PairMatcher.nextPairedChar(
this.vimState.cursorStopPosition,
key,
this.vimState,
Expand All @@ -1771,7 +1771,7 @@ export class ModeHandler implements vscode.Disposable, IModeHandler {
}
}

result = PairMatcher.nextPairedChar(
result = await PairMatcher.nextPairedChar(
this.vimState.cursorStopPosition.getLeft(),
key,
this.vimState,
Expand Down