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
72 changes: 35 additions & 37 deletions src/Actions/Delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,60 +10,58 @@ 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;

const promisedRanges = activeTextEditor.selections.map(async (selection) => {
const start = selection.active;
const end = await args.motions.reduce((promisedPosition, motion) => {
return promisedPosition.then((position) =>
motion.apply(position, {
isInclusive: true,
shouldCrossLines: false,
isChangeAction: args.isChangeAction,
}),
);
}, Promise.resolve(start));
return new Range(start, end);
});
let ranges: Range[] = [];

return Promise.all(promisedRanges).then((ranges) => {
if (args.motions.some((motion) => motion.isLinewise)) {
ranges = ranges.map((range) => UtilRange.toLinewise(range, document));
for (const selection of activeTextEditor.selections) {
const start = selection.active;
let position = start;
for (const motion of args.motions) {
position = await motion.apply(position, {
isInclusive: true,
shouldCrossLines: false,
isChangeAction: args.isChangeAction,
});
}
ranges.push(new Range(start, position));
}

ranges = UtilRange.unionOverlaps(ranges);

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

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

ranges = UtilRange.unionOverlaps(ranges);

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

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
42 changes: 23 additions & 19 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,16 +65,21 @@ export class ActionMoveCursor {

const document = activeTextEditor.document;

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

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

let active = await args.motions.reduce((promisedPosition, motion) => {
return promisedPosition.then((position) =>
motion.apply(position, {
preferredColumn: ActionMoveCursor.preferredColumnBySelectionIndex[i],
}),
);
}, Promise.resolve(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 @@ -124,13 +129,12 @@ export class ActionMoveCursor {
anchor = active;
}

return new Selection(anchor, active);
});
return Promise.all(promisedSelections)
.then((selections) => {
activeTextEditor.selections = selections;
return Promise.resolve(true);
})
.then(() => ActionReveal.primaryCursor());
selections.push(new Selection(anchor, active));
}

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

return true;
}
}
42 changes: 23 additions & 19 deletions src/Actions/Register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,36 +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 promisedRanges = activeTextEditor.selections.map(async (selection) => {
let ranges: Range[] = [];

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

return true;
}

static async yankByTextObject(args: { textObject: TextObject }): Promise<boolean> {
Expand Down