Skip to content

Commit 56172e3

Browse files
Refactor add scopes
1 parent b56f753 commit 56172e3

File tree

1 file changed

+53
-51
lines changed

1 file changed

+53
-51
lines changed

packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/CollectionItemTextualScopeHandler.ts

Lines changed: 53 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -82,61 +82,14 @@ export class CollectionItemTextualScopeHandler extends BaseScopeHandler {
8282
direction: Direction,
8383
hints: ScopeIteratorRequirements,
8484
): Iterable<TargetScope> {
85-
const { document } = editor;
8685
const isEveryScope = hints.containment == null && hints.skipAncestorScopes;
87-
const separatorRanges = getSeparatorOccurrences(document);
88-
86+
const separatorRanges = getSeparatorOccurrences(editor.document);
8987
const interiorRanges = this.getInteriorRanges(editor, "collectionBoundary");
9088
const stringRanges = this.getInteriorRanges(editor, "string");
91-
9289
const scopes: TargetScope[] = [];
9390
const usedInteriors = new Set<Range>();
9491
const iterationStatesStack: IterationState[] = [];
9592

96-
function addScopes(state: IterationState) {
97-
const { delimiters, iterationRange: iterationRange } = state;
98-
99-
if (delimiters.length === 0) {
100-
return;
101-
}
102-
103-
const itemRanges: Range[] = [];
104-
105-
for (let i = 0; i < delimiters.length; ++i) {
106-
const current = delimiters[i];
107-
108-
const previous = delimiters[i - 1]?.end ?? iterationRange.start;
109-
itemRanges.push(new Range(previous, current.start));
110-
}
111-
112-
const lastDelimiter = delimiters[delimiters.length - 1];
113-
itemRanges.push(new Range(lastDelimiter.end, iterationRange.end));
114-
115-
const trimmedRanges = itemRanges.map((range) =>
116-
shrinkRangeToFitContent(editor, range),
117-
);
118-
119-
for (let i = 0; i < trimmedRanges.length; ++i) {
120-
// Handle trailing delimiter
121-
if (
122-
i === trimmedRanges.length - 1 &&
123-
document.getText(trimmedRanges[i]).trim() === ""
124-
) {
125-
continue;
126-
}
127-
scopes.push(
128-
createTargetScope(
129-
isEveryScope,
130-
editor,
131-
iterationRange,
132-
trimmedRanges[i],
133-
trimmedRanges[i - 1],
134-
trimmedRanges[i + 1],
135-
),
136-
);
137-
}
138-
}
139-
14093
// TODO: fixed performance on large files
14194
for (const separator of separatorRanges) {
14295
// Separators in a string are not considered
@@ -154,7 +107,8 @@ export class CollectionItemTextualScopeHandler extends BaseScopeHandler {
154107

155108
// The contain range is either the interior or the line containing the separator
156109
const containingIterationRange =
157-
containingInteriorRange ?? document.lineAt(separator.start.line).range;
110+
containingInteriorRange ??
111+
editor.document.lineAt(separator.start.line).range;
158112

159113
if (currentIterationState != null) {
160114
// The current containing iteration range is the same as the previous one. Just append delimiter.
@@ -169,7 +123,7 @@ export class CollectionItemTextualScopeHandler extends BaseScopeHandler {
169123

170124
// The current containing range does not intersect previous one. Add scopes and remove state.
171125
if (!currentIterationState.iterationRange.contains(separator)) {
172-
addScopes(currentIterationState);
126+
this.addScopes(scopes, currentIterationState);
173127
// Remove already added state
174128
iterationStatesStack.pop();
175129
}
@@ -188,13 +142,15 @@ export class CollectionItemTextualScopeHandler extends BaseScopeHandler {
188142
usedInteriors.add(containingInteriorRange);
189143

190144
iterationStatesStack.push({
145+
editor,
146+
isEveryScope,
191147
iterationRange: containingIterationRange,
192148
delimiters: [separator],
193149
});
194150
}
195151

196152
for (const state of iterationStatesStack) {
197-
addScopes(state);
153+
this.addScopes(scopes, state);
198154
}
199155

200156
// Add interior ranges without a delimiter in them. eg: `[foo]`
@@ -211,9 +167,55 @@ export class CollectionItemTextualScopeHandler extends BaseScopeHandler {
211167

212168
yield* scopes;
213169
}
170+
171+
private addScopes(scopes: TargetScope[], state: IterationState) {
172+
const { editor, iterationRange, isEveryScope, delimiters } = state;
173+
174+
if (delimiters.length === 0) {
175+
return;
176+
}
177+
178+
const itemRanges: Range[] = [];
179+
180+
for (let i = 0; i < delimiters.length; ++i) {
181+
const current = delimiters[i];
182+
183+
const previous = delimiters[i - 1]?.end ?? iterationRange.start;
184+
itemRanges.push(new Range(previous, current.start));
185+
}
186+
187+
const lastDelimiter = delimiters[delimiters.length - 1];
188+
itemRanges.push(new Range(lastDelimiter.end, iterationRange.end));
189+
190+
const trimmedRanges = itemRanges.map((range) =>
191+
shrinkRangeToFitContent(editor, range),
192+
);
193+
194+
for (let i = 0; i < trimmedRanges.length; ++i) {
195+
// Handle trailing delimiter
196+
if (
197+
i === trimmedRanges.length - 1 &&
198+
editor.document.getText(trimmedRanges[i]).trim() === ""
199+
) {
200+
continue;
201+
}
202+
scopes.push(
203+
createTargetScope(
204+
isEveryScope,
205+
editor,
206+
iterationRange,
207+
trimmedRanges[i],
208+
trimmedRanges[i - 1],
209+
trimmedRanges[i + 1],
210+
),
211+
);
212+
}
213+
}
214214
}
215215

216216
interface IterationState {
217+
editor: TextEditor;
217218
iterationRange: Range;
219+
isEveryScope: boolean;
218220
delimiters: Range[];
219221
}

0 commit comments

Comments
 (0)