Skip to content

Reworked weak target #888

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

Merged
merged 43 commits into from
Jul 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
b0dc3d6
Renamed weak target, Renamed is weak, Added explicit range attribute
AndreasArvidsson Jul 24, 2022
2fa5144
Don't remove leading or trailing delimited ranges for empty selection
AndreasArvidsson Jul 24, 2022
a2bfab8
Added clone parameters
AndreasArvidsson Jul 24, 2022
b2c1e26
Updated comment
AndreasArvidsson Jul 24, 2022
de404c0
Always create continuous range
AndreasArvidsson Jul 24, 2022
a9eeb96
Renamed UnTypedRangeTarget to UnTypedTarget
AndreasArvidsson Jul 24, 2022
4195f75
Process targets before test recorded command hook
AndreasArvidsson Jul 24, 2022
6184bc9
Added tests
AndreasArvidsson Jul 24, 2022
a382209
Renamed to ifUntyped
AndreasArvidsson Jul 24, 2022
8437c1c
Added item tests
AndreasArvidsson Jul 24, 2022
9016ebe
Cleanup
AndreasArvidsson Jul 24, 2022
93378eb
Update src/typings/targetDescriptor.types.ts
AndreasArvidsson Jul 24, 2022
3d3b016
Update src/typings/targetDescriptor.types.ts
AndreasArvidsson Jul 24, 2022
471bc4d
Cleanup
AndreasArvidsson Jul 24, 2022
ce502b4
Cleanup
AndreasArvidsson Jul 24, 2022
1c1fc65
Added tests
AndreasArvidsson Jul 24, 2022
62f86b6
Cleanup
AndreasArvidsson Jul 24, 2022
7eb81f0
Added tests
AndreasArvidsson Jul 24, 2022
414aaa2
added tests
AndreasArvidsson Jul 24, 2022
718af86
Use undefined return value in error test cases
pokey Jul 25, 2022
bf83803
Docstring
pokey Jul 25, 2022
32c6f91
Better error type for no inside / bounds
pokey Jul 25, 2022
22ad63d
Remove code sharing from ThatStage and CursorStage
pokey Jul 25, 2022
6850321
Doc strings
pokey Jul 25, 2022
5cbef5c
Switch test subset
pokey Jul 25, 2022
8664789
Fix docstring link
pokey Jul 25, 2022
7b87638
Record alternate "leading funk" test
pokey Jul 25, 2022
feaffd4
Record some more tests
pokey Jul 25, 2022
bf25d47
Add a bunch of tests
pokey Jul 25, 2022
8118438
Cleaned up from review
pokey Jul 25, 2022
4f4fda7
Docstring
pokey Jul 25, 2022
46997e0
More tests
pokey Jul 25, 2022
6e18a39
One more test
pokey Jul 25, 2022
46bf278
Another test
pokey Jul 25, 2022
9ad7e9f
Rollback imports to avoid circular import
pokey Jul 25, 2022
8e1daa9
Improve test
pokey Jul 25, 2022
77b4663
Revert "Rollback imports to avoid circular import"
pokey Jul 25, 2022
29b63c2
Fix imports
pokey Jul 25, 2022
d1d3421
Add tests; fix bug with `"every block"`
pokey Jul 27, 2022
6abc639
Minor tweak
pokey Jul 27, 2022
142cd4b
Fix doc
pokey Jul 27, 2022
d6341ed
Docstrings
pokey Jul 27, 2022
82e2a47
Merge branch 'main' into reworkIsWeek
pokey Jul 27, 2022
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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@
"@types/vscode": "~1.61.0",
"@typescript-eslint/eslint-plugin": "^5.20.0",
"@typescript-eslint/parser": "^5.20.0",
"@vscode/test-electron": "^2.1.3",
"esbuild": "^0.11.12",
"eslint": "^8.13.0",
"eslint-config-prettier": "^8.5.0",
Expand All @@ -558,8 +559,7 @@
"semver": "^7.3.7",
"sinon": "^11.1.1",
"ts-unused-exports": "8.0.0",
"typescript": "^4.5.5",
"@vscode/test-electron": "^2.1.3"
"typescript": "^4.5.5"
},
"dependencies": {
"@types/lodash": "^4.14.168",
Expand Down
4 changes: 2 additions & 2 deletions src/actions/EditNew/EditNew.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { weakContainingLineStage } from "../../processTargets/modifiers/commonWeakContainingScopeStages";
import { containingLineIfUntypedStage } from "../../processTargets/modifiers/commonContainingScopeIfUntypedStages";
import PositionStage from "../../processTargets/modifiers/PositionStage";
import { ModifierStage } from "../../processTargets/PipelineStages.types";
import { Target } from "../../typings/target.types";
Expand All @@ -14,7 +14,7 @@ import { runEditTargets } from "./runEditTargets";

export class EditNew implements Action {
getFinalStages(): ModifierStage[] {
return [weakContainingLineStage];
return [containingLineIfUntypedStage];
}

constructor(private graph: Graph) {
Expand Down
4 changes: 2 additions & 2 deletions src/actions/InsertCopy.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { flatten, zip } from "lodash";
import { DecorationRangeBehavior, Selection, TextEditor } from "vscode";
import { performEditsAndUpdateSelectionsWithBehavior } from "../core/updateSelections/updateSelections";
import { weakContainingLineStage } from "../processTargets/modifiers/commonWeakContainingScopeStages";
import { containingLineIfUntypedStage } from "../processTargets/modifiers/commonContainingScopeIfUntypedStages";
import { Target } from "../typings/target.types";
import { Graph } from "../typings/Types";
import { setSelectionsWithoutFocusingEditor } from "../util/setSelectionsAndFocusEditor";
import { createThatMark, runOnTargetsForEachEditor } from "../util/targetUtils";
import { Action, ActionReturnValue } from "./actions.types";

class InsertCopy implements Action {
getFinalStages = () => [weakContainingLineStage];
getFinalStages = () => [containingLineIfUntypedStage];

constructor(private graph: Graph, private isBefore: boolean) {
this.run = this.run.bind(this);
Expand Down
6 changes: 3 additions & 3 deletions src/actions/InsertSnippet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
callFunctionAndUpdateSelectionInfos,
getSelectionInfo,
} from "../core/updateSelections/updateSelections";
import ModifyIfWeakStage from "../processTargets/modifiers/ModifyIfWeakStage";
import ModifyIfUntypedStage from "../processTargets/modifiers/ModifyIfUntypedStage";
import { Snippet, SnippetDefinition } from "../typings/snippet";
import { Target } from "../typings/target.types";
import { Graph } from "../typings/Types";
Expand All @@ -29,8 +29,8 @@ export default class InsertSnippet implements Action {
}

return [
new ModifyIfWeakStage({
type: "modifyIfWeak",
new ModifyIfUntypedStage({
type: "modifyIfUntyped",
modifier: {
type: "cascading",
modifiers: defaultScopeTypes.map((scopeType) => ({
Expand Down
4 changes: 2 additions & 2 deletions src/actions/Rewrap.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { performEditsAndUpdateRanges } from "../core/updateSelections/updateSelections";
import { weakContainingSurroundingPairStage } from "../processTargets/modifiers/commonWeakContainingScopeStages";
import { containingSurroundingPairIfUntypedStage } from "../processTargets/modifiers/commonContainingScopeIfUntypedStages";
import { Target } from "../typings/target.types";
import { Graph } from "../typings/Types";
import { createThatMark, runOnTargetsForEachEditor } from "../util/targetUtils";
import { Action, ActionReturnValue } from "./actions.types";

export default class Rewrap implements Action {
getFinalStages = () => [weakContainingSurroundingPairStage];
getFinalStages = () => [containingSurroundingPairIfUntypedStage];

constructor(private graph: Graph) {
this.run = this.run.bind(this);
Expand Down
4 changes: 2 additions & 2 deletions src/actions/ToggleBreakpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
SourceBreakpoint,
Uri,
} from "vscode";
import { weakContainingLineStage } from "../processTargets/modifiers/commonWeakContainingScopeStages";
import { containingLineIfUntypedStage } from "../processTargets/modifiers/commonContainingScopeIfUntypedStages";
import { Target } from "../typings/target.types";
import { Graph } from "../typings/Types";
import { createThatMark } from "../util/targetUtils";
Expand All @@ -22,7 +22,7 @@ function getBreakpoints(uri: Uri, range: Range) {
}

export default class ToggleBreakpoint implements Action {
getFinalStages = () => [weakContainingLineStage];
getFinalStages = () => [containingLineIfUntypedStage];

constructor(private graph: Graph) {
this.run = this.run.bind(this);
Expand Down
6 changes: 3 additions & 3 deletions src/actions/WrapWithSnippet.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { commands } from "vscode";
import { callFunctionAndUpdateSelections } from "../core/updateSelections/updateSelections";
import ModifyIfWeakStage from "../processTargets/modifiers/ModifyIfWeakStage";
import ModifyIfUntypedStage from "../processTargets/modifiers/ModifyIfUntypedStage";
import { Target } from "../typings/target.types";
import { Graph } from "../typings/Types";
import {
Expand Down Expand Up @@ -28,8 +28,8 @@ export default class WrapWithSnippet implements Action {
}

return [
new ModifyIfWeakStage({
type: "modifyIfWeak",
new ModifyIfUntypedStage({
type: "modifyIfUntyped",
modifier: {
type: "containingScope",
scopeType: {
Expand Down
3 changes: 1 addition & 2 deletions src/processTargets/getMarkStage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import CursorStage from "./marks/CursorStage";
import DecoratedSymbolStage from "./marks/DecoratedSymbolStage";
import LineNumberStage from "./marks/LineNumberStage";
import NothingStage from "./marks/NothingStage";
import SourceStage from "./marks/SourceStage";
import ThatStage from "./marks/ThatStage";
import { SourceStage, ThatStage } from "./marks/ThatStage";
import { MarkStage } from "./PipelineStages.types";

export default (mark: Mark): MarkStage => {
Expand Down
6 changes: 3 additions & 3 deletions src/processTargets/getModifierStage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from "./modifiers/InteriorStage";
import ItemStage from "./modifiers/ItemStage";
import { LeadingStage, TrailingStage } from "./modifiers/LeadingTrailingStages";
import ModifyIfWeakStage from "./modifiers/ModifyIfWeakStage";
import ModifyIfUntypedStage from "./modifiers/ModifyIfUntypedStage";
import OrdinalRangeSubTokenStage, {
OrdinalRangeSubTokenModifier,
} from "./modifiers/OrdinalRangeSubTokenStage";
Expand Down Expand Up @@ -70,8 +70,8 @@ export default (modifier: Modifier): ModifierStage => {
);
case "cascading":
return new CascadingStage(modifier);
case "modifyIfWeak":
return new ModifyIfWeakStage(modifier);
case "modifyIfUntyped":
return new ModifyIfUntypedStage(modifier);
}
};

Expand Down
26 changes: 11 additions & 15 deletions src/processTargets/marks/CursorStage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,20 @@ import type { CursorMark } from "../../typings/targetDescriptor.types";
import { ProcessedTargetsContext } from "../../typings/Types";
import { isReversed } from "../../util/selectionUtils";
import { MarkStage } from "../PipelineStages.types";
import WeakTarget from "../targets/WeakTarget";
import TokenTarget from "../targets/TokenTarget";
import UntypedTarget from "../targets/UntypedTarget";

export default class CursorStage implements MarkStage {
constructor(_modifier: CursorMark) {
// takes mark for consistency and does nothing
}
constructor(private modifier: CursorMark) {}

run(context: ProcessedTargetsContext): Target[] {
return context.currentSelections.map((selection) => {
const parameters = {
editor: selection.editor,
isReversed: isReversed(selection.selection),
contentRange: selection.selection,
};
return selection.selection.isEmpty
? new WeakTarget(parameters)
: new TokenTarget(parameters);
});
return context.currentSelections.map(
(selection) =>
new UntypedTarget({
editor: selection.editor,
isReversed: isReversed(selection.selection),
contentRange: selection.selection,
hasExplicitRange: !selection.selection.isEmpty,
})
);
}
}
5 changes: 3 additions & 2 deletions src/processTargets/marks/DecoratedSymbolStage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Target } from "../../typings/target.types";
import { DecoratedSymbolMark } from "../../typings/targetDescriptor.types";
import { ProcessedTargetsContext } from "../../typings/Types";
import { MarkStage } from "../PipelineStages.types";
import { WeakTarget } from "../targets";
import { UntypedTarget } from "../targets";

export default class implements MarkStage {
constructor(private modifier: DecoratedSymbolMark) {}
Expand All @@ -20,10 +20,11 @@ export default class implements MarkStage {
}

return [
new WeakTarget({
new UntypedTarget({
editor: token.editor,
contentRange: token.range,
isReversed: false,
hasExplicitRange: false,
}),
];
}
Expand Down
23 changes: 0 additions & 23 deletions src/processTargets/marks/SourceStage.ts

This file was deleted.

40 changes: 31 additions & 9 deletions src/processTargets/marks/ThatStage.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,45 @@
import { Target } from "../../typings/target.types";
import { ThatMark } from "../../typings/targetDescriptor.types";
import { ProcessedTargetsContext } from "../../typings/Types";
import { SourceMark, ThatMark } from "../../typings/targetDescriptor.types";
import {
ProcessedTargetsContext,
SelectionWithEditor,
} from "../../typings/Types";
import { isReversed } from "../../util/selectionUtils";
import { MarkStage } from "../PipelineStages.types";
import WeakTarget from "../targets/WeakTarget";
import { UntypedTarget } from "../targets";

export default class implements MarkStage {
export class ThatStage implements MarkStage {
constructor(private modifier: ThatMark) {}

run(context: ProcessedTargetsContext): Target[] {
if (context.thatMark.length === 0) {
throw Error("No available that marks");
}
return context.thatMark.map((selection) => {
return new WeakTarget({

return selectionsToTarget(context.thatMark);
}
}

export class SourceStage implements MarkStage {
constructor(private modifier: SourceMark) {}

run(context: ProcessedTargetsContext): Target[] {
if (context.sourceMark.length === 0) {
throw Error("No available source marks");
}

return selectionsToTarget(context.sourceMark);
}
}

function selectionsToTarget(selections: SelectionWithEditor[]) {
return selections.map(
(selection) =>
new UntypedTarget({
editor: selection.editor,
isReversed: isReversed(selection.selection),
contentRange: selection.selection,
});
});
}
hasExplicitRange: !selection.selection.isEmpty,
})
);
}
6 changes: 3 additions & 3 deletions src/processTargets/modifiers/InteriorStage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import {
} from "../../typings/targetDescriptor.types";
import { ProcessedTargetsContext } from "../../typings/Types";
import { ModifierStage } from "../PipelineStages.types";
import { weakContainingSurroundingPairStage } from "./commonWeakContainingScopeStages";
import { containingSurroundingPairIfUntypedStage } from "./commonContainingScopeIfUntypedStages";

export class InteriorOnlyStage implements ModifierStage {
constructor(private modifier: InteriorOnlyModifier) {}

run(context: ProcessedTargetsContext, target: Target): Target[] {
return weakContainingSurroundingPairStage
return containingSurroundingPairIfUntypedStage
.run(context, target)
.flatMap((target) => target.getInteriorStrict());
}
Expand All @@ -21,7 +21,7 @@ export class ExcludeInteriorStage implements ModifierStage {
constructor(private modifier: ExcludeInteriorModifier) {}

run(context: ProcessedTargetsContext, target: Target): Target[] {
return weakContainingSurroundingPairStage
return containingSurroundingPairIfUntypedStage
.run(context, target)
.flatMap((target) => target.getBoundaryStrict());
}
Expand Down
8 changes: 4 additions & 4 deletions src/processTargets/modifiers/ItemStage/ItemStage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ export default class ItemStage implements ModifierStage {
private getEveryTarget(context: ProcessedTargetsContext, target: Target) {
const itemInfos = getItemInfosForIterationScope(context, target);

// If weak expand to all items in iteration scope
const filteredItemInfos = target.isWeak
? itemInfos
: filterItemInfos(target, itemInfos);
// If target has explicit range filter to items in that range. Otherwise expand to all items in iteration scope.
const filteredItemInfos = target.hasExplicitRange
? filterItemInfos(target, itemInfos)
: itemInfos;

if (filteredItemInfos.length === 0) {
throw new NoContainingScopeError(this.modifier.scopeType.type);
Expand Down
21 changes: 16 additions & 5 deletions src/processTargets/modifiers/LeadingTrailingStages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,27 @@ import {
} from "../../typings/targetDescriptor.types";
import { ProcessedTargetsContext } from "../../typings/Types";
import { ModifierStage } from "../PipelineStages.types";
import { weakContainingTokenStage } from "./commonWeakContainingScopeStages";
import { containingTokenIfUntypedStage } from "./commonContainingScopeIfUntypedStages";

/**
* Throw this error if user has requested leading or trailing delimiter but no
* such delimiter exists on the given target.
*/
class NoDelimiterError extends Error {
constructor(type: "leading" | "trailing") {
super(`Target has no ${type} delimiter.`);
this.name = "NoDelimiterError";
}
}

export class LeadingStage implements ModifierStage {
constructor(private modifier: LeadingModifier) {}

run(context: ProcessedTargetsContext, target: Target): Target[] {
return weakContainingTokenStage.run(context, target).map((target) => {
return containingTokenIfUntypedStage.run(context, target).map((target) => {
const leading = target.getLeadingDelimiterTarget();
if (leading == null) {
throw Error("No available leading delimiter range");
throw new NoDelimiterError("leading");
}
return leading;
});
Expand All @@ -25,10 +36,10 @@ export class TrailingStage implements ModifierStage {
constructor(private modifier: TrailingModifier) {}

run(context: ProcessedTargetsContext, target: Target): Target[] {
return weakContainingTokenStage.run(context, target).map((target) => {
return containingTokenIfUntypedStage.run(context, target).map((target) => {
const trailing = target.getTrailingDelimiterTarget();
if (trailing == null) {
throw Error("No available trailing delimiter range");
throw new NoDelimiterError("trailing");
}
return trailing;
});
Expand Down
Loading