Skip to content
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

Add gd go to definition motion #258

Merged
48 changes: 25 additions & 23 deletions src/Actions/Delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,36 @@ import { UtilRange } from '../Utils/Range';

export class ActionDelete {
@StaticReflect.metadata(SymbolMetadata.Action.isChange, true)
static byMotions(args: {
static async byMotions(args: {
motions: Motion[];
isChangeAction?: boolean;
shouldYank?: boolean;
}): Thenable<boolean> {
}): Promise<boolean> {
args.isChangeAction = args.isChangeAction === undefined ? false : args.isChangeAction;
args.shouldYank = args.shouldYank === undefined ? false : args.shouldYank;

const activeTextEditor = window.activeTextEditor;

if (!activeTextEditor) {
return Promise.resolve(false);
return false;
}

const document = activeTextEditor.document;

let ranges = activeTextEditor.selections.map((selection) => {
let ranges: Range[] = [];

for (const selection of activeTextEditor.selections) {
const start = selection.active;
const end = args.motions.reduce((position, motion) => {
return motion.apply(position, {
let position = start;
for (const motion of args.motions) {
position = await motion.apply(position, {
isInclusive: true,
shouldCrossLines: false,
isChangeAction: args.isChangeAction,
});
}, start);
return new Range(start, end);
});
}
ranges.push(new Range(start, position));
}

if (args.motions.some((motion) => motion.isLinewise)) {
ranges = ranges.map((range) => UtilRange.toLinewise(range, document));
Expand All @@ -46,20 +49,19 @@ export class ActionDelete {

// TODO: Move cursor to first non-space if needed

return (args.shouldYank
? ActionRegister.yankByMotions({
motions: args.motions,
isChangeAction: args.isChangeAction,
})
: Promise.resolve(true)
)
.then(() => {
return activeTextEditor.edit((editBuilder) => {
ranges.forEach((range) => editBuilder.delete(range));
});
})
.then(() => ActionSelection.shrinkToStarts())
.then(() => ActionReveal.primaryCursor());
if (args.shouldYank) {
await ActionRegister.yankByMotions({
motions: args.motions,
isChangeAction: args.isChangeAction,
});
}
await activeTextEditor.edit((editBuilder) => {
ranges.forEach((range) => editBuilder.delete(range));
});
await ActionSelection.shrinkToStarts();
await ActionReveal.primaryCursor();

return true;
}

@StaticReflect.metadata(SymbolMetadata.Action.isChange, true)
Expand Down
39 changes: 22 additions & 17 deletions src/Actions/MoveCursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,20 @@ export class ActionMoveCursor {
return Promise.resolve(true);
}

static byMotions(args: {
static async byMotions(args: {
motions: Motion[];
isVisualMode?: boolean;
isVisualLineMode?: boolean;
noEmptyAtLineEnd?: boolean;
}): Thenable<boolean> {
}): Promise<boolean> {
args.isVisualMode = args.isVisualMode === undefined ? false : args.isVisualMode;
args.isVisualLineMode = args.isVisualLineMode === undefined ? false : args.isVisualLineMode;
args.noEmptyAtLineEnd = args.noEmptyAtLineEnd === undefined ? false : args.noEmptyAtLineEnd;

const activeTextEditor = window.activeTextEditor;

if (!activeTextEditor) {
return Promise.resolve(false);
return false;
}

// Prevent preferred character update if no motion updates character.
Expand All @@ -65,19 +65,21 @@ export class ActionMoveCursor {

const document = activeTextEditor.document;

activeTextEditor.selections = activeTextEditor.selections.map((selection, i) => {
const selections: Selection[] = [];

for (let i = 0; i < activeTextEditor.selections.length; i++) {
const selection = activeTextEditor.selections[i];
let anchor: Position;

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

for (const motion of args.motions) {
active = await motion.apply(active, {
preferredColumn: ActionMoveCursor.preferredColumnBySelectionIndex[i],
});
}

if (args.isVisualMode) {
anchor = selection.anchor;
Expand Down Expand Up @@ -127,9 +129,12 @@ export class ActionMoveCursor {
anchor = active;
}

return new Selection(anchor, active);
});
selections.push(new Selection(anchor, active));
}

activeTextEditor.selections = selections;
await ActionReveal.primaryCursor();
alisonatwork marked this conversation as resolved.
Show resolved Hide resolved

return ActionReveal.primaryCursor();
return true;
}
}
27 changes: 17 additions & 10 deletions src/Actions/Register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,33 +72,40 @@ export class ActionRegister {
return Promise.resolve(true);
}

static yankByMotions(args: { motions: Motion[]; isChangeAction?: boolean }): Thenable<boolean> {
static async yankByMotions(args: {
motions: Motion[];
isChangeAction?: boolean;
}): Promise<boolean> {
args.isChangeAction = args.isChangeAction === undefined ? false : args.isChangeAction;

const activeTextEditor = window.activeTextEditor;

if (!activeTextEditor) {
return Promise.resolve(false);
return false;
}

const isLinewise = args.motions.some((motion) => motion.isLinewise);

const ranges = activeTextEditor.selections.map((selection) => {
let ranges: Range[] = [];

for (const selection of activeTextEditor.selections) {
const start = selection.active;
const end = args.motions.reduce((position, motion) => {
return motion.apply(position, {
let position = start;
for (const motion of args.motions) {
position = await motion.apply(position, {
isInclusive: true,
shouldCrossLines: false,
isChangeAction: args.isChangeAction,
});
}, start);
return new Range(start, end);
});

return ActionRegister.yankRanges({
}
ranges.push(new Range(start, position));
}
await ActionRegister.yankRanges({
ranges: ranges,
isLinewise: isLinewise,
});

return true;
}

static async yankByTextObject(args: { textObject: TextObject }): Promise<boolean> {
Expand Down
3 changes: 3 additions & 0 deletions src/Mappers/SpecialKeys/Motion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { MotionMatchPair } from '../../Motions/MatchPair';
import { MotionLine } from '../../Motions/Line';
import { MotionParagraph } from '../../Motions/Paragraph';
import { MotionDocument } from '../../Motions/Document';
import { MotionNavigation } from '../../Motions/Navigation';

interface MotionGenerator {
(args?: {}): Motion;
Expand Down Expand Up @@ -120,6 +121,8 @@ export class SpecialKeyMotion extends GenericMapper implements SpecialKeyCommon

{ keys: 'space', motionGenerators: [MotionDirection.next] },
{ keys: 'backspace', motionGenerators: [MotionDirection.prev] },
{ keys: 'g d', motionGenerators: [MotionNavigation.toDeclaration] },
{ keys: 'g D', motionGenerators: [MotionNavigation.toTypeDefinition] },
];

constructor() {
Expand Down
4 changes: 2 additions & 2 deletions src/Motions/Direction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ export class MotionDirection extends Motion {
});
}

apply(from: Position, option?: any): Position {
from = super.apply(from);
async apply(from: Position, option?: any): Promise<Position> {
from = await super.apply(from);

const activeTextEditor = window.activeTextEditor;

Expand Down
4 changes: 2 additions & 2 deletions src/Motions/Document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ export class MotionDocument extends Motion {
return obj;
}

apply(from: Position): Position {
from = super.apply(from);
async apply(from: Position): Promise<Position> {
from = await super.apply(from);

const activeTextEditor = window.activeTextEditor;

Expand Down
4 changes: 2 additions & 2 deletions src/Motions/Line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ export class MotionLine extends Motion {
return obj;
}

apply(from: Position): Position {
from = super.apply(from);
async apply(from: Position): Promise<Position> {
from = await super.apply(from);

const activeTextEditor = window.activeTextEditor;

Expand Down
4 changes: 2 additions & 2 deletions src/Motions/Match.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ export class MotionMatch extends Motion {
return obj;
}

apply(from: Position, option: { isInclusive?: boolean } = {}): Position {
async apply(from: Position, option: { isInclusive?: boolean } = {}): Promise<Position> {
option.isInclusive = option.isInclusive === undefined ? false : option.isInclusive;

from = super.apply(from);
from = await super.apply(from);

const activeTextEditor = window.activeTextEditor;

Expand Down
6 changes: 3 additions & 3 deletions src/Motions/MatchPair.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ export class MotionMatchPair extends Motion {
return new MotionMatchPair();
}

apply(
async apply(
from: Position,
option: {
isInclusive?: boolean;
} = {},
): Position {
): Promise<Position> {
option.isInclusive = option.isInclusive === undefined ? false : option.isInclusive;

from = super.apply(from);
from = await super.apply(from);

const activeTextEditor = window.activeTextEditor;

Expand Down
2 changes: 1 addition & 1 deletion src/Motions/Motion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export abstract class Motion {
this.characterDelta += characterDelta;
}

apply(from: Position, option?: any): Position {
async apply(from: Position, option?: any): Promise<Position> {
const activeTextEditor = window.activeTextEditor;

if (!activeTextEditor) {
Expand Down
32 changes: 32 additions & 0 deletions src/Motions/Navigation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { commands, window, Position } from 'vscode';
import { Motion } from './Motion';

export class MotionNavigation extends Motion {
private command: string;

static toDeclaration(): Motion {
const obj = new MotionNavigation({ isLinewise: true });
obj.command = 'editor.action.goToDeclaration';
return obj;
}

static toTypeDefinition(): Motion {
const obj = new MotionNavigation({ isLinewise: true });
obj.command = 'editor.action.goToTypeDefinition';
return obj;
}

async apply(from: Position): Promise<Position> {
from = await super.apply(from);

const activeTextEditor = window.activeTextEditor;

if (!activeTextEditor) {
return from;
}

await commands.executeCommand(this.command);

return activeTextEditor.selection.active;
}
}
4 changes: 2 additions & 2 deletions src/Motions/Paragraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ export class MotionParagraph extends Motion {
});
}

apply(from: Position): Position {
from = super.apply(from);
async apply(from: Position): Promise<Position> {
from = await super.apply(from);

const activeTextEditor = window.activeTextEditor;

Expand Down
6 changes: 3 additions & 3 deletions src/Motions/Word.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,20 @@ export class MotionWord extends Motion {
return obj;
}

apply(
async apply(
from: Position,
option: {
isInclusive?: boolean;
isChangeAction?: boolean;
shouldCrossLines?: boolean;
} = {},
): Position {
): Promise<Position> {
option.isInclusive = option.isInclusive === undefined ? false : option.isInclusive;
option.isChangeAction = option.isChangeAction === undefined ? false : option.isChangeAction;
option.shouldCrossLines =
option.shouldCrossLines === undefined ? true : option.shouldCrossLines;

from = super.apply(from);
from = await super.apply(from);

const activeTextEditor = window.activeTextEditor;

Expand Down
Loading