diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 787c6fe3f46..cab7547557c 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -243,8 +243,18 @@ module ts.formatting { } var precedingToken = findPrecedingToken(originalRange.pos, sourceFile); - // no preceding token found - start from the beginning of enclosing node - return precedingToken ? precedingToken.end : enclosingNode.pos; + if (!precedingToken) { + // no preceding token found - start from the beginning of enclosing node + return enclosingNode.pos; + } + + // preceding token ends after the start of original range (i.e when originaRange.pos falls in the middle of literal) + // start from the beginning of enclosingNode to handle the entire 'originalRange' + if (precedingToken.end >= originalRange.pos) { + return enclosingNode.pos; + } + + return precedingToken.end; } /* diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts index 7ddfecc17f2..e9485158aba 100644 --- a/src/services/formatting/formattingScanner.ts +++ b/src/services/formatting/formattingScanner.ts @@ -187,6 +187,9 @@ module ts.formatting { } // consume trailing trivia + if (trailingTrivia) { + trailingTrivia = undefined; + } while(scanner.getStartPos() < endPos) { currentToken = scanner.scan(); if (!isTrivia(currentToken)) { diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index ce240a95168..3aa97fe6ae6 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -12,10 +12,15 @@ module ts.formatting { return 0; } - // no indentation in string \regex literals - if ((precedingToken.kind === SyntaxKind.StringLiteral || precedingToken.kind === SyntaxKind.RegularExpressionLiteral) && - precedingToken.getStart(sourceFile) <= position && - precedingToken.end > position) { + // no indentation in string \regex\template literals + var precedingTokenIsLiteral = + precedingToken.kind === SyntaxKind.StringLiteral || + precedingToken.kind === SyntaxKind.RegularExpressionLiteral || + precedingToken.kind === SyntaxKind.NoSubstitutionTemplateLiteral || + precedingToken.kind === SyntaxKind.TemplateHead || + precedingToken.kind === SyntaxKind.TemplateMiddle || + precedingToken.kind === SyntaxKind.TemplateTail; + if (precedingTokenIsLiteral && precedingToken.getStart(sourceFile) <= position && precedingToken.end > position) { return 0; } diff --git a/tests/cases/fourslash/formatTemplateLiteral.ts b/tests/cases/fourslash/formatTemplateLiteral.ts new file mode 100644 index 00000000000..a1f5ef963da --- /dev/null +++ b/tests/cases/fourslash/formatTemplateLiteral.ts @@ -0,0 +1,13 @@ +/// +////var x = `sadasdasdasdasfegsfd +/////*1*/rasdesgeryt35t35y35 e4 ergt er 35t 3535 `; +////var y = `1${2}/*2*/3`; + + +goTo.marker("1"); +edit.insert("\r\n"); // edit will trigger formatting - should succeeed + +goTo.marker("2"); +edit.insert("\r\n"); +verify.indentationIs(0); +verify.currentLineContentIs("3`;") \ No newline at end of file diff --git a/tests/cases/fourslash/smartIndentTemplateLiterals.ts b/tests/cases/fourslash/smartIndentTemplateLiterals.ts new file mode 100644 index 00000000000..679978a515c --- /dev/null +++ b/tests/cases/fourslash/smartIndentTemplateLiterals.ts @@ -0,0 +1,17 @@ +/// +////var x0 = `sadasdasdasdas/*1*/fegsfdrasdesgeryt35t35y35 e4 ergt er 35t 3535 `; +////var x1 = `sadasdasdasdas/*2*/fegsfdr${0}asdesgeryt35t35y35 e4 ergt er 35t 3535 `; +////var x2 = `sadasdasdasdasfegsfdra${0}sdesge/*3*/ryt35t35y35 e4 ergt er 35t 3535 `; +////var x3 = `sadasdasdasdasfegsfdra${0}sdesge/*4*/ryt35${1}t35y35 e4 ergt er 35t 3535 `; +////var x2 = `sadasdasdasdasfegsfdra${0}sdesge${1}sf/*5*/ryt35t35y35 e4 ergt er 35t 3535 `; + +function verifyIndentation(marker: string): void { + goTo.marker(marker); + edit.insert("\r\n"); + verify.indentationIs(0); +} +verifyIndentation("1"); +verifyIndentation("2"); +verifyIndentation("3"); +verifyIndentation("4"); +verifyIndentation("5");