From b85d56b8570ce6bdb4ec0ee4dd5e8694dc0cabb9 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Fri, 15 May 2015 21:00:32 +0900 Subject: [PATCH 1/7] block form indentation --- src/services/formatting/smartIndenter.ts | 28 ++++++++++++++++++- .../fourslash/formattingOnChainedCallbacks.ts | 2 ++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 9cd28a40a54..35bc015d66b 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -26,7 +26,7 @@ module 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; } @@ -110,6 +110,12 @@ module ts.formatting { if (actualIndentation !== Value.Unknown) { return actualIndentation + indentationDelta; } + + // check if current node is a block-form item - if yes, take indentation from it + actualIndentation = getActualIndentationForBlockFormItem(current, sourceFile, options); + if (actualIndentation !== Value.Unknown) { + return actualIndentation + indentationDelta; + } } parentStart = getParentStart(parent, current, sourceFile); let parentAndChildShareLine = @@ -277,6 +283,15 @@ module ts.formatting { return undefined; } + function getActualIndentationForBlockFormItem(node: Node, sourceFile: SourceFile, options: EditorOptions): number { + if (isPassableBlockForm(node.kind)) { + let firstChild = node.getChildAt(0); + let lineAndCharacter = getStartLineAndCharacterForNode(firstChild, sourceFile); + return findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options); + } + return Value.Unknown; + } + function getActualIndentationForListItem(node: Node, sourceFile: SourceFile, options: EditorOptions): number { let containingList = getContainingList(node, sourceFile); return containingList ? getActualIndentationFromList(containingList) : Value.Unknown; @@ -400,5 +415,16 @@ module ts.formatting { return false; } } + + export function isPassableBlockForm(kind: SyntaxKind): boolean { + switch (kind) { + case SyntaxKind.ArrowFunction: + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrayLiteralExpression: + case SyntaxKind.ObjectLiteralExpression: + return true; + } + return false; + } } } \ No newline at end of file diff --git a/tests/cases/fourslash/formattingOnChainedCallbacks.ts b/tests/cases/fourslash/formattingOnChainedCallbacks.ts index 37fa6ff03f1..98f91de56fb 100644 --- a/tests/cases/fourslash/formattingOnChainedCallbacks.ts +++ b/tests/cases/fourslash/formattingOnChainedCallbacks.ts @@ -17,6 +17,8 @@ goTo.marker('1'); edit.insertLine(''); goTo.marker('2'); verify.currentLineContentIs(' ""'); +edit.insertLine(''); +verify.indentationIs(8); goTo.marker('4'); edit.insertLine(''); goTo.marker('3'); From a9eba62b68611bfb4aa75446ad6b147086dbe541 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sat, 16 May 2015 16:24:50 +0900 Subject: [PATCH 2/7] getLineIndentation --- src/services/formatting/smartIndenter.ts | 62 +++++++++++++----------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 35bc015d66b..77e70a1ceaf 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -110,12 +110,6 @@ module ts.formatting { if (actualIndentation !== Value.Unknown) { return actualIndentation + indentationDelta; } - - // check if current node is a block-form item - if yes, take indentation from it - actualIndentation = getActualIndentationForBlockFormItem(current, sourceFile, options); - if (actualIndentation !== Value.Unknown) { - return actualIndentation + indentationDelta; - } } parentStart = getParentStart(parent, current, sourceFile); let parentAndChildShareLine = @@ -283,23 +277,48 @@ module ts.formatting { return undefined; } - function getActualIndentationForBlockFormItem(node: Node, sourceFile: SourceFile, options: EditorOptions): number { - if (isPassableBlockForm(node.kind)) { - let firstChild = node.getChildAt(0); - let lineAndCharacter = getStartLineAndCharacterForNode(firstChild, sourceFile); - return findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options); - } - return Value.Unknown; - } - function getActualIndentationForListItem(node: Node, sourceFile: SourceFile, options: EditorOptions): number { let containingList = getContainingList(node, sourceFile); - return containingList ? getActualIndentationFromList(containingList) : Value.Unknown; + + if (containingList) { + let lineIndentation = getLineIndentationWhenExpressionIsInMultiLine(); + if (lineIndentation !== Value.Unknown) + return lineIndentation; + return getActualIndentationFromList(containingList); + } + return Value.Unknown; function getActualIndentationFromList(list: Node[]): number { let index = indexOf(list, node); return index !== -1 ? deriveActualIndentationFromList(list, index, sourceFile, options) : Value.Unknown; } + + function getLineIndentationWhenExpressionIsInMultiLine() { + if (node.parent.kind === SyntaxKind.CallExpression) { + let parentExpression = (node.parent).expression; + let startingExpression = getStartingExpression(parentExpression); + + if (parentExpression === startingExpression) { + return Value.Unknown; + } + + let parentExpressionEnd = sourceFile.getLineAndCharacterOfPosition(parentExpression.end); + let startingExpressionEnd = sourceFile.getLineAndCharacterOfPosition(startingExpression.end); + + if (parentExpressionEnd.line === startingExpressionEnd.line) { + return Value.Unknown; + } + + return findColumnForFirstNonWhitespaceCharacterInLine(parentExpressionEnd, sourceFile, options); + } + return Value.Unknown; + } + + function getStartingExpression(expression: CallExpression) { + while (expression.expression) + expression = expression.expression; + return expression; + } } function deriveActualIndentationFromList(list: Node[], index: number, sourceFile: SourceFile, options: EditorOptions): number { @@ -415,16 +434,5 @@ module ts.formatting { return false; } } - - export function isPassableBlockForm(kind: SyntaxKind): boolean { - switch (kind) { - case SyntaxKind.ArrowFunction: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrayLiteralExpression: - case SyntaxKind.ObjectLiteralExpression: - return true; - } - return false; - } } } \ No newline at end of file From 4b4fc0147e6480033ccfb50cc2a8a8168c1fde76 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sat, 16 May 2015 17:08:09 +0900 Subject: [PATCH 3/7] take the function out --- src/services/formatting/smartIndenter.ts | 38 ++++++++++++------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 77e70a1ceaf..a02dc4454fa 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -281,7 +281,7 @@ module ts.formatting { let containingList = getContainingList(node, sourceFile); if (containingList) { - let lineIndentation = getLineIndentationWhenExpressionIsInMultiLine(); + let lineIndentation = getLineIndentationWhenExpressionIsInMultiLine(node, sourceFile, options); if (lineIndentation !== Value.Unknown) return lineIndentation; return getActualIndentationFromList(containingList); @@ -292,28 +292,28 @@ module ts.formatting { let index = indexOf(list, node); return index !== -1 ? deriveActualIndentationFromList(list, index, sourceFile, options) : Value.Unknown; } + } - function getLineIndentationWhenExpressionIsInMultiLine() { - if (node.parent.kind === SyntaxKind.CallExpression) { - let parentExpression = (node.parent).expression; - let startingExpression = getStartingExpression(parentExpression); + function getLineIndentationWhenExpressionIsInMultiLine(node: Node, sourceFile: SourceFile, options: EditorOptions): number { + if (node.parent.kind === SyntaxKind.CallExpression) { + let parentExpression = (node.parent).expression; + let startingExpression = getStartingExpression(parentExpression); - if (parentExpression === startingExpression) { - return Value.Unknown; - } - - let parentExpressionEnd = sourceFile.getLineAndCharacterOfPosition(parentExpression.end); - let startingExpressionEnd = sourceFile.getLineAndCharacterOfPosition(startingExpression.end); - - if (parentExpressionEnd.line === startingExpressionEnd.line) { - return Value.Unknown; - } - - return findColumnForFirstNonWhitespaceCharacterInLine(parentExpressionEnd, sourceFile, options); + if (parentExpression === startingExpression) { + return Value.Unknown; } - return Value.Unknown; - } + let parentExpressionEnd = sourceFile.getLineAndCharacterOfPosition(parentExpression.end); + let startingExpressionEnd = sourceFile.getLineAndCharacterOfPosition(startingExpression.end); + + if (parentExpressionEnd.line === startingExpressionEnd.line) { + return Value.Unknown; + } + + return findColumnForFirstNonWhitespaceCharacterInLine(parentExpressionEnd, sourceFile, options); + } + return Value.Unknown; + function getStartingExpression(expression: CallExpression) { while (expression.expression) expression = expression.expression; From e20be958122788560753e67dda48792f7bca6fc6 Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sat, 23 May 2015 17:47:13 +0900 Subject: [PATCH 4/7] fixing some types --- src/services/formatting/smartIndenter.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index a02dc4454fa..712c8a2f93f 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -295,9 +295,11 @@ module ts.formatting { } function getLineIndentationWhenExpressionIsInMultiLine(node: Node, sourceFile: SourceFile, options: EditorOptions): number { - if (node.parent.kind === SyntaxKind.CallExpression) { - let parentExpression = (node.parent).expression; - let startingExpression = getStartingExpression(parentExpression); + if (node.parent.kind === SyntaxKind.CallExpression || + node.parent.kind === SyntaxKind.NewExpression) { + + let parentExpression = (node.parent).expression; + let startingExpression = getStartingExpression(parentExpression); if (parentExpression === startingExpression) { return Value.Unknown; @@ -314,9 +316,9 @@ module ts.formatting { } return Value.Unknown; - function getStartingExpression(expression: CallExpression) { + function getStartingExpression(expression: PropertyAccessExpression | CallExpression | ElementAccessExpression) { while (expression.expression) - expression = expression.expression; + expression = expression.expression; return expression; } } From 50a02237d1fc2deb2001214843ab01f0b9cae61c Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Sun, 24 May 2015 14:38:17 +0900 Subject: [PATCH 5/7] getLineIndentation for others --- src/services/formatting/smartIndenter.ts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 712c8a2f93f..4bd7fd66411 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -66,6 +66,10 @@ module 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 @@ module 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 @@ -279,14 +287,7 @@ module ts.formatting { function getActualIndentationForListItem(node: Node, sourceFile: SourceFile, options: EditorOptions): number { let containingList = getContainingList(node, sourceFile); - - if (containingList) { - let lineIndentation = getLineIndentationWhenExpressionIsInMultiLine(node, sourceFile, options); - if (lineIndentation !== Value.Unknown) - return lineIndentation; - return getActualIndentationFromList(containingList); - } - return Value.Unknown; + return containingList ? getActualIndentationFromList(containingList) : Value.Unknown; function getActualIndentationFromList(list: Node[]): number { let index = indexOf(list, node); @@ -295,8 +296,9 @@ module ts.formatting { } function getLineIndentationWhenExpressionIsInMultiLine(node: Node, sourceFile: SourceFile, options: EditorOptions): number { - if (node.parent.kind === SyntaxKind.CallExpression || - node.parent.kind === SyntaxKind.NewExpression) { + if (node.parent && ( + node.parent.kind === SyntaxKind.CallExpression || + node.parent.kind === SyntaxKind.NewExpression)) { let parentExpression = (node.parent).expression; let startingExpression = getStartingExpression(parentExpression); From 910079a60e88686b34acc4df0f2db4c79af9ac2e Mon Sep 17 00:00:00 2001 From: SaschaNaz Date: Tue, 2 Jun 2015 15:28:29 +0900 Subject: [PATCH 6/7] exclude closeparen/propertyaccess tokens --- src/services/formatting/smartIndenter.ts | 7 ++++++- ...nsistenceOnIndentionsOfChainedFunctionCalls.ts | 2 +- .../fourslash/formattingOnChainedCallbacks.ts | 15 ++++++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 4bd7fd66411..f904cfe744d 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -296,7 +296,12 @@ module ts.formatting { } function getLineIndentationWhenExpressionIsInMultiLine(node: Node, sourceFile: SourceFile, options: EditorOptions): number { - if (node.parent && ( + // actual indentation should not be used when: + // - node is close parenthesis - this is the end of the expression + // - node is property access expression + if (node.kind !== SyntaxKind.CloseParenToken && + node.kind !== SyntaxKind.PropertyAccessExpression && + node.parent && ( node.parent.kind === SyntaxKind.CallExpression || node.parent.kind === SyntaxKind.NewExpression)) { 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 98f91de56fb..b8dbc55d8b6 100644 --- a/tests/cases/fourslash/formattingOnChainedCallbacks.ts +++ b/tests/cases/fourslash/formattingOnChainedCallbacks.ts @@ -13,6 +13,14 @@ //// })/*b*/ ////} +////Promise +//// .then( +//// /*n1*/ +//// ) +//// /*n2*/ +//// .then(); + + goTo.marker('1'); edit.insertLine(''); goTo.marker('2'); @@ -36,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 From 36a30c42b5d53aa1ee1911515e29aa6645e6b003 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 24 Jun 2015 11:53:53 -0700 Subject: [PATCH 7/7] Rename functions and variables, also a small refactoring. --- src/services/formatting/smartIndenter.ts | 44 ++++++++++++++++-------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index b9636a8ddb8..db748f7f494 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -298,35 +298,49 @@ 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 - // - node is property access expression - if (node.kind !== SyntaxKind.CloseParenToken && - node.kind !== SyntaxKind.PropertyAccessExpression && - node.parent && ( + if (node.kind === SyntaxKind.CloseParenToken) { + return Value.Unknown; + } + + if (node.parent && ( node.parent.kind === SyntaxKind.CallExpression || - node.parent.kind === SyntaxKind.NewExpression)) { + node.parent.kind === SyntaxKind.NewExpression) && + (node.parent).expression !== node) { - let parentExpression = (node.parent).expression; - let startingExpression = getStartingExpression(parentExpression); + let fullCallOrNewExpression = (node.parent).expression; + let startingExpression = getStartingExpression(fullCallOrNewExpression); - if (parentExpression === startingExpression) { + if (fullCallOrNewExpression === startingExpression) { return Value.Unknown; } - let parentExpressionEnd = sourceFile.getLineAndCharacterOfPosition(parentExpression.end); + let fullCallOrNewExpressionEnd = sourceFile.getLineAndCharacterOfPosition(fullCallOrNewExpression.end); let startingExpressionEnd = sourceFile.getLineAndCharacterOfPosition(startingExpression.end); - if (parentExpressionEnd.line === startingExpressionEnd.line) { + if (fullCallOrNewExpressionEnd.line === startingExpressionEnd.line) { return Value.Unknown; } - return findColumnForFirstNonWhitespaceCharacterInLine(parentExpressionEnd, sourceFile, options); + return findColumnForFirstNonWhitespaceCharacterInLine(fullCallOrNewExpressionEnd, sourceFile, options); } + return Value.Unknown; - function getStartingExpression(expression: PropertyAccessExpression | CallExpression | ElementAccessExpression) { - while (expression.expression) - expression = expression.expression; - return expression; + 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; } }