From e97118e5698a9bd0518d96a67447417fb6a9c758 Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Tue, 22 Dec 2015 18:30:07 +0900 Subject: [PATCH] InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces --- src/harness/fourslash.ts | 3 ++- src/server/editorServices.ts | 1 + src/services/formatting/rules.ts | 16 +++++++++---- src/services/formatting/rulesProvider.ts | 23 +++++++++++++------ src/services/services.ts | 1 + .../cases/fourslash/formatTemplateLiteral.ts | 4 ++-- .../fourslash/formattingOptionsChange.ts | 6 +++-- tests/cases/fourslash/formattingTemplates.ts | 4 ++-- tests/cases/fourslash/fourslash.ts | 1 + 9 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 9d729345781..8069a4d2e61 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -317,6 +317,7 @@ namespace FourSlash { InsertSpaceAfterFunctionKeywordForAnonymousFunctions: false, InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, + InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, PlaceOpenBraceOnNewLineForFunctions: false, PlaceOpenBraceOnNewLineForControlBlocks: false, }; @@ -3287,4 +3288,4 @@ namespace FourSlashInterface { }; } } -} +} diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 0305b7595c2..d84cf75acfc 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1357,6 +1357,7 @@ namespace ts.server { InsertSpaceAfterFunctionKeywordForAnonymousFunctions: false, InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, + InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, PlaceOpenBraceOnNewLineForFunctions: false, PlaceOpenBraceOnNewLineForControlBlocks: false, }; diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index de4761f57d2..23d5c0db8ca 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -219,9 +219,11 @@ namespace ts.formatting { public SpaceBetweenAsyncAndFunctionKeyword: Rule; // Template strings - public SpaceBetweenTagAndTemplateString: Rule; + public NoSpaceBetweenTagAndTemplateString: Rule; public NoSpaceAfterTemplateHeadAndMiddle: Rule; + public SpaceAfterTemplateHeadAndMiddle: Rule; public NoSpaceBeforeTemplateMiddleAndTail: Rule; + public SpaceBeforeTemplateMiddleAndTail: Rule; constructor() { /// @@ -376,9 +378,7 @@ namespace ts.formatting { this.SpaceBetweenAsyncAndFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.AsyncKeyword, SyntaxKind.FunctionKeyword), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); // template string - this.SpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); - this.NoSpaceAfterTemplateHeadAndMiddle = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); - this.NoSpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); + this.NoSpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); // These rules are higher in priority than user-configurable rules. this.HighPriorityCommonRules = [ @@ -406,7 +406,7 @@ namespace ts.formatting { this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator, this.SpaceAfterVoidOperator, this.SpaceBetweenAsyncAndOpenParen, this.SpaceBetweenAsyncAndFunctionKeyword, - this.SpaceBetweenTagAndTemplateString, this.NoSpaceAfterTemplateHeadAndMiddle, this.NoSpaceBeforeTemplateMiddleAndTail, + this.NoSpaceBetweenTagAndTemplateString, // TypeScript-specific rules this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport, @@ -485,6 +485,12 @@ namespace ts.formatting { this.NoSpaceAfterOpenBracket = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBracketToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); this.NoSpaceBeforeCloseBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBracketToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); + // Insert space after opening and before closing template string braces + this.NoSpaceAfterTemplateHeadAndMiddle = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); + this.SpaceAfterTemplateHeadAndMiddle = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); + this.NoSpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete)); + this.SpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space)); + // Insert space after function keyword for anonymous functions this.SpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space)); this.NoSpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Delete)); diff --git a/src/services/formatting/rulesProvider.ts b/src/services/formatting/rulesProvider.ts index f6cf1de474b..48a783dd0c6 100644 --- a/src/services/formatting/rulesProvider.ts +++ b/src/services/formatting/rulesProvider.ts @@ -71,15 +71,24 @@ namespace ts.formatting { rules.push(this.globalRules.NoSpaceBetweenParens); } - if ( options.InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets ) { - rules.push( this.globalRules.SpaceAfterOpenBracket ); - rules.push( this.globalRules.SpaceBeforeCloseBracket ); - rules.push( this.globalRules.NoSpaceBetweenBrackets ); + if (options.InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets) { + rules.push(this.globalRules.SpaceAfterOpenBracket); + rules.push(this.globalRules.SpaceBeforeCloseBracket); + rules.push(this.globalRules.NoSpaceBetweenBrackets); } else { - rules.push( this.globalRules.NoSpaceAfterOpenBracket ); - rules.push( this.globalRules.NoSpaceBeforeCloseBracket ); - rules.push( this.globalRules.NoSpaceBetweenBrackets ); + rules.push(this.globalRules.NoSpaceAfterOpenBracket); + rules.push(this.globalRules.NoSpaceBeforeCloseBracket); + rules.push(this.globalRules.NoSpaceBetweenBrackets); + } + + if (options.InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces) { + rules.push(this.globalRules.SpaceAfterTemplateHeadAndMiddle); + rules.push(this.globalRules.SpaceBeforeTemplateMiddleAndTail); + } + else { + rules.push(this.globalRules.NoSpaceAfterTemplateHeadAndMiddle); + rules.push(this.globalRules.NoSpaceBeforeTemplateMiddleAndTail); } if (options.InsertSpaceAfterSemicolonInForStatements) { diff --git a/src/services/services.ts b/src/services/services.ts index a9dda549ead..04a3b865bdb 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1218,6 +1218,7 @@ namespace ts { InsertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean; InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean; InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean; + InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; [s: string]: boolean | number| string; diff --git a/tests/cases/fourslash/formatTemplateLiteral.ts b/tests/cases/fourslash/formatTemplateLiteral.ts index 68f2c8c9469..a10f8dba8f2 100644 --- a/tests/cases/fourslash/formatTemplateLiteral.ts +++ b/tests/cases/fourslash/formatTemplateLiteral.ts @@ -32,9 +32,9 @@ verify.currentLineContentIs("let w = `bar${3}`;"); goTo.marker("5"); verify.currentLineContentIs(" `template`;"); goTo.marker("6"); -verify.currentLineContentIs("String.raw `foo`;"); +verify.currentLineContentIs("String.raw`foo`;"); goTo.marker("7"); -verify.currentLineContentIs("String.raw `bar${3}`;"); +verify.currentLineContentIs("String.raw`bar${3}`;"); goTo.marker("spaceInside"); verify.currentLineContentIs('`Write ${JSON.stringify("")} and ${(765)} and ${346}`;'); \ No newline at end of file diff --git a/tests/cases/fourslash/formattingOptionsChange.ts b/tests/cases/fourslash/formattingOptionsChange.ts index cdd8f61a215..a9c49d72507 100644 --- a/tests/cases/fourslash/formattingOptionsChange.ts +++ b/tests/cases/fourslash/formattingOptionsChange.ts @@ -6,7 +6,8 @@ /////*InsertSpaceAfterKeywordsInControlFlowStatements*/if (true) { } /////*InsertSpaceAfterFunctionKeywordForAnonymousFunctions*/(function () { }) /////*InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis*/(1 ) -/////*InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets*/[1 ]; [ ]; []; [,] +/////*InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets*/[1 ]; [ ]; []; [,]; +/////*InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces*/`${1}`;`${ 1 }` /////*PlaceOpenBraceOnNewLineForFunctions*/class foo { ////} /////*PlaceOpenBraceOnNewLineForControlBlocks*/if (true) { @@ -18,7 +19,8 @@ runTest("InsertSpaceBeforeAndAfterBinaryOperators", "1 + 2 - 3", "1+2-3"); runTest("InsertSpaceAfterKeywordsInControlFlowStatements", "if (true) { }", "if(true) { }"); runTest("InsertSpaceAfterFunctionKeywordForAnonymousFunctions", "(function () { })", "(function() { })"); runTest("InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis", " ( 1 )", " (1)"); -runTest("InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets", "[ 1 ];[];[];[ , ]", "[1];[];[];[, ]"); +runTest("InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets", "[ 1 ];[];[];[ , ];", "[1];[];[];[, ];"); +runTest("InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces", "`${ 1 }`; `${ 1 }`", "`${1}`; `${1}`"); runTest("PlaceOpenBraceOnNewLineForFunctions", "class foo", "class foo {"); runTest("PlaceOpenBraceOnNewLineForControlBlocks", "if ( true )", "if ( true ) {"); diff --git a/tests/cases/fourslash/formattingTemplates.ts b/tests/cases/fourslash/formattingTemplates.ts index c7decd10316..c759376335d 100644 --- a/tests/cases/fourslash/formattingTemplates.ts +++ b/tests/cases/fourslash/formattingTemplates.ts @@ -5,8 +5,8 @@ goTo.marker("1"); edit.insert(";"); -verify.currentLineContentIs("String.call `${123}`;"); +verify.currentLineContentIs("String.call`${123}`;"); goTo.marker("2"); edit.insert(";"); -verify.currentLineContentIs("String.call `${123} ${456}`;"); \ No newline at end of file +verify.currentLineContentIs("String.call`${123} ${456}`;"); \ No newline at end of file diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index b9b379bd465..febc48ff340 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -81,6 +81,7 @@ declare namespace FourSlashInterface { InsertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean; InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean; InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean; + InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; [s: string]: boolean | number | string;