diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index a82e57f050f..db748f7f494 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -26,7 +26,7 @@ namespace ts.formatting { precedingToken.kind === SyntaxKind.TemplateHead || precedingToken.kind === SyntaxKind.TemplateMiddle || precedingToken.kind === SyntaxKind.TemplateTail; - if (precedingTokenIsLiteral && precedingToken.getStart(sourceFile) <= position && precedingToken.end > position) { + if (precedingTokenIsLiteral && precedingToken.getStart(sourceFile) <= position && precedingToken.end > position) { return 0; } @@ -66,6 +66,10 @@ namespace ts.formatting { if (actualIndentation !== Value.Unknown) { return actualIndentation; } + actualIndentation = getLineIndentationWhenExpressionIsInMultiLine(current, sourceFile, options); + if (actualIndentation !== Value.Unknown) { + return actualIndentation + options.IndentSize; + } previous = current; current = current.parent; @@ -122,6 +126,10 @@ namespace ts.formatting { if (actualIndentation !== Value.Unknown) { return actualIndentation + indentationDelta; } + actualIndentation = getLineIndentationWhenExpressionIsInMultiLine(current, sourceFile, options); + if (actualIndentation !== Value.Unknown) { + return actualIndentation + indentationDelta; + } } // increase indentation if parent node wants its content to be indented and parent and child nodes don't start on the same line @@ -287,6 +295,55 @@ namespace ts.formatting { } } + function getLineIndentationWhenExpressionIsInMultiLine(node: Node, sourceFile: SourceFile, options: EditorOptions): number { + // actual indentation should not be used when: + // - node is close parenthesis - this is the end of the expression + if (node.kind === SyntaxKind.CloseParenToken) { + return Value.Unknown; + } + + if (node.parent && ( + node.parent.kind === SyntaxKind.CallExpression || + node.parent.kind === SyntaxKind.NewExpression) && + (node.parent).expression !== node) { + + let fullCallOrNewExpression = (node.parent).expression; + let startingExpression = getStartingExpression(fullCallOrNewExpression); + + if (fullCallOrNewExpression === startingExpression) { + return Value.Unknown; + } + + let fullCallOrNewExpressionEnd = sourceFile.getLineAndCharacterOfPosition(fullCallOrNewExpression.end); + let startingExpressionEnd = sourceFile.getLineAndCharacterOfPosition(startingExpression.end); + + if (fullCallOrNewExpressionEnd.line === startingExpressionEnd.line) { + return Value.Unknown; + } + + return findColumnForFirstNonWhitespaceCharacterInLine(fullCallOrNewExpressionEnd, sourceFile, options); + } + + return Value.Unknown; + + function getStartingExpression(node: PropertyAccessExpression | CallExpression | ElementAccessExpression) { + while (true) { + switch (node.kind) { + case SyntaxKind.CallExpression: + case SyntaxKind.NewExpression: + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.ElementAccessExpression: + + node = node.expression; + break; + default: + return node; + } + } + return node; + } + } + function deriveActualIndentationFromList(list: Node[], index: number, sourceFile: SourceFile, options: EditorOptions): number { Debug.assert(index >= 0 && index < list.length); let node = list[index]; diff --git a/tests/cases/fourslash/consistenceOnIndentionsOfChainedFunctionCalls.ts b/tests/cases/fourslash/consistenceOnIndentionsOfChainedFunctionCalls.ts index ec2ae9b3c22..3692974f5fb 100644 --- a/tests/cases/fourslash/consistenceOnIndentionsOfChainedFunctionCalls.ts +++ b/tests/cases/fourslash/consistenceOnIndentionsOfChainedFunctionCalls.ts @@ -18,4 +18,4 @@ goTo.marker("1"); edit.insert("\r\n"); goTo.marker("0"); // Won't-fixed: Smart indent during chained function calls -verify.indentationIs(4); \ No newline at end of file +verify.indentationIs(8); \ No newline at end of file diff --git a/tests/cases/fourslash/formattingOnChainedCallbacks.ts b/tests/cases/fourslash/formattingOnChainedCallbacks.ts index 37fa6ff03f1..b8dbc55d8b6 100644 --- a/tests/cases/fourslash/formattingOnChainedCallbacks.ts +++ b/tests/cases/fourslash/formattingOnChainedCallbacks.ts @@ -13,10 +13,20 @@ //// })/*b*/ ////} +////Promise +//// .then( +//// /*n1*/ +//// ) +//// /*n2*/ +//// .then(); + + goTo.marker('1'); edit.insertLine(''); goTo.marker('2'); verify.currentLineContentIs(' ""'); +edit.insertLine(''); +verify.indentationIs(8); goTo.marker('4'); edit.insertLine(''); goTo.marker('3'); @@ -34,4 +44,9 @@ edit.insert(';'); verify.currentLineContentIs(' "";'); goTo.marker('b'); edit.insert(';'); -verify.currentLineContentIs(' });'); \ No newline at end of file +verify.currentLineContentIs(' });'); + +goTo.marker('n1'); +verify.indentationIs(8); +goTo.marker('n2'); +verify.indentationIs(4); \ No newline at end of file