Skip to content

Commit

Permalink
Merge pull request #172 from aioutecism/fix/match-pair-motion
Browse files Browse the repository at this point in the history
Fix wrong behavior with %
  • Loading branch information
aioutecism committed Apr 7, 2017
2 parents 1a2f493 + 3c563f9 commit 6bcc339
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 27 deletions.
43 changes: 22 additions & 21 deletions src/Actions/MoveCursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {window, Position, Selection} from 'vscode';
import {ActionReveal} from './Reveal';
import {Motion} from '../Motions/Motion';
import {UtilPosition} from '../Utils/Position';
import {UtilSelection} from '../Utils/Selection';

export class ActionMoveCursor {

Expand Down Expand Up @@ -66,34 +67,34 @@ export class ActionMoveCursor {
activeTextEditor.selections = activeTextEditor.selections.map((selection, i) => {
let anchor: Position;

let active = args.motions.reduce((position, motion) => {
return motion.apply(position, {
isInclusive: args.isVisualMode,
preferedColumn: ActionMoveCursor.preferedColumnBySelectionIndex[i]
});
}, selection.active);
let active = args.motions.reduce(
(position, motion) => {
return motion.apply(position, {
preferedColumn: ActionMoveCursor.preferedColumnBySelectionIndex[i]
});
},
args.isVisualMode
? UtilSelection.getActiveInVisualMode(selection)
: selection.active
);

if (args.isVisualMode) {
anchor = selection.anchor;

if (anchor.isEqual(active)) {
if (active.isBefore(selection.active)) {
anchor = anchor.translate(0, +1);
if (active.character > 0) {
active = active.translate(0, -1);
}
}
else {
if (anchor.character > 0) {
anchor = anchor.translate(0, -1);
}
active = active.translate(0, +1);
}
const anchorLineLength = activeTextEditor.document.lineAt(anchor.line).text.length;
const activeLineLength = activeTextEditor.document.lineAt(active.line).text.length;

if (active.isAfterOrEqual(anchor) && active.character < activeLineLength) {
active = active.translate(0, +1);
}

if (active.isEqual(anchor) && anchor.character > 0) {
anchor = anchor.translate(0, -1);
}
else if (active.isAfter(anchor) && selection.active.isBefore(selection.anchor)) {
else if (active.isAfter(anchor) && selection.isReversed && anchor.character > 0) {
anchor = anchor.translate(0, -1);
}
else if (active.isBefore(anchor) && selection.active.isAfter(selection.anchor)) {
else if (active.isBefore(anchor) && !selection.isReversed && anchor.character < anchorLineLength) {
anchor = anchor.translate(0, +1);
}
}
Expand Down
11 changes: 9 additions & 2 deletions src/Motions/MatchPair.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,14 @@ export class MotionMatchPair extends Motion {
return new MotionMatchPair();
}

apply(from: Position, option?: any): Position {
apply(
from: Position,
option: {
isInclusive?: boolean,
} = {}
): Position {
option.isInclusive = option.isInclusive === undefined ? false : option.isInclusive;

from = super.apply(from);

const activeTextEditor = window.activeTextEditor;
Expand Down Expand Up @@ -65,7 +72,7 @@ export class MotionMatchPair extends Motion {
else {
const endRange = textObject.findEndRange(document, new Position(from.line, character));
if (endRange !== null) {
return endRange.start;
return option.isInclusive ? endRange.end : endRange.start;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Motions/Word.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import {window, TextDocument, Position} from 'vscode';
import {Motion} from './Motion';
import {WordCharacterKind, UtilWord} from '../Utils/Word';

enum MotionWordDirection {Previous, Next};
enum MotionWordMatchKind {Start, End, Both};
enum MotionWordDirection {Previous, Next}
enum MotionWordMatchKind {Start, End, Both}

export class MotionWord extends Motion {

Expand Down
22 changes: 21 additions & 1 deletion src/Utils/Selection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Selection} from 'vscode';
import {Selection, Position} from 'vscode';

export class UtilSelection {

Expand Down Expand Up @@ -47,4 +47,24 @@ export class UtilSelection {
return selections.map(selection => UtilSelection.shrinkToActive(selection));
}

static getActiveInVisualMode(anchor: Position, active: Position): Position;
static getActiveInVisualMode(selection: Selection): Position;
static getActiveInVisualMode(first: Position | Selection, second?: Position): Position {
let active: Position;
let isReversed: boolean;

if (second) {
isReversed = (first as Position).isAfter(second);
active = second;
}
else {
isReversed = (first as Selection).isReversed;
active = (first as Selection).active;
}

return !isReversed && active.character > 0
? active.translate(0, -1)
: active;
}

}
2 changes: 1 addition & 1 deletion test/ModeNormal/~.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as BlackBox from '../Framework/BlackBox';

suite.only('Normal: ~', () => {
suite('Normal: ~', () => {
const testCases: BlackBox.TestCase[] = [
{
from: '[]Foo',
Expand Down
30 changes: 30 additions & 0 deletions test/ModeVisual/h.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as BlackBox from '../Framework/BlackBox';

suite('Visual: h', () => {
const testCases: BlackBox.TestCase[] = [
{
from: '[F]oo bar',
inputs: 'h',
to: '[F]oo bar',
},
{
from: 'F[o]o bar',
inputs: 'h',
to: '~[Fo]o bar',
},
{
from: '[Fo]o bar',
inputs: 'h',
to: '[F]oo bar',
},
{
from: '~[F]oo bar',
inputs: 'h',
to: '~[F]oo bar',
},
];

for (let i = 0; i < testCases.length; i++) {
BlackBox.run(testCases[i]);
}
});
30 changes: 30 additions & 0 deletions test/ModeVisual/l.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as BlackBox from '../Framework/BlackBox';

suite('Visual: l', () => {
const testCases: BlackBox.TestCase[] = [
{
from: 'Foo ba~[r]',
inputs: 'l',
to: 'Foo ba[r]',
},
{
from: 'Foo b~[a]r',
inputs: 'l',
to: 'Foo b[ar]',
},
{
from: 'Foo b~[ar]',
inputs: 'l',
to: 'Foo ba~[r]',
},
{
from: 'Foo ba[r]',
inputs: 'l',
to: 'Foo ba[r]',
},
];

for (let i = 0; i < testCases.length; i++) {
BlackBox.run(testCases[i]);
}
});

0 comments on commit 6bcc339

Please sign in to comment.