From c6b3f39c631d4e8a8101f7ae106e94c1bfaae1cf Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 6 Sep 2016 14:46:09 +0200 Subject: [PATCH] fix #11572 --- .vscode/launch.json | 4 +- src/vs/base/common/strings.ts | 18 +- src/vs/editor/common/model/textModel.ts | 47 ++--- .../common/modes/supports/richEditBrackets.ts | 2 +- src/vs/editor/test/common/model/model.test.ts | 197 ++++++++++++++++-- .../test/common/model/textModel.test.ts | 80 ------- src/vs/platform/search/common/replace.ts | 2 +- .../services/search/node/textSearch.ts | 2 +- 8 files changed, 219 insertions(+), 133 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index df5aedd1c04c8..ec6f15691b9a2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,9 @@ "stopOnEntry": false, "args": [ "--timeout", - "999999" + "999999", + "-g", + "Editor Model - Find" ], "cwd": "${workspaceRoot}", "runtimeArgs": [], diff --git a/src/vs/base/common/strings.ts b/src/vs/base/common/strings.ts index 9b392e320108e..c20ff1172a8cc 100644 --- a/src/vs/base/common/strings.ts +++ b/src/vs/base/common/strings.ts @@ -174,14 +174,21 @@ export function endsWith(haystack: string, needle: string): boolean { } } -export function createRegExp(searchString: string, isRegex: boolean, matchCase: boolean, wholeWord: boolean, global:boolean): RegExp { +export interface RegExpOptions { + matchCase?: boolean; + wholeWord?: boolean; + multiline?: boolean; + global?: boolean; +} + +export function createRegExp(searchString: string, isRegex: boolean, options: RegExpOptions = {}): RegExp { if (searchString === '') { throw new Error('Cannot create regex from empty string'); } if (!isRegex) { searchString = searchString.replace(/[\-\\\{\}\*\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&'); } - if (wholeWord) { + if (options.wholeWord) { if (!/\B/.test(searchString.charAt(0))) { searchString = '\\b' + searchString; } @@ -190,12 +197,15 @@ export function createRegExp(searchString: string, isRegex: boolean, matchCase: } } let modifiers = ''; - if (global) { + if (options.global) { modifiers += 'g'; } - if (!matchCase) { + if (!options.matchCase) { modifiers += 'i'; } + if (options.multiline) { + modifiers += 'm'; + } return new RegExp(searchString, modifiers); } diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index c46c8d3b50d00..a33910ffd4468 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -18,11 +18,6 @@ import {IndentRange, computeRanges} from 'vs/editor/common/model/indentRanges'; const LIMIT_FIND_COUNT = 999; export const LONG_LINE_BOUNDARY = 1000; -export interface IParsedSearchRequest { - regex: RegExp; - isMultiline: boolean; -} - export class TextModel extends OrderGuaranteeEventEmitter implements editorCommon.ITextModel { private static MODEL_SYNC_LIMIT = 5 * 1024 * 1024; // 5 MB private static MODEL_TOKENIZATION_LIMIT = 20 * 1024 * 1024; // 20 MB @@ -764,15 +759,16 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo return false; } - public static parseSearchRequest(searchString:string, isRegex:boolean, matchCase:boolean, wholeWord:boolean): IParsedSearchRequest { + public static parseSearchRequest(searchString:string, isRegex:boolean, matchCase:boolean, wholeWord:boolean): RegExp { if (searchString === '') { return null; } // Try to create a RegExp out of the params - var regex:RegExp = null; + var regex: RegExp = null; + var multiline = isRegex && TextModel._isMultiline(searchString); try { - regex = strings.createRegExp(searchString, isRegex, matchCase, wholeWord, true); + regex = strings.createRegExp(searchString, isRegex, {matchCase, wholeWord, multiline, global: true}); } catch (err) { return null; } @@ -781,15 +777,12 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo return null; } - return { - regex: regex, - isMultiline: isRegex && TextModel._isMultiline(searchString) - }; + return regex; } public findMatches(searchString:string, rawSearchScope:any, isRegex:boolean, matchCase:boolean, wholeWord:boolean, limitResultCount:number = LIMIT_FIND_COUNT): Range[] { - let r = TextModel.parseSearchRequest(searchString, isRegex, matchCase, wholeWord); - if (!r) { + let regex = TextModel.parseSearchRequest(searchString, isRegex, matchCase, wholeWord); + if (!regex) { return []; } @@ -800,10 +793,10 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo searchRange = this.getFullModelRange(); } - if (r.isMultiline) { - return this._doFindMatchesMultiline(searchRange, r.regex, limitResultCount); + if (regex.multiline) { + return this._doFindMatchesMultiline(searchRange, regex, limitResultCount); } - return this._doFindMatchesLineByLine(searchRange, r.regex, limitResultCount); + return this._doFindMatchesLineByLine(searchRange, regex, limitResultCount); } private _doFindMatchesMultiline(searchRange:Range, searchRegex:RegExp, limitResultCount:number): Range[] { @@ -871,16 +864,16 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo } public findNextMatch(searchString:string, rawSearchStart:editorCommon.IPosition, isRegex:boolean, matchCase:boolean, wholeWord:boolean): Range { - let r = TextModel.parseSearchRequest(searchString, isRegex, matchCase, wholeWord); - if (!r) { + let regex = TextModel.parseSearchRequest(searchString, isRegex, matchCase, wholeWord); + if (!regex) { return null; } let searchStart = this.validatePosition(rawSearchStart); - if (r.isMultiline) { - return this._doFindNextMatchMultiline(searchStart, r.regex); + if (regex.multiline) { + return this._doFindNextMatchMultiline(searchStart, regex); } - return this._doFindNextMatchLineByLine(searchStart, r.regex); + return this._doFindNextMatchLineByLine(searchStart, regex); } @@ -932,16 +925,16 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo } public findPreviousMatch(searchString:string, rawSearchStart:editorCommon.IPosition, isRegex:boolean, matchCase:boolean, wholeWord:boolean): Range { - let r = TextModel.parseSearchRequest(searchString, isRegex, matchCase, wholeWord); - if (!r) { + let regex = TextModel.parseSearchRequest(searchString, isRegex, matchCase, wholeWord); + if (!regex) { return null; } let searchStart = this.validatePosition(rawSearchStart); - if (r.isMultiline) { - return this._doFindPreviousMatchMultiline(searchStart, r.regex); + if (regex.multiline) { + return this._doFindPreviousMatchMultiline(searchStart, regex); } - return this._doFindPreviousMatchLineByLine(searchStart, r.regex); + return this._doFindPreviousMatchLineByLine(searchStart, regex); } private _doFindPreviousMatchMultiline(searchStart:Position, searchRegex:RegExp): Range { diff --git a/src/vs/editor/common/modes/supports/richEditBrackets.ts b/src/vs/editor/common/modes/supports/richEditBrackets.ts index 22210f681a735..1c671c8069b08 100644 --- a/src/vs/editor/common/modes/supports/richEditBrackets.ts +++ b/src/vs/editor/common/modes/supports/richEditBrackets.ts @@ -101,7 +101,7 @@ var getReversedRegexForBrackets = once( function createOrRegex(pieces:string[]): RegExp { let regexStr = `(${pieces.map(strings.escapeRegExpCharacters).join(')|(')})`; - return strings.createRegExp(regexStr, true, false, false, false); + return strings.createRegExp(regexStr, true); } function toReversedString(str:string): string { diff --git a/src/vs/editor/test/common/model/model.test.ts b/src/vs/editor/test/common/model/model.test.ts index 407a9bfe62b4f..6d8a71007eb6b 100644 --- a/src/vs/editor/test/common/model/model.test.ts +++ b/src/vs/editor/test/common/model/model.test.ts @@ -13,7 +13,7 @@ import { IModelContentChangedLinesDeletedEvent, IModelContentChangedLinesInsertedEvent } from 'vs/editor/common/editorCommon'; import {Model} from 'vs/editor/common/model/model'; -import {TextModel, IParsedSearchRequest} from 'vs/editor/common/model/textModel'; +import {TextModel} from 'vs/editor/common/model/textModel'; // --------- utils @@ -599,6 +599,77 @@ suite('Editor Model - Find', () => { ); }); + test('multiline find with line beginning regex', () => { + assertFindMatches( + [ + 'if', + 'else', + '', + 'if', + 'else' + ].join('\n'), + '^if\\nelse', true, false, false, + [ + [1, 1, 2, 5], + [4, 1, 5, 5] + ] + ); + }); + + test('matching empty lines using boundary expression', () => { + assertFindMatches( + [ + 'if', + '', + 'else', + ' ', + 'if', + ' ', + 'else' + ].join('\n'), + '^\\s*$\\n', true, false, false, + [ + [2, 1, 3, 1], + [4, 1, 5, 1], + [6, 1, 7, 1] + ] + ); + }); + + test('matching lines starting with A and ending with B', () => { + assertFindMatches( + [ + 'a if b', + 'a', + 'ab', + 'eb' + ].join('\n'), + '^a.*b$', true, false, false, + [ + [1, 1, 1, 7], + [3, 1, 3, 3] + ] + ); + }); + + test('multiline find with line ending regex', () => { + assertFindMatches( + [ + 'if', + 'else', + '', + 'if', + 'elseif', + 'else' + ].join('\n'), + 'if\\nelse$', true, false, false, + [ + [1, 1, 2, 5], + [5, 5, 6, 5] + ] + ); + }); + test('issue #4836 - ^.*$', () => { assertFindMatches( [ @@ -619,7 +690,97 @@ suite('Editor Model - Find', () => { ); }); - function assertParseSearchResult(searchString:string, isRegex:boolean, matchCase:boolean, wholeWord:boolean, expected:IParsedSearchRequest): void { + test('findNextMatch without regex', () => { + var testObject = new TextModel([], TextModel.toRawText('line line one\nline two\nthree', TextModel.DEFAULT_CREATION_OPTIONS)); + + let actual = testObject.findNextMatch('line', { lineNumber: 1, column: 1 }, false, false, false); + assert.equal(new Range(1, 1, 1, 5).toString(), actual.toString()); + + actual = testObject.findNextMatch('line', actual.getEndPosition(), false, false, false); + assert.equal(new Range(1, 6, 1, 10).toString(), actual.toString()); + + actual = testObject.findNextMatch('line', {lineNumber: 1, column: 3}, false, false, false); + assert.equal(new Range(1, 6, 1, 10).toString(), actual.toString()); + + actual = testObject.findNextMatch('line', actual.getEndPosition(), false, false, false); + assert.equal(new Range(2, 1, 2, 5).toString(), actual.toString()); + + actual = testObject.findNextMatch('line', actual.getEndPosition(), false, false, false); + assert.equal(new Range(1, 1, 1, 5).toString(), actual.toString()); + + testObject.dispose(); + }); + + test('findNextMatch with beginning boundary regex', () => { + var testObject = new TextModel([], TextModel.toRawText('line one\nline two\nthree', TextModel.DEFAULT_CREATION_OPTIONS)); + + let actual = testObject.findNextMatch('^line', { lineNumber: 1, column: 1 }, true, false, false); + assert.equal(new Range(1, 1, 1, 5).toString(), actual.toString()); + + actual = testObject.findNextMatch('^line', actual.getEndPosition(), true, false, false); + assert.equal(new Range(2, 1, 2, 5).toString(), actual.toString()); + + actual = testObject.findNextMatch('^line', { lineNumber: 1, column: 3 }, true, false, false); + assert.equal(new Range(2, 1, 2, 5).toString(), actual.toString()); + + actual = testObject.findNextMatch('^line', actual.getEndPosition(), true, false, false); + assert.equal(new Range(1, 1, 1, 5).toString(), actual.toString()); + + testObject.dispose(); + }); + + test('findNextMatch with beginning boundary regex and line has repetitive beginnings', () => { + var testObject = new TextModel([], TextModel.toRawText('line line one\nline two\nthree', TextModel.DEFAULT_CREATION_OPTIONS)); + + let actual = testObject.findNextMatch('^line', { lineNumber: 1, column: 1 }, true, false, false); + assert.equal(new Range(1, 1, 1, 5).toString(), actual.toString()); + + actual = testObject.findNextMatch('^line', actual.getEndPosition(), true, false, false); + assert.equal(new Range(2, 1, 2, 5).toString(), actual.toString()); + + actual = testObject.findNextMatch('^line', { lineNumber: 1, column: 3 }, true, false, false); + assert.equal(new Range(2, 1, 2, 5).toString(), actual.toString()); + + actual = testObject.findNextMatch('^line', actual.getEndPosition(), true, false, false); + assert.equal(new Range(1, 1, 1, 5).toString(), actual.toString()); + + testObject.dispose(); + }); + + test('findNextMatch with beginning boundary multiline regex and line has repetitive beginnings', () => { + var testObject = new TextModel([], TextModel.toRawText('line line one\nline two\nline three\nline four', TextModel.DEFAULT_CREATION_OPTIONS)); + + let actual = testObject.findNextMatch('^line.*\\nline', { lineNumber: 1, column: 1 }, true, false, false); + assert.equal(new Range(1, 1, 2, 5).toString(), actual.toString()); + + actual = testObject.findNextMatch('^line.*\\nline', actual.getEndPosition(), true, false, false); + assert.equal(new Range(3, 1, 4, 5).toString(), actual.toString()); + + actual = testObject.findNextMatch('^line.*\\nline', { lineNumber: 2, column: 1 }, true, false, false); + assert.equal(new Range(2, 1, 3, 5).toString(), actual.toString()); + + testObject.dispose(); + }); + + test('findNextMatch with ending boundary regex', () => { + var testObject = new TextModel([], TextModel.toRawText('one line line\ntwo line\nthree', TextModel.DEFAULT_CREATION_OPTIONS)); + + let actual = testObject.findNextMatch('line$', { lineNumber: 1, column: 1 }, true, false, false); + assert.equal(new Range(1, 10, 1, 14).toString(), actual.toString()); + + actual = testObject.findNextMatch('line$', { lineNumber: 1, column: 4 }, true, false, false); + assert.equal(new Range(1, 10, 1, 14).toString(), actual.toString()); + + actual = testObject.findNextMatch('line$', actual.getEndPosition(), true, false, false); + assert.equal(new Range(2, 5, 2, 9).toString(), actual.toString()); + + actual = testObject.findNextMatch('line$', actual.getEndPosition(), true, false, false); + assert.equal(new Range(1, 10, 1, 14).toString(), actual.toString()); + + testObject.dispose(); + }); + + function assertParseSearchResult(searchString:string, isRegex:boolean, matchCase:boolean, wholeWord:boolean, expected:RegExp): void { let actual = TextModel.parseSearchRequest(searchString, isRegex, matchCase, wholeWord); assert.deepEqual(actual, expected); } @@ -631,24 +792,24 @@ suite('Editor Model - Find', () => { }); test('parseSearchRequest non regex', () => { - assertParseSearchResult('foo', false, false, false, { regex: /foo/gi, isMultiline: false }); - assertParseSearchResult('foo', false, false, true, { regex: /\bfoo\b/gi, isMultiline: false }); - assertParseSearchResult('foo', false, true, false, { regex: /foo/g, isMultiline: false }); - assertParseSearchResult('foo', false, true, true, { regex: /\bfoo\b/g, isMultiline: false }); - assertParseSearchResult('foo\\n', false, false, false, { regex: /foo\\n/gi, isMultiline: false }); - assertParseSearchResult('foo\\\\n', false, false, false, { regex: /foo\\\\n/gi, isMultiline: false }); - assertParseSearchResult('foo\\r', false, false, false, { regex: /foo\\r/gi, isMultiline: false }); - assertParseSearchResult('foo\\\\r', false, false, false, { regex: /foo\\\\r/gi, isMultiline: false }); + assertParseSearchResult('foo', false, false, false, /foo/gi); + assertParseSearchResult('foo', false, false, true, /\bfoo\b/gi); + assertParseSearchResult('foo', false, true, false, /foo/g); + assertParseSearchResult('foo', false, true, true, /\bfoo\b/g); + assertParseSearchResult('foo\\n', false, false, false, /foo\\n/gi); + assertParseSearchResult('foo\\\\n', false, false, false, /foo\\\\n/gi); + assertParseSearchResult('foo\\r', false, false, false, /foo\\r/gi); + assertParseSearchResult('foo\\\\r', false, false, false, /foo\\\\r/gi); }); test('parseSearchRequest regex', () => { - assertParseSearchResult('foo', true, false, false, { regex: /foo/gi, isMultiline: false }); - assertParseSearchResult('foo', true, false, true, { regex: /\bfoo\b/gi, isMultiline: false }); - assertParseSearchResult('foo', true, true, false, { regex: /foo/g, isMultiline: false }); - assertParseSearchResult('foo', true, true, true, { regex: /\bfoo\b/g, isMultiline: false }); - assertParseSearchResult('foo\\n', true, false, false, { regex: /foo\n/gi, isMultiline: true }); - assertParseSearchResult('foo\\\\n', true, false, false, { regex: /foo\\n/gi, isMultiline: false }); - assertParseSearchResult('foo\\r', true, false, false, { regex: /foo\r/gi, isMultiline: true }); - assertParseSearchResult('foo\\\\r', true, false, false, { regex: /foo\\r/gi, isMultiline: false }); + assertParseSearchResult('foo', true, false, false, /foo/gi); + assertParseSearchResult('foo', true, false, true, /\bfoo\b/gi); + assertParseSearchResult('foo', true, true, false, /foo/g); + assertParseSearchResult('foo', true, true, true, /\bfoo\b/g); + assertParseSearchResult('foo\\n', true, false, false, /foo\n/gim); + assertParseSearchResult('foo\\\\n', true, false, false, /foo\\n/gi); + assertParseSearchResult('foo\\r', true, false, false, /foo\r/gim); + assertParseSearchResult('foo\\\\r', true, false, false, /foo\\r/gi); }); }); diff --git a/src/vs/editor/test/common/model/textModel.test.ts b/src/vs/editor/test/common/model/textModel.test.ts index 239299c8b51cb..7ee2e6ea4bbb1 100644 --- a/src/vs/editor/test/common/model/textModel.test.ts +++ b/src/vs/editor/test/common/model/textModel.test.ts @@ -555,86 +555,6 @@ suite('Editor Model - TextModel', () => { model.dispose(); }); - - test('findNextMatch without regex', () => { - var testObject = new TextModel([], TextModel.toRawText('line line one\nline two\nthree', TextModel.DEFAULT_CREATION_OPTIONS)); - - let actual = testObject.findNextMatch('line', { lineNumber: 1, column: 1 }, false, false, false); - assert.equal(new Range(1, 1, 1, 5).toString(), actual.toString()); - - actual = testObject.findNextMatch('line', actual.getEndPosition(), false, false, false); - assert.equal(new Range(1, 6, 1, 10).toString(), actual.toString()); - - actual = testObject.findNextMatch('line', {lineNumber: 1, column: 3}, false, false, false); - assert.equal(new Range(1, 6, 1, 10).toString(), actual.toString()); - - actual = testObject.findNextMatch('line', actual.getEndPosition(), false, false, false); - assert.equal(new Range(2, 1, 2, 5).toString(), actual.toString()); - - actual = testObject.findNextMatch('line', actual.getEndPosition(), false, false, false); - assert.equal(new Range(1, 1, 1, 5).toString(), actual.toString()); - }); - - test('findNextMatch with beginning boundary regex', () => { - var testObject = new TextModel([], TextModel.toRawText('line one\nline two\nthree', TextModel.DEFAULT_CREATION_OPTIONS)); - - let actual = testObject.findNextMatch('^line', { lineNumber: 1, column: 1 }, true, false, false); - assert.equal(new Range(1, 1, 1, 5).toString(), actual.toString()); - - actual = testObject.findNextMatch('^line', actual.getEndPosition(), true, false, false); - assert.equal(new Range(2, 1, 2, 5).toString(), actual.toString()); - - actual = testObject.findNextMatch('^line', { lineNumber: 1, column: 3 }, true, false, false); - assert.equal(new Range(2, 1, 2, 5).toString(), actual.toString()); - - actual = testObject.findNextMatch('^line', actual.getEndPosition(), true, false, false); - assert.equal(new Range(1, 1, 1, 5).toString(), actual.toString()); - }); - - test('findNextMatch with beginning boundary regex and line has repetitive beginnings', () => { - var testObject = new TextModel([], TextModel.toRawText('line line one\nline two\nthree', TextModel.DEFAULT_CREATION_OPTIONS)); - - let actual = testObject.findNextMatch('^line', { lineNumber: 1, column: 1 }, true, false, false); - assert.equal(new Range(1, 1, 1, 5).toString(), actual.toString()); - - actual = testObject.findNextMatch('^line', actual.getEndPosition(), true, false, false); - assert.equal(new Range(2, 1, 2, 5).toString(), actual.toString()); - - actual = testObject.findNextMatch('^line', { lineNumber: 1, column: 3 }, true, false, false); - assert.equal(new Range(2, 1, 2, 5).toString(), actual.toString()); - - actual = testObject.findNextMatch('^line', actual.getEndPosition(), true, false, false); - assert.equal(new Range(1, 1, 1, 5).toString(), actual.toString()); - }); - - test('findNextMatch with beginning boundary multiline regex and line has repetitive beginnings', () => { - var testObject = new TextModel([], TextModel.toRawText('line line one\nline two\nline three', TextModel.DEFAULT_CREATION_OPTIONS)); - - let actual = testObject.findNextMatch('^line.*\\nline', { lineNumber: 1, column: 1 }, true, false, false); - assert.equal(new Range(1, 1, 2, 5).toString(), actual.toString()); - - actual = testObject.findNextMatch('^line.*\\nline', actual.getEndPosition(), true, false, false); - assert.equal(new Range(1, 1, 2, 5).toString(), actual.toString()); - - actual = testObject.findNextMatch('^line.*\\nline', { lineNumber: 2, column: 1 }, true, false, false); - assert.equal(new Range(2, 1, 3, 5).toString(), actual.toString()); - }); - - test('findNextMatch with ending boundary regex', () => { - var testObject = new TextModel([], TextModel.toRawText('one line line\ntwo line\nthree', TextModel.DEFAULT_CREATION_OPTIONS)); - - let actual = testObject.findNextMatch('line$', { lineNumber: 1, column: 1 }, true, false, false); - assert.equal(new Range(1, 10, 1, 14).toString(), actual.toString()); - - actual = testObject.findNextMatch('line$', { lineNumber: 1, column: 4 }, true, false, false); - assert.equal(new Range(1, 10, 1, 14).toString(), actual.toString()); - - actual = testObject.findNextMatch('line$', actual.getEndPosition(), true, false, false); - assert.equal(new Range(2, 5, 2, 9).toString(), actual.toString()); - - actual = testObject.findNextMatch('line$', actual.getEndPosition(), true, false, false); - assert.equal(new Range(1, 10, 1, 14).toString(), actual.toString()); - }); }); suite('TextModel.getLineIndentGuide', () => { diff --git a/src/vs/platform/search/common/replace.ts b/src/vs/platform/search/common/replace.ts index 3ca69b60ef884..2ffa230dd0be8 100644 --- a/src/vs/platform/search/common/replace.ts +++ b/src/vs/platform/search/common/replace.ts @@ -26,7 +26,7 @@ export class ReplacePattern { constructor(private replaceString: string, private searchPatternInfo: IPatternInfo) { this._replacePattern= replaceString; if (searchPatternInfo.isRegExp) { - this._searchRegExp= strings.createRegExp(searchPatternInfo.pattern, searchPatternInfo.isRegExp, searchPatternInfo.isCaseSensitive, searchPatternInfo.isWordMatch, true); + this._searchRegExp= strings.createRegExp(searchPatternInfo.pattern, searchPatternInfo.isRegExp, {matchCase: searchPatternInfo.isCaseSensitive, wholeWord: searchPatternInfo.isWordMatch, multiline: false, global: true}); this.parseReplaceString(replaceString); } } diff --git a/src/vs/workbench/services/search/node/textSearch.ts b/src/vs/workbench/services/search/node/textSearch.ts index c2b203f52783e..b1901ab44f5cb 100644 --- a/src/vs/workbench/services/search/node/textSearch.ts +++ b/src/vs/workbench/services/search/node/textSearch.ts @@ -45,7 +45,7 @@ export class Engine implements ISearchEngine { this.rootFolders = config.rootFolders; this.extraFiles = config.extraFiles; this.walker = walker; - this.contentPattern = strings.createRegExp(config.contentPattern.pattern, config.contentPattern.isRegExp, config.contentPattern.isCaseSensitive, config.contentPattern.isWordMatch, true); + this.contentPattern = strings.createRegExp(config.contentPattern.pattern, config.contentPattern.isRegExp, {matchCase: config.contentPattern.isCaseSensitive, wholeWord: config.contentPattern.isWordMatch, multiline: false, global: true}); this.isCanceled = false; this.limitReached = false; this.maxResults = config.maxResults;