提交 ac2bd0a4 编写于 作者: J Johannes Rieken

use actual word range and block ranges to compute distance

上级 39facdaf
......@@ -500,13 +500,13 @@ export abstract class BaseEditorSimpleWorker {
//#region -- word ranges --
computeWordLines(modelUrl: string, range: IRange, wordDef: string, wordDefFlags: string): Promise<{ [word: string]: number[] }> {
computeWordRanges(modelUrl: string, range: IRange, wordDef: string, wordDefFlags: string): Promise<{ [word: string]: IRange[] }> {
let model = this._getModel(modelUrl);
if (!model) {
return Promise.resolve({});
return Promise.resolve(Object.create(null));
}
const wordDefRegExp = new RegExp(wordDef, wordDefFlags);
const result: { [word: string]: number[] } = Object.create(null);
const result: { [word: string]: IRange[] } = Object.create(null);
for (let line = range.startLineNumber; line < range.endLineNumber; line++) {
let words = model.getLineWords(line, wordDefRegExp);
for (const word of words) {
......@@ -518,7 +518,12 @@ export abstract class BaseEditorSimpleWorker {
array = [];
result[word.word] = array;
}
array.push(line);
array.push({
startLineNumber: line,
startColumn: word.startColumn,
endLineNumber: line,
endColumn: word.endColumn
});
}
}
return Promise.resolve(result);
......
......@@ -25,8 +25,8 @@ export interface IEditorWorkerService {
computeMoreMinimalEdits(resource: URI, edits: TextEdit[]): TPromise<TextEdit[]>;
canComputeWordLines(resource: URI): boolean;
computeWordLines(resource: URI, range: IRange): TPromise<{ [word: string]: number[] }>;
canComputeWordRanges(resource: URI): boolean;
computeWordRanges(resource: URI, range: IRange): TPromise<{ [word: string]: IRange[] }>;
canNavigateValueSet(resource: URI): boolean;
navigateValueSet(resource: URI, range: IRange, up: boolean): TPromise<IInplaceReplaceSupportResult>;
......
......@@ -108,12 +108,12 @@ export class EditorWorkerServiceImpl extends Disposable implements IEditorWorker
return this._workerManager.withWorker().then(client => client.navigateValueSet(resource, range, up));
}
canComputeWordLines(resource: URI): boolean {
canComputeWordRanges(resource: URI): boolean {
return canSyncModel(this._modelService, resource);
}
computeWordLines(resource: URI, range: IRange): TPromise<{ [word: string]: number[] }> {
return this._workerManager.withWorker().then(client => client.computeWordLines(resource, range));
computeWordRanges(resource: URI, range: IRange): TPromise<{ [word: string]: IRange[] }> {
return this._workerManager.withWorker().then(client => client.computeWordRanges(resource, range));
}
}
......@@ -422,7 +422,7 @@ export class EditorWorkerClient extends Disposable {
});
}
computeWordLines(resource: URI, range: IRange): TPromise<{ [word: string]: number[] }> {
computeWordRanges(resource: URI, range: IRange): TPromise<{ [word: string]: IRange[] }> {
return this._withSyncedResources([resource]).then(proxy => {
let model = this._modelService.getModel(resource);
if (!model) {
......@@ -431,7 +431,7 @@ export class EditorWorkerClient extends Disposable {
let wordDefRegExp = LanguageConfigurationRegistry.getWordDefinition(model.getLanguageIdentifier().id);
let wordDef = wordDefRegExp.source;
let wordDefFlags = (wordDefRegExp.global ? 'g' : '') + (wordDefRegExp.ignoreCase ? 'i' : '') + (wordDefRegExp.multiline ? 'm' : '');
return proxy.computeWordLines(resource.toString(), range, wordDef, wordDefFlags);
return proxy.computeWordRanges(resource.toString(), range, wordDef, wordDefFlags);
});
}
......
......@@ -178,7 +178,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
return new Promise((resolve, reject) => {
const editor = createMockEditor(model);
const oracle = new SuggestModel(editor, new class extends mock<IEditorWorkerService>() {
computeWordLines(): Promise<{ [word: string]: number[] }> {
computeWordRanges() {
return Promise.resolve({});
}
......
......@@ -28,52 +28,45 @@ export abstract class WordDistance {
const model = editor.getModel();
const position = editor.getPosition();
if (!service.canComputeWordRanges(model.uri)) {
return Promise.resolve(WordDistance.None);
}
// use token tree ranges
let node = find(build(model), position);
let blockScores = new Map<number, number>();
let score = 0;
let ranges: Range[] = [];
let stop = false;
let lastRange: Range;
while (node && !stop) {
if (node instanceof Block || !node.parent) {
// assign block score
score += 1;
if (!lastRange) {
for (let line = node.start.lineNumber; line <= node.end.lineNumber; line++) {
blockScores.set(line, score);
}
} else {
for (let line = node.start.lineNumber; line < lastRange.startLineNumber; line++) {
blockScores.set(line, score);
}
for (let line = lastRange.endLineNumber; line <= node.end.lineNumber; line++) {
blockScores.set(line, score);
}
}
lastRange = node.range;
ranges.push(node.range);
stop = node.end.lineNumber - node.start.lineNumber >= 100;
}
node = node.parent;
}
ranges.reverse();
return service.computeWordLines(model.uri, lastRange).then(lineNumbers => {
return service.computeWordRanges(model.uri, ranges[0]).then(wordRanges => {
return new class extends WordDistance {
distance(anchor: IPosition, word: string) {
if (!lineNumbers || !position.equals(editor.getPosition())) {
if (!wordRanges || !position.equals(editor.getPosition())) {
return 0;
}
let wordLines = lineNumbers[word];
let wordLines = wordRanges[word];
if (isFalsyOrEmpty(wordLines)) {
return 101;
return 2 << 20;
}
let idx = binarySearch(wordLines, anchor.lineNumber, (a, b) => a - b);
let wordLineNumber = idx >= 0 ? wordLines[idx] : wordLines[Math.max(0, ~idx - 1)];
if (!blockScores.has(wordLineNumber)) {
return 101;
let idx = binarySearch(wordLines, Range.fromPositions(anchor), Range.compareRangesUsingStarts);
let bestWordRange = idx >= 0 ? wordLines[idx] : wordLines[Math.max(0, ~idx - 1)];
let blockDistance = ranges.length;
for (const range of ranges) {
if (!Range.containsRange(range, bestWordRange)) {
break;
}
blockDistance -= 1;
}
return blockScores.get(wordLineNumber);
return blockDistance;
}
};
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册