Skip to content

Commit de982ac

Browse files
Aiden Scandellajohnfn
authored andcommitted
Allow regex in / search (#627)
* Allow regex in / search * Handle invalid regexen * Update constructor * Escape backslash * Also support backwards search
1 parent c092ef5 commit de982ac

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

src/actions/actions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ export class CommandSearchForwards extends BaseCommand {
782782
isMotion = true;
783783

784784
public async exec(position: Position, vimState: VimState): Promise<VimState> {
785-
vimState.searchState = new SearchState(SearchDirection.Forward, vimState.cursorPosition);
785+
vimState.searchState = new SearchState(SearchDirection.Forward, vimState.cursorPosition, "", { isRegex: true });
786786
vimState.currentMode = ModeName.SearchInProgressMode;
787787

788788
return vimState;
@@ -796,7 +796,7 @@ export class CommandSearchBackwards extends BaseCommand {
796796
isMotion = true;
797797

798798
public async exec(position: Position, vimState: VimState): Promise<VimState> {
799-
vimState.searchState = new SearchState(SearchDirection.Backward, vimState.cursorPosition);
799+
vimState.searchState = new SearchState(SearchDirection.Backward, vimState.cursorPosition, "", { isRegex: true });
800800
vimState.currentMode = ModeName.SearchInProgressMode;
801801

802802
return vimState;

src/mode/modeHandler.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ export class SearchState {
180180

181181
private _matchesDocVersion: number;
182182
private _searchDirection: SearchDirection = SearchDirection.Forward;
183+
private isRegex: boolean;
183184

184185
private _searchString = "";
185186
public get searchString(): string {
@@ -214,7 +215,21 @@ export class SearchState {
214215
ignorecase = false;
215216
}
216217

217-
const regex = new RegExp(search.replace(SearchState.specialCharactersRegex, "\\$&"), ignorecase ? 'gi' : 'g');
218+
let searchRE = search;
219+
if (!this.isRegex) {
220+
searchRE = search.replace(SearchState.specialCharactersRegex, "\\$&");
221+
}
222+
223+
const regexFlags = ignorecase ? 'gi' : 'g';
224+
225+
let regex: RegExp;
226+
try {
227+
regex = new RegExp(searchRE, regexFlags);
228+
} catch (err) {
229+
// Couldn't compile the regexp, try again with special characters escaped
230+
searchRE = search.replace(SearchState.specialCharactersRegex, "\\$&");
231+
regex = new RegExp(searchRE, regexFlags);
232+
}
218233

219234
outer:
220235
for (let lineIdx = 0; lineIdx < TextEditor.getLineCount(); lineIdx++) {
@@ -228,7 +243,7 @@ export class SearchState {
228243

229244
this.matchRanges.push(new vscode.Range(
230245
new Position(lineIdx, result.index),
231-
new Position(lineIdx, result.index + search.length)
246+
new Position(lineIdx, result.index + result[0].length)
232247
));
233248

234249
if (result.index === regex.lastIndex) {
@@ -281,10 +296,11 @@ export class SearchState {
281296
}
282297
}
283298

284-
constructor(direction: SearchDirection, startPosition: Position, searchString = "") {
299+
constructor(direction: SearchDirection, startPosition: Position, searchString = "", { isRegex = false } = {}) {
285300
this._searchDirection = direction;
286301
this._searchCursorStartPosition = startPosition;
287302
this.searchString = searchString;
303+
this.isRegex = isRegex;
288304
}
289305
}
290306

test/mode/modeNormal.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,6 +1191,13 @@ suite("Mode Normal", () => {
11911191
end: ["|one", "twooo", "thurr"]
11921192
});
11931193

1194+
newTest({
1195+
title: "/ can search with regex",
1196+
start: ["|", "one two2o"],
1197+
keysPressed: "/o\\do",
1198+
end: ["", "one tw|o2o"]
1199+
});
1200+
11941201
newTest({
11951202
title: "Can do C",
11961203
start: ["export const options = {", "|", "};"],

0 commit comments

Comments
 (0)