提交 1926da78 编写于 作者: R Rob Lourens

#59458 for editor matches, tests

上级 9a6cd0a3
......@@ -5,7 +5,7 @@
import { Range } from 'vs/editor/common/core/range';
import { FindMatch, ITextModel } from 'vs/editor/common/model';
import { ITextSearchPreviewOptions, TextSearchMatch } from 'vs/platform/search/common/search';
import { ITextSearchPreviewOptions, TextSearchMatch, ITextSearchResult, ITextSearchMatch, ITextQuery, ITextSearchContext } from 'vs/platform/search/common/search';
function editorMatchToTextSearchResult(matches: FindMatch[], model: ITextModel, previewOptions?: ITextSearchPreviewOptions): TextSearchMatch {
const firstLine = matches[0].range.startLineNumber;
......@@ -43,4 +43,51 @@ export function editorMatchesToTextSearchResults(matches: FindMatch[], model: IT
return groupedMatches.map(sameLineMatches => {
return editorMatchToTextSearchResult(sameLineMatches, model, previewOptions);
});
}
export function addContextToEditorMatches(matches: ITextSearchMatch[], model: ITextModel, query: ITextQuery): ITextSearchResult[] {
const results: ITextSearchResult[] = [];
let prevLine = -1;
for (let i = 0; i < matches.length; i++) {
const { start: matchStartLine, end: matchEndLine } = getMatchStartEnd(matches[i]);
if (query.beforeContext > 0) {
const beforeContextStartLine = Math.max(prevLine + 1, matchStartLine - query.beforeContext);
for (let b = beforeContextStartLine; b < matchStartLine; b++) {
results.push(<ITextSearchContext>{
text: model.getLineContent(b + 1),
lineNumber: b
});
}
}
results.push(matches[i]);
const nextMatch = matches[i + 1];
let nextMatchStartLine = nextMatch ? getMatchStartEnd(nextMatch).start : Number.MAX_VALUE;
if (query.afterContext > 0) {
const afterContextToLine = Math.min(nextMatchStartLine - 1, matchEndLine + query.afterContext, model.getLineCount() - 1);
for (let a = matchEndLine + 1; a <= afterContextToLine; a++) {
results.push(<ITextSearchContext>{
text: model.getLineContent(a + 1),
lineNumber: a
});
}
}
prevLine = matchEndLine;
}
return results;
}
function getMatchStartEnd(match: ITextSearchMatch): { start: number, end: number } {
const matchRanges = match.ranges;
const matchStartLine = Array.isArray(matchRanges) ? matchRanges[0].startLineNumber : matchRanges.startLineNumber;
const matchEndLine = Array.isArray(matchRanges) ? matchRanges[matchRanges.length - 1].endLineNumber : matchRanges.endLineNumber;
return {
start: matchStartLine,
end: matchEndLine
};
}
\ No newline at end of file
......@@ -26,7 +26,7 @@ import { FileMatch, ICachedSearchStats, IFileMatch, IFileQuery, IFileSearchStats
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { editorMatchesToTextSearchResults } from 'vs/workbench/services/search/common/searchHelpers';
import { addContextToEditorMatches, editorMatchesToTextSearchResults } from 'vs/workbench/services/search/common/searchHelpers';
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { IRawSearchService, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, isSerializedSearchComplete, isSerializedSearchSuccess } from './search';
import { ISearchChannel, SearchChannelClient } from './searchIpc';
......@@ -422,7 +422,8 @@ export class SearchService extends Disposable implements ISearchService {
let fileMatch = new FileMatch(resource);
localResults.set(resource, fileMatch);
fileMatch.results = editorMatchesToTextSearchResults(matches, model, query.previewOptions);
const textSearchResults = editorMatchesToTextSearchResults(matches, model, query.previewOptions);
fileMatch.results = addContextToEditorMatches(textSearchResults, model, query);
} else {
localResults.set(resource, null);
}
......@@ -591,4 +592,3 @@ export class DiskSearch implements ISearchResultProvider {
return this.raw.clearCache(cacheKey);
}
}
......@@ -5,8 +5,9 @@
import * as assert from 'assert';
import { ITextModel, FindMatch } from 'vs/editor/common/model';
import { editorMatchesToTextSearchResults } from 'vs/workbench/services/search/common/searchHelpers';
import { editorMatchesToTextSearchResults, addContextToEditorMatches } from 'vs/workbench/services/search/common/searchHelpers';
import { Range } from 'vs/editor/common/core/range';
import { ITextQuery, QueryType, ITextSearchContext } from 'vs/platform/search/common/search';
suite('editorMatchesToTextSearchResults', () => {
const mockTextModel: ITextModel = <ITextModel>{
......@@ -50,4 +51,138 @@ suite('editorMatchesToTextSearchResults', () => {
]);
assert.equal(results[1].preview.text, '9\n10');
});
});
suite('addContextToEditorMatches', () => {
const MOCK_LINE_COUNT = 100;
const mockTextModel: ITextModel = <ITextModel>{
getLineContent(lineNumber: number): string {
if (lineNumber < 1 || lineNumber > MOCK_LINE_COUNT) {
throw new Error(`invalid line count: ${lineNumber}`);
}
return '' + lineNumber;
},
getLineCount(): number {
return MOCK_LINE_COUNT;
}
};
function getQuery(beforeContext?: number, afterContext?: number): ITextQuery {
return {
type: QueryType.Text,
contentPattern: { pattern: 'test' },
beforeContext,
afterContext
};
}
test('no context', () => {
const matches = [{
preview: {
text: 'foo',
matches: new Range(0, 0, 0, 10)
},
ranges: new Range(0, 0, 0, 10)
}];
assert.deepEqual(addContextToEditorMatches(matches, mockTextModel, getQuery()), matches);
});
test('simple', () => {
const matches = [{
preview: {
text: 'foo',
matches: new Range(0, 0, 0, 10)
},
ranges: new Range(1, 0, 1, 10)
}];
assert.deepEqual(addContextToEditorMatches(matches, mockTextModel, getQuery(1, 2)), [
<ITextSearchContext>{
text: '1',
lineNumber: 0
},
...matches,
<ITextSearchContext>{
text: '3',
lineNumber: 2
},
<ITextSearchContext>{
text: '4',
lineNumber: 3
},
]);
});
test('multiple matches next to each other', () => {
const matches = [
{
preview: {
text: 'foo',
matches: new Range(0, 0, 0, 10)
},
ranges: new Range(1, 0, 1, 10)
},
{
preview: {
text: 'bar',
matches: new Range(0, 0, 0, 10)
},
ranges: new Range(2, 0, 2, 10)
}];
assert.deepEqual(addContextToEditorMatches(matches, mockTextModel, getQuery(1, 2)), [
<ITextSearchContext>{
text: '1',
lineNumber: 0
},
...matches,
<ITextSearchContext>{
text: '4',
lineNumber: 3
},
<ITextSearchContext>{
text: '5',
lineNumber: 4
},
]);
});
test('boundaries', () => {
const matches = [
{
preview: {
text: 'foo',
matches: new Range(0, 0, 0, 10)
},
ranges: new Range(0, 0, 0, 10)
},
{
preview: {
text: 'bar',
matches: new Range(0, 0, 0, 10)
},
ranges: new Range(MOCK_LINE_COUNT - 1, 0, MOCK_LINE_COUNT - 1, 10)
}];
assert.deepEqual(addContextToEditorMatches(matches, mockTextModel, getQuery(1, 2)), [
matches[0],
<ITextSearchContext>{
text: '2',
lineNumber: 1
},
<ITextSearchContext>{
text: '3',
lineNumber: 2
},
<ITextSearchContext>{
text: '' + (MOCK_LINE_COUNT - 1),
lineNumber: MOCK_LINE_COUNT - 2
},
matches[1]
]);
});
});
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册