From bfbb4835708b6a98bf6016682ec6347820671c54 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 12 Sep 2018 18:12:20 +0200 Subject: [PATCH] Fixes #55818: Tweak indentation guessing code to accomodate for code alignment --- .../editor/common/model/indentationGuesser.ts | 43 ++++++++++++++++--- .../test/common/model/textModel.test.ts | 26 +++++++++++ 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/common/model/indentationGuesser.ts b/src/vs/editor/common/model/indentationGuesser.ts index 3f89f6d9cd3..01e850b65ff 100644 --- a/src/vs/editor/common/model/indentationGuesser.ts +++ b/src/vs/editor/common/model/indentationGuesser.ts @@ -7,10 +7,18 @@ import { CharCode } from 'vs/base/common/charCode'; import { ITextBuffer } from 'vs/editor/common/model'; +class SpacesDiffResult { + public spacesDiff: number; + public looksLikeAlignment: boolean; +} + /** * Compute the diff in spaces between two line's indentation. */ -function spacesDiff(a: string, aLength: number, b: string, bLength: number): number { +function spacesDiff(a: string, aLength: number, b: string, bLength: number, result: SpacesDiffResult): void { + + result.spacesDiff = 0; + result.looksLikeAlignment = false; // This can go both ways (e.g.): // - a: "\t" @@ -49,22 +57,35 @@ function spacesDiff(a: string, aLength: number, b: string, bLength: number): num } if (aSpacesCnt > 0 && aTabsCount > 0) { - return 0; + return; } if (bSpacesCnt > 0 && bTabsCount > 0) { - return 0; + return; } let tabsDiff = Math.abs(aTabsCount - bTabsCount); let spacesDiff = Math.abs(aSpacesCnt - bSpacesCnt); if (tabsDiff === 0) { - return spacesDiff; + // check if the indentation difference might be caused by alignment reasons + // sometime folks like to align their code, but this should not be used as a hint + result.spacesDiff = spacesDiff; + + if (spacesDiff > 0 && 0 <= bSpacesCnt - 1 && bSpacesCnt - 1 < a.length && bSpacesCnt < b.length) { + if (b.charCodeAt(bSpacesCnt) !== CharCode.Space && a.charCodeAt(bSpacesCnt - 1) === CharCode.Space) { + // This looks like an alignment desire: e.g. + // const a = b + c, + // d = b - c; + + result.looksLikeAlignment = true; + } + } + return; } if (spacesDiff % tabsDiff === 0) { - return spacesDiff / tabsDiff; + result.spacesDiff = spacesDiff / tabsDiff; + return; } - return 0; } /** @@ -95,6 +116,7 @@ export function guessIndentation(source: ITextBuffer, defaultTabSize: number, de const MAX_ALLOWED_TAB_SIZE_GUESS = 8; // max(2,4,6,8) = 8 let spacesDiffCount = [0, 0, 0, 0, 0, 0, 0, 0, 0]; // `tabSize` scores + let tmp = new SpacesDiffResult(); for (let lineNumber = 1; lineNumber <= linesCount; lineNumber++) { let currentLineLength = source.getLineLength(lineNumber); @@ -134,7 +156,14 @@ export function guessIndentation(source: ITextBuffer, defaultTabSize: number, de linesIndentedWithSpacesCount++; } - let currentSpacesDiff = spacesDiff(previousLineText, previousLineIndentation, currentLineText, currentLineIndentation); + spacesDiff(previousLineText, previousLineIndentation, currentLineText, currentLineIndentation, tmp); + + if (tmp.looksLikeAlignment) { + // skip this line entirely + continue; + } + + let currentSpacesDiff = tmp.spacesDiff; if (currentSpacesDiff <= MAX_ALLOWED_TAB_SIZE_GUESS) { spacesDiffCount[currentSpacesDiff]++; } diff --git a/src/vs/editor/test/common/model/textModel.test.ts b/src/vs/editor/test/common/model/textModel.test.ts index d4506ec14e0..ae557f66ab4 100644 --- a/src/vs/editor/test/common/model/textModel.test.ts +++ b/src/vs/editor/test/common/model/textModel.test.ts @@ -550,6 +550,32 @@ suite('Editor Model - TextModel', () => { ]); }); + test('issue #55818: Broken indentation detection', () => { + assertGuess(true, 2, [ + '', + '/* REQUIRE */', + '', + 'const foo = require ( \'foo\' ),', + ' bar = require ( \'bar\' );', + '', + '/* MY FN */', + '', + 'function myFn () {', + '', + ' const asd = 1,', + ' dsa = 2;', + '', + ' return bar ( foo ( asd ) );', + '', + '}', + '', + '/* EXPORT */', + '', + 'module.exports = myFn;', + '', + ]); + }); + test('validatePosition', () => { let m = TextModel.createFromString('line one\nline two'); -- GitLab