Skip to content

Commit

Permalink
Implement inside-paren and inside-doublequote movement
Browse files Browse the repository at this point in the history
This allows for e.g. 'ci(' and 'ci"' commands.
  • Loading branch information
ascandella committed Jul 15, 2016
1 parent 5a2bce3 commit 5a50f21
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 6 deletions.
51 changes: 45 additions & 6 deletions src/actions/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2157,10 +2157,8 @@ class MovementIWordTextObject extends BaseMovement {
}
}

@RegisterAction
class MoveToMatchingBracket extends BaseMovement {
abstract class MoveToMatchingBase extends BaseMovement {
modes = [ModeName.Normal, ModeName.Visual, ModeName.VisualLine];
keys = ["%"];

pairings: { [key: string]: { match: string, nextMatchIsForward: boolean }} = {
"(" : { match: ")", nextMatchIsForward: true },
Expand Down Expand Up @@ -2190,11 +2188,11 @@ class MoveToMatchingBracket extends BaseMovement {
let matchedPosition: Position | undefined = undefined;

for (const { char, pos } of Position.IterateDocument(position, toFind.nextMatchIsForward)) {
if (char === charToMatch) {
if (char === charToMatch && charToMatch !== toFind.match) {
stackHeight++;
}

if (char === this.pairings[charToMatch].match) {
if (char === toFind.match) {
stackHeight--;
}

Expand All @@ -2212,6 +2210,11 @@ class MoveToMatchingBracket extends BaseMovement {
// TODO(bell)
return position;
}
}

@RegisterAction
class MoveToMatchingBracket extends MoveToMatchingBase {
keys = ["%"];

public async execAction(position: Position, vimState: VimState): Promise<Position> {
const text = TextEditor.getLineAt(position).text;
Expand All @@ -2233,7 +2236,7 @@ class MoveToMatchingBracket extends BaseMovement {
}

return this.nextBracket(position, charToMatch, toFind, true);
}
}

public async execActionForOperator(position: Position, vimState: VimState): Promise<Position> {
const result = await this.execAction(position, vimState);
Expand All @@ -2246,6 +2249,42 @@ class MoveToMatchingBracket extends BaseMovement {
}
}

abstract class MoveInsideCharacter extends MoveToMatchingBase {
modes = [ModeName.Normal, ModeName.Visual, ModeName.VisualLine];
protected charToMatch: string;

public async execAction(position: Position, vimState: VimState): Promise<Position | IMovement> {
const text = TextEditor.getLineAt(position).text;
const pairedCharacter = this.pairings[this.charToMatch];
const charToClose = pairedCharacter ? pairedCharacter.match : this.charToMatch;

// First, search backwards for the opening character of the sequence
const start = text.lastIndexOf(this.charToMatch, position.character);
const startPos = new Position(position.line, start + 1);
const endPos = this.nextBracket(startPos, this.charToMatch, { match: charToClose, nextMatchIsForward: true }, false);
if (start === -1 || endPos.character === start + 1 || start > position.character || endPos.character < position.character) {
return position;
}

return {
start : startPos,
stop : endPos,
};
}
}

@RegisterAction
class MoveIParentheses extends MoveInsideCharacter {
keys = ["i", "("];
charToMatch = "(";
}

@RegisterAction
class MoveIDoubleQuote extends MoveInsideCharacter {
keys = ["i", "\""];
charToMatch = "\"";
}

@RegisterAction
class MoveToUnclosedRoundBracketBackward extends MoveToMatchingBracket {
keys = ["[", "("];
Expand Down
21 changes: 21 additions & 0 deletions test/mode/modeNormal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,27 @@ suite("Mode Normal", () => {
endMode: ModeName.Insert
});

newTest({
title: "Can handle 'ci(' on first parentheses",
start: ['print(|"hello")'],
keysPressed: 'ci(',
end: ['print(|)']
});

newTest({
title: "Can handle 'ci(' with nested parentheses",
start: ['call|(() => 5)'],
keysPressed: 'ci(',
end: ['call(|)']
});

newTest({
title: "Can handle 'ci\"' inside a string",
start: ['"hel|lo" world'],
keysPressed: 'ci"',
end: ['"|" world']
});

newTest({
title: "Can handle 'df'",
start: ['aext tex|t'],
Expand Down

0 comments on commit 5a50f21

Please sign in to comment.