Skip to content

Commit

Permalink
Fixes #141550.
Browse files Browse the repository at this point in the history
  • Loading branch information
hediet committed Mar 2, 2022
1 parent 7e4da40 commit 11e60eb
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,18 @@ function cachingDiff(originalValue: string, newValue: string): readonly IDiffCha
if (lastRequest?.originalValue === originalValue && lastRequest?.newValue === newValue) {
return lastRequest?.changes;
} else {
const changes = smartDiff(originalValue, newValue);
let changes = smartDiff(originalValue, newValue, true);
if (changes) {
const deletedChars = deletedCharacters(changes);
if (deletedChars > 0) {
// For performance reasons, don't compute diff if there is nothing to improve
const newChanges = smartDiff(originalValue, newValue, false);
if (newChanges && deletedCharacters(newChanges) < deletedChars) {
// Disabling smartness seems to be better here
changes = newChanges;
}
}
}
lastRequest = {
originalValue,
newValue,
Expand All @@ -153,6 +164,14 @@ function cachingDiff(originalValue: string, newValue: string): readonly IDiffCha
}
}

function deletedCharacters(changes: readonly IDiffChange[]): number {
let sum = 0;
for (const c of changes) {
sum += Math.max(c.originalLength - c.modifiedLength, 0);
}
return sum;
}

/**
* When matching `if ()` with `if (f() = 1) { g(); }`,
* align it like this: `if ( )`
Expand All @@ -161,7 +180,7 @@ function cachingDiff(originalValue: string, newValue: string): readonly IDiffCha
*
* The parenthesis are preprocessed to ensure that they match correctly.
*/
function smartDiff(originalValue: string, newValue: string): (readonly IDiffChange[]) | undefined {
function smartDiff(originalValue: string, newValue: string, smartBracketMatching: boolean): (readonly IDiffChange[]) | undefined {
if (originalValue.length > 5000 || newValue.length > 5000) {
// We don't want to work on strings that are too big
return undefined;
Expand Down Expand Up @@ -191,18 +210,18 @@ function smartDiff(originalValue: string, newValue: string): (readonly IDiffChan
let group = 0;
const characters = new Int32Array(source.length);
for (let i = 0, len = source.length; i < len; i++) {
const id = group * 100 + level;

// TODO support more brackets
if (source[i] === '(') {
if (smartBracketMatching && source[i] === '(') {
const id = group * 100 + level;
characters[i] = getUniqueCharCode(2 * id);
level++;
} else if (source[i] === ')') {
} else if (smartBracketMatching && source[i] === ')') {
level = Math.max(level - 1, 0);
const id = group * 100 + level;
characters[i] = getUniqueCharCode(2 * id + 1);
if (level === 1) {
if (level === 0) {
group++;
}
level = Math.max(level - 1, 0);
} else {
characters[i] = source.charCodeAt(i);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,18 @@ suite('Inline Completions', () => {
assert.deepStrictEqual(getOutput('[\tfoo]', '\t\tfoobar'), { prefix: undefined, subword: '\t[\t]foo[bar]' });
assert.deepStrictEqual(getOutput('[(y ===)]', '(y === 1) { f(); }'), { prefix: undefined, subword: '(y ===[ 1])[ { f(); }]' });
assert.deepStrictEqual(getOutput('[(y ==)]', '(y === 1) { f(); }'), { prefix: undefined, subword: '(y ==[= 1])[ { f(); }]' });

assert.deepStrictEqual(getOutput('[(y ==)]', '(y === 1) { f(); }'), { prefix: undefined, subword: '(y ==[= 1])[ { f(); }]' });
});

test('Multi Part Diffing 1', () => {
assert.deepStrictEqual(getOutput('[if () ()]', 'if (1 == f()) ()'), { prefix: undefined, subword: 'if ([1 == f()]) ()' });
});

test('Multi Part Diffing 2', () => {
assert.deepStrictEqual(getOutput('[)]', '())'), ({ prefix: undefined, subword: "[(])[)]" }));
assert.deepStrictEqual(getOutput('[))]', '(())'), ({ prefix: undefined, subword: "[((]))" }));
});
});

test('Does not trigger automatically if disabled', async function () {
Expand Down

0 comments on commit 11e60eb

Please sign in to comment.