|
1 |
| -import { Range } from "@cursorless/common"; |
| 1 | +import { Range, adjustPosition } from "@cursorless/common"; |
2 | 2 | import { z } from "zod";
|
3 | 3 | import { makeRangeFromPositions } from "../../util/nodeSelectors";
|
4 | 4 | import { MutableQueryCapture } from "./QueryCapture";
|
@@ -139,6 +139,26 @@ class ShrinkToMatch extends QueryPredicateOperator<ShrinkToMatch> {
|
139 | 139 | }
|
140 | 140 | }
|
141 | 141 |
|
| 142 | +/** |
| 143 | + * A predicate operator that modifies the range of the match by trimming trailing whitespace, |
| 144 | + * similar to the javascript trimEnd function. |
| 145 | + */ |
| 146 | +class TrimEnd extends QueryPredicateOperator<TrimEnd> { |
| 147 | + name = "trim-end!" as const; |
| 148 | + schema = z.tuple([q.node]); |
| 149 | + |
| 150 | + run(nodeInfo: MutableQueryCapture) { |
| 151 | + const { document, range } = nodeInfo; |
| 152 | + const text = document.getText(range); |
| 153 | + const whitespaceLength = text.length - text.trimEnd().length; |
| 154 | + nodeInfo.range = new Range( |
| 155 | + range.start, |
| 156 | + adjustPosition(document, range.end, -whitespaceLength), |
| 157 | + ); |
| 158 | + return true; |
| 159 | + } |
| 160 | +} |
| 161 | + |
142 | 162 | /**
|
143 | 163 | * Indicates that it is ok for multiple captures to have the same domain but
|
144 | 164 | * different targets. For example, if we have the query `(#allow-multiple!
|
@@ -197,6 +217,7 @@ class InsertionDelimiter extends QueryPredicateOperator<InsertionDelimiter> {
|
197 | 217 | export const queryPredicateOperators = [
|
198 | 218 | new Log(),
|
199 | 219 | new NotType(),
|
| 220 | + new TrimEnd(), |
200 | 221 | new NotParentType(),
|
201 | 222 | new IsNthChild(),
|
202 | 223 | new ChildRange(),
|
|
0 commit comments