Fix invalid handling of global RegExps (fixes #143).

This commit is contained in:
Grégoire Geis 2021-05-06 00:34:31 +02:00
parent 1cce5798db
commit 0d994c6f83
4 changed files with 52 additions and 8 deletions

View File

@ -721,12 +721,28 @@ export function splitSelections(re: RegExp, selections = Context.current.selecti
/**
* Returns the selections obtained by finding all the matches within the given
* selections using the given RegExp.
*
* ### Example
*
* ```ts
* expect(Selections.selectWithin(/\d/).map(text), "to equal", [
* "1",
* "2",
* "6",
* "7",
* "8",
* ]);
* ```
*
* With:
* ```
* a1b2c3d4
* ^^^^^ 0
* e5f6g7h8
* ^^^^^^ 1
* ```
*/
export function selectWithinSelections(re: RegExp, selections = Context.current.selections) {
if (!re.global) {
re = new RegExp(re.source, re.flags + "g");
}
const document = Context.current.document;
return Selections.map((text, selection) => {

View File

@ -40,11 +40,11 @@ export function search(
setInput: SetInput<RegExp>,
) {
return manipulateSelectionsInteractively(_, input, setInput, interactive, {
...prompt.regexpOpts("mug"),
...prompt.regexpOpts("mu"),
value: lastSearchInput?.source,
}, (input, selections) => {
if (typeof input === "string") {
input = new RegExp(input, "mug");
input = new RegExp(input, "mu");
}
lastSearchInput = input;

View File

@ -1656,6 +1656,8 @@ export function splitRange(text: string, re: RegExp) {
const sections: [start: number, end: number][] = [];
for (let start = 0;;) {
re.lastIndex = 0;
const match = re.exec(text);
if (match === null || text.length === 0) {
@ -1673,8 +1675,6 @@ export function splitRange(text: string, re: RegExp) {
text = text.slice(match.index + match[0].length);
start += match.index + match[0].length;
}
re.lastIndex = 0;
}
}
@ -1683,6 +1683,8 @@ export function splitRange(text: string, re: RegExp) {
* indices corresponding to each matched result.
*/
export function execRange(text: string, re: RegExp) {
re.lastIndex = 0;
const sections: [start: number, end: number, match: RegExpExecArray][] = [];
let diff = 0;
@ -1694,6 +1696,7 @@ export function execRange(text: string, re: RegExp) {
text = text.slice(end);
diff += end;
re.lastIndex = 0;
if (start === end) {
text = text.slice(1);

View File

@ -1009,6 +1009,31 @@ suite("API tests", function () {
// No expected end document.
});
test("function selectWithinSelections", async function () {
const editorState = extension.editors.getState(editor)!,
context = new Context(editorState, cancellationToken),
before = ExpectedDocument.parseIndented(14, String.raw`
a1b2c3d4
^^^^^ 0
e5f6g7h8
^^^^^^ 1
`);
await before.apply(editor);
await context.runAsync(async () => {
expect(Selections.selectWithin(/\d/).map(text), "to equal", [
"1",
"2",
"6",
"7",
"8",
]);
});
// No expected end document.
});
test("function mergeOverlappingSelections", async function () {
const editorState = extension.editors.getState(editor)!,
context = new Context(editorState, cancellationToken),