From 63113bea12f8195b52ff76bee9c40bc75412a333 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Mon, 29 Apr 2019 17:36:04 +0200 Subject: [PATCH] Fixes #70832: Never guess tabSize when inserting tabs --- .../editor/common/model/indentationGuesser.ts | 30 ++++++----- .../test/common/model/textModel.test.ts | 51 +++++++++++++++---- 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/vs/editor/common/model/indentationGuesser.ts b/src/vs/editor/common/model/indentationGuesser.ts index e5fc19ba129bd..24c449c60c42c 100644 --- a/src/vs/editor/common/model/indentationGuesser.ts +++ b/src/vs/editor/common/model/indentationGuesser.ts @@ -177,22 +177,26 @@ export function guessIndentation(source: ITextBuffer, defaultTabSize: number, de } let tabSize = defaultTabSize; - let tabSizeScore = (insertSpaces ? 0 : 0.1 * linesCount); - // console.log("score threshold: " + tabSizeScore); + // Guess tabSize only if inserting spaces... + if (insertSpaces) { + let tabSizeScore = (insertSpaces ? 0 : 0.1 * linesCount); - ALLOWED_TAB_SIZE_GUESSES.forEach((possibleTabSize) => { - let possibleTabSizeScore = spacesDiffCount[possibleTabSize]; - if (possibleTabSizeScore > tabSizeScore) { - tabSizeScore = possibleTabSizeScore; - tabSize = possibleTabSize; - } - }); + // console.log("score threshold: " + tabSizeScore); + + ALLOWED_TAB_SIZE_GUESSES.forEach((possibleTabSize) => { + let possibleTabSizeScore = spacesDiffCount[possibleTabSize]; + if (possibleTabSizeScore > tabSizeScore) { + tabSizeScore = possibleTabSizeScore; + tabSize = possibleTabSize; + } + }); - // Let a tabSize of 2 win even if it is not the maximum - // (only in case 4 was guessed) - if (tabSize === 4 && spacesDiffCount[4] > 0 && spacesDiffCount[2] > 0 && spacesDiffCount[2] >= spacesDiffCount[4] / 2) { - tabSize = 2; + // Let a tabSize of 2 win even if it is not the maximum + // (only in case 4 was guessed) + if (tabSize === 4 && spacesDiffCount[4] > 0 && spacesDiffCount[2] > 0 && spacesDiffCount[2] >= spacesDiffCount[4] / 2) { + tabSize = 2; + } } diff --git a/src/vs/editor/test/common/model/textModel.test.ts b/src/vs/editor/test/common/model/textModel.test.ts index d2a8d3cd4f7bb..812edc45468a3 100644 --- a/src/vs/editor/test/common/model/textModel.test.ts +++ b/src/vs/editor/test/common/model/textModel.test.ts @@ -26,17 +26,21 @@ function testGuessIndentation(defaultInsertSpaces: boolean, defaultTabSize: numb assert.equal(r.tabSize, expectedTabSize, msg); } -function assertGuess(expectedInsertSpaces: boolean | undefined, expectedTabSize: number | undefined, text: string[], msg?: string): void { +function assertGuess(expectedInsertSpaces: boolean | undefined, expectedTabSize: number | undefined | [number], text: string[], msg?: string): void { if (typeof expectedInsertSpaces === 'undefined') { // cannot guess insertSpaces if (typeof expectedTabSize === 'undefined') { // cannot guess tabSize testGuessIndentation(true, 13370, true, 13370, text, msg); testGuessIndentation(false, 13371, false, 13371, text, msg); - } else { + } else if (typeof expectedTabSize === 'number') { // can guess tabSize testGuessIndentation(true, 13370, true, expectedTabSize, text, msg); testGuessIndentation(false, 13371, false, expectedTabSize, text, msg); + } else { + // can only guess tabSize when insertSpaces is true + testGuessIndentation(true, 13370, true, expectedTabSize[0], text, msg); + testGuessIndentation(false, 13371, false, 13371, text, msg); } } else { // can guess insertSpaces @@ -44,10 +48,19 @@ function assertGuess(expectedInsertSpaces: boolean | undefined, expectedTabSize: // cannot guess tabSize testGuessIndentation(true, 13370, expectedInsertSpaces, 13370, text, msg); testGuessIndentation(false, 13371, expectedInsertSpaces, 13371, text, msg); - } else { + } else if (typeof expectedTabSize === 'number') { // can guess tabSize testGuessIndentation(true, 13370, expectedInsertSpaces, expectedTabSize, text, msg); testGuessIndentation(false, 13371, expectedInsertSpaces, expectedTabSize, text, msg); + } else { + // can only guess tabSize when insertSpaces is true + if (expectedInsertSpaces === true) { + testGuessIndentation(true, 13370, expectedInsertSpaces, expectedTabSize[0], text, msg); + testGuessIndentation(false, 13371, expectedInsertSpaces, expectedTabSize[0], text, msg); + } else { + testGuessIndentation(true, 13370, expectedInsertSpaces, 13370, text, msg); + testGuessIndentation(false, 13371, expectedInsertSpaces, 13371, text, msg); + } } } } @@ -219,7 +232,7 @@ suite('Editor Model - TextModel', () => { '\tx' ], '7xTAB'); - assertGuess(undefined, 2, [ + assertGuess(undefined, [2], [ '\tx', ' x', '\tx', @@ -239,7 +252,7 @@ suite('Editor Model - TextModel', () => { '\tx', ' x' ], '4x1, 4xTAB'); - assertGuess(false, 2, [ + assertGuess(false, undefined, [ '\tx', '\tx', ' x', @@ -250,7 +263,7 @@ suite('Editor Model - TextModel', () => { '\tx', ' x', ], '4x2, 5xTAB'); - assertGuess(false, 2, [ + assertGuess(false, undefined, [ '\tx', '\tx', 'x', @@ -261,7 +274,7 @@ suite('Editor Model - TextModel', () => { '\tx', ' x', ], '1x2, 5xTAB'); - assertGuess(false, 4, [ + assertGuess(false, undefined, [ '\tx', '\tx', 'x', @@ -272,7 +285,7 @@ suite('Editor Model - TextModel', () => { '\tx', ' x', ], '1x4, 5xTAB'); - assertGuess(false, 2, [ + assertGuess(false, undefined, [ '\tx', '\tx', 'x', @@ -524,7 +537,7 @@ suite('Editor Model - TextModel', () => { ' \t x', '\tx' ], 'mixed whitespace 1'); - assertGuess(false, 4, [ + assertGuess(false, undefined, [ '\tx', '\t x' ], 'mixed whitespace 2'); @@ -575,6 +588,26 @@ suite('Editor Model - TextModel', () => { ]); }); + test('issue #70832: Broken indentation detection', () => { + assertGuess(false, undefined, [ + 'x', + 'x', + 'x', + 'x', + ' x', + ' x', + ' x', + ' x', + ' x', + ' x', + ' x', + ' x', + ' x', + ' x', + 'x', + ]); + }); + test('validatePosition', () => { let m = TextModel.createFromString('line one\nline two');