mirror of
https://github.com/Microsoft/vscode
synced 2024-09-13 21:55:38 +00:00
Fix #62980
This commit is contained in:
parent
c8cbfdad24
commit
6ef7e81ec0
|
@ -33,26 +33,26 @@ export class Match {
|
|||
|
||||
private _id: string;
|
||||
private _range: Range;
|
||||
private _previewText: string;
|
||||
private _rangeInPreviewText: Range;
|
||||
private _oneLinePreviewText: string;
|
||||
private _rangeInPreviewText: ISearchRange;
|
||||
|
||||
constructor(private _parent: FileMatch, _result: ITextSearchMatch) {
|
||||
if (Array.isArray(_result.ranges) || Array.isArray(_result.preview.matches)) {
|
||||
throw new Error('A Match can only be built from a single search result');
|
||||
}
|
||||
// For replace
|
||||
private _fullPreviewRange: ISearchRange;
|
||||
|
||||
constructor(private _parent: FileMatch, private _fullPreviewLines: string[], _fullPreviewRange: ISearchRange, _documentRange: ISearchRange) {
|
||||
this._oneLinePreviewText = _fullPreviewLines[_fullPreviewRange.startLineNumber];
|
||||
const adjustedEndCol = _fullPreviewRange.startLineNumber === _fullPreviewRange.endLineNumber ?
|
||||
_fullPreviewRange.endColumn :
|
||||
this._oneLinePreviewText.length;
|
||||
this._rangeInPreviewText = new OneLineRange(1, _fullPreviewRange.startColumn + 1, adjustedEndCol + 1);
|
||||
|
||||
this._range = new Range(
|
||||
_result.ranges.startLineNumber + 1,
|
||||
_result.ranges.startColumn + 1,
|
||||
_result.ranges.endLineNumber + 1,
|
||||
_result.ranges.endColumn + 1);
|
||||
_documentRange.startLineNumber + 1,
|
||||
_documentRange.startColumn + 1,
|
||||
_documentRange.endLineNumber + 1,
|
||||
_documentRange.endColumn + 1);
|
||||
|
||||
this._rangeInPreviewText = new Range(
|
||||
_result.preview.matches.startLineNumber + 1,
|
||||
_result.preview.matches.startColumn + 1,
|
||||
_result.preview.matches.endLineNumber + 1,
|
||||
_result.preview.matches.endColumn + 1);
|
||||
this._previewText = _result.preview.text;
|
||||
this._fullPreviewRange = _fullPreviewRange;
|
||||
|
||||
this._id = this._parent.id() + '>' + this._range + this.getMatchString();
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ export class Match {
|
|||
}
|
||||
|
||||
public text(): string {
|
||||
return this._previewText;
|
||||
return this._oneLinePreviewText;
|
||||
}
|
||||
|
||||
public range(): Range {
|
||||
|
@ -74,9 +74,9 @@ export class Match {
|
|||
}
|
||||
|
||||
public preview(): { before: string; inside: string; after: string; } {
|
||||
let before = this._previewText.substring(0, this._rangeInPreviewText.startColumn - 1),
|
||||
let before = this._oneLinePreviewText.substring(0, this._rangeInPreviewText.startColumn - 1),
|
||||
inside = this.getMatchString(),
|
||||
after = this._previewText.substring(this._rangeInPreviewText.endColumn - 1);
|
||||
after = this._oneLinePreviewText.substring(this._rangeInPreviewText.endColumn - 1);
|
||||
|
||||
before = lcut(before, 26);
|
||||
|
||||
|
@ -93,13 +93,15 @@ export class Match {
|
|||
}
|
||||
|
||||
public get replaceString(): string {
|
||||
let searchModel = this.parent().parent().searchModel;
|
||||
let matchString = this.getMatchString();
|
||||
let replaceString = searchModel.replacePattern.getReplaceString(matchString);
|
||||
const searchModel = this.parent().parent().searchModel;
|
||||
|
||||
const fullMatchText = this.getFullMatchText();
|
||||
let replaceString = searchModel.replacePattern.getReplaceString(fullMatchText);
|
||||
|
||||
// If match string is not matching then regex pattern has a lookahead expression
|
||||
if (replaceString === null) {
|
||||
replaceString = searchModel.replacePattern.getReplaceString(matchString + this._previewText.substring(this._rangeInPreviewText.endColumn - 1));
|
||||
const fullMatchTextWithTrailingContent = this.getFullMatchText(true);
|
||||
replaceString = searchModel.replacePattern.getReplaceString(fullMatchTextWithTrailingContent);
|
||||
}
|
||||
|
||||
// Match string is still not matching. Could be unsupported matches (multi-line).
|
||||
|
@ -110,8 +112,22 @@ export class Match {
|
|||
return replaceString;
|
||||
}
|
||||
|
||||
private getFullMatchText(includeTrailing = false): string {
|
||||
let thisMatchPreviewLines: string[];
|
||||
if (includeTrailing) {
|
||||
thisMatchPreviewLines = this._fullPreviewLines.slice(this._fullPreviewRange.startLineNumber);
|
||||
} else {
|
||||
thisMatchPreviewLines = this._fullPreviewLines.slice(this._fullPreviewRange.startLineNumber, this._fullPreviewRange.endLineNumber + 1);
|
||||
thisMatchPreviewLines[thisMatchPreviewLines.length - 1] = thisMatchPreviewLines[thisMatchPreviewLines.length - 1].slice(0, this._fullPreviewRange.endColumn);
|
||||
|
||||
}
|
||||
|
||||
thisMatchPreviewLines[0] = thisMatchPreviewLines[0].slice(this._fullPreviewRange.startColumn);
|
||||
return thisMatchPreviewLines.join('\n');
|
||||
}
|
||||
|
||||
public getMatchString(): string {
|
||||
return this._previewText.substring(this._rangeInPreviewText.startColumn - 1, this._rangeInPreviewText.endColumn - 1);
|
||||
return this._oneLinePreviewText.substring(this._rangeInPreviewText.startColumn - 1, this._rangeInPreviewText.endColumn - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1021,45 +1037,15 @@ export class RangeHighlightDecorations implements IDisposable {
|
|||
}
|
||||
|
||||
function textSearchResultToMatches(rawMatch: ITextSearchMatch, fileMatch: FileMatch): Match[] {
|
||||
const previewLines = rawMatch.preview.text.split('\n');
|
||||
if (Array.isArray(rawMatch.ranges)) {
|
||||
const previewLines = rawMatch.preview.text.split('\n');
|
||||
return rawMatch.ranges.map((r, i) => {
|
||||
const previewRange: ISearchRange = rawMatch.preview.matches[i];
|
||||
const matchText = previewLines[previewRange.startLineNumber];
|
||||
const adjustedEndCol = previewRange.startLineNumber === previewRange.endLineNumber ?
|
||||
previewRange.endColumn :
|
||||
matchText.length;
|
||||
const adjustedRange = new OneLineRange(0, previewRange.startColumn, adjustedEndCol);
|
||||
|
||||
return new Match(fileMatch, {
|
||||
uri: rawMatch.uri,
|
||||
ranges: r,
|
||||
preview: {
|
||||
text: matchText,
|
||||
matches: adjustedRange
|
||||
}
|
||||
});
|
||||
return new Match(fileMatch, previewLines, previewRange, r);
|
||||
});
|
||||
} else {
|
||||
const firstNewlineIdx = rawMatch.preview.text.indexOf('\n');
|
||||
const matchText = firstNewlineIdx >= 0 ?
|
||||
rawMatch.preview.text.slice(0, firstNewlineIdx) :
|
||||
rawMatch.preview.text;
|
||||
const previewRange = <ISearchRange>rawMatch.preview.matches;
|
||||
const adjustedEndCol = previewRange.startLineNumber === previewRange.endLineNumber ?
|
||||
previewRange.endColumn :
|
||||
matchText.length;
|
||||
const adjustedRange = new OneLineRange(0, previewRange.startColumn, adjustedEndCol);
|
||||
|
||||
const adjustedMatch: ITextSearchMatch = {
|
||||
preview: {
|
||||
text: matchText,
|
||||
matches: adjustedRange
|
||||
},
|
||||
ranges: rawMatch.ranges
|
||||
};
|
||||
|
||||
let match = new Match(fileMatch, adjustedMatch);
|
||||
let match = new Match(fileMatch, previewLines, previewRange, rawMatch.ranges);
|
||||
return [match];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,19 +134,22 @@ suite('Search Actions', () => {
|
|||
|
||||
function aMatch(fileMatch: FileMatch): Match {
|
||||
const line = ++counter;
|
||||
const ranges = {
|
||||
startLineNumber: line,
|
||||
startColumn: 0,
|
||||
endLineNumber: line,
|
||||
endColumn: 2
|
||||
};
|
||||
let match = new Match(fileMatch, {
|
||||
preview: {
|
||||
text: 'some match',
|
||||
matches: ranges
|
||||
let match = new Match(
|
||||
fileMatch,
|
||||
['some match'],
|
||||
{
|
||||
startLineNumber: 0,
|
||||
startColumn: 0,
|
||||
endLineNumber: 0,
|
||||
endColumn: 2
|
||||
},
|
||||
ranges
|
||||
});
|
||||
{
|
||||
startLineNumber: line,
|
||||
startColumn: 0,
|
||||
endLineNumber: line,
|
||||
endColumn: 2
|
||||
}
|
||||
);
|
||||
fileMatch.add(match);
|
||||
return match;
|
||||
}
|
||||
|
|
|
@ -4,17 +4,17 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as assert from 'assert';
|
||||
import { URI as uri } from 'vs/base/common/uri';
|
||||
import { Match, FileMatch, SearchResult } from 'vs/workbench/parts/search/common/searchModel';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { SearchDataSource, SearchSorter } from 'vs/workbench/parts/search/browser/searchResultsView';
|
||||
import { IFileMatch, TextSearchMatch, OneLineRange, ITextSearchMatch, QueryType } from 'vs/platform/search/common/search';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { IFileMatch, ITextSearchMatch, OneLineRange, QueryType } from 'vs/platform/search/common/search';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { TestContextService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
|
||||
import { SearchDataSource, SearchSorter } from 'vs/workbench/parts/search/browser/searchResultsView';
|
||||
import { FileMatch, Match, SearchResult } from 'vs/workbench/parts/search/common/searchModel';
|
||||
import { TestContextService } from 'vs/workbench/test/workbenchTestServices';
|
||||
|
||||
suite('Search - Viewlet', () => {
|
||||
let instantiation: TestInstantiationService;
|
||||
|
@ -36,20 +36,24 @@ suite('Search - Viewlet', () => {
|
|||
}]
|
||||
};
|
||||
|
||||
const ranges = {
|
||||
startLineNumber: 1,
|
||||
startColumn: 0,
|
||||
endLineNumber: 1,
|
||||
endColumn: 1
|
||||
};
|
||||
result.add([{
|
||||
resource: uri.parse('file:///c:/foo'),
|
||||
results: [{
|
||||
preview: {
|
||||
text: 'bar',
|
||||
matches: ranges
|
||||
matches: {
|
||||
startLineNumber: 0,
|
||||
startColumn: 0,
|
||||
endLineNumber: 0,
|
||||
endColumn: 1
|
||||
}
|
||||
},
|
||||
ranges
|
||||
ranges: {
|
||||
startLineNumber: 1,
|
||||
startColumn: 0,
|
||||
endLineNumber: 1,
|
||||
endColumn: 1
|
||||
}
|
||||
}]
|
||||
}]);
|
||||
|
||||
|
@ -70,9 +74,9 @@ suite('Search - Viewlet', () => {
|
|||
let fileMatch1 = aFileMatch('C:\\foo');
|
||||
let fileMatch2 = aFileMatch('C:\\with\\path');
|
||||
let fileMatch3 = aFileMatch('C:\\with\\path\\foo');
|
||||
let lineMatch1 = new Match(fileMatch1, new TextSearchMatch('bar', new OneLineRange(0, 1, 1)));
|
||||
let lineMatch2 = new Match(fileMatch1, new TextSearchMatch('bar', new OneLineRange(2, 1, 1)));
|
||||
let lineMatch3 = new Match(fileMatch1, new TextSearchMatch('bar', new OneLineRange(2, 1, 1)));
|
||||
let lineMatch1 = new Match(fileMatch1, ['bar'], new OneLineRange(0, 1, 1), new OneLineRange(0, 1, 1));
|
||||
let lineMatch2 = new Match(fileMatch1, ['bar'], new OneLineRange(0, 1, 1), new OneLineRange(2, 1, 1));
|
||||
let lineMatch3 = new Match(fileMatch1, ['bar'], new OneLineRange(0, 1, 1), new OneLineRange(2, 1, 1));
|
||||
|
||||
let s = new SearchSorter();
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ suite('SearchResult', () => {
|
|||
|
||||
test('Line Match', function () {
|
||||
let fileMatch = aFileMatch('folder/file.txt', null);
|
||||
let lineMatch = new Match(fileMatch, new TextSearchMatch('foo bar', new OneLineRange(1, 0, 3)));
|
||||
let lineMatch = new Match(fileMatch, ['foo bar'], new OneLineRange(0, 0, 3), new OneLineRange(1, 0, 3));
|
||||
assert.equal(lineMatch.text(), 'foo bar');
|
||||
assert.equal(lineMatch.range().startLineNumber, 2);
|
||||
assert.equal(lineMatch.range().endLineNumber, 2);
|
||||
|
@ -134,7 +134,7 @@ suite('SearchResult', () => {
|
|||
test('Alle Drei Zusammen', function () {
|
||||
let searchResult = instantiationService.createInstance(SearchResult, null);
|
||||
let fileMatch = aFileMatch('far/boo', searchResult);
|
||||
let lineMatch = new Match(fileMatch, new TextSearchMatch('foo bar', new OneLineRange(1, 0, 3)));
|
||||
let lineMatch = new Match(fileMatch, ['foo bar'], new OneLineRange(0, 0, 3), new OneLineRange(1, 0, 3));
|
||||
|
||||
assert(lineMatch.parent() === fileMatch);
|
||||
assert(fileMatch.parent() === searchResult);
|
||||
|
|
|
@ -12,8 +12,7 @@ function editorMatchToTextSearchResult(matches: FindMatch[], model: ITextModel,
|
|||
const lastLine = matches[matches.length - 1].range.endLineNumber;
|
||||
|
||||
const lineTexts: string[] = [];
|
||||
const numLines = (previewOptions && matches.length === 1) ? previewOptions.matchLines : Number.MAX_VALUE;
|
||||
for (let i = firstLine; i <= lastLine && (i - firstLine) < numLines; i++) {
|
||||
for (let i = firstLine; i <= lastLine; i++) {
|
||||
lineTexts.push(model.getLineContent(i));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue