Skip to content

Commit 54aedf0

Browse files
committed
Merge pull request microsoft#6202 from SaschaNaz/formatTemplateOptional
Optionally insert spaces between template string braces
2 parents 93e942e + e97118e commit 54aedf0

File tree

9 files changed

+39
-18
lines changed

9 files changed

+39
-18
lines changed

src/harness/fourslash.ts

+1
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ namespace FourSlash {
317317
InsertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
318318
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
319319
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
320+
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
320321
PlaceOpenBraceOnNewLineForFunctions: false,
321322
PlaceOpenBraceOnNewLineForControlBlocks: false,
322323
};

src/server/editorServices.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,7 @@ namespace ts.server {
13321332
InsertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
13331333
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
13341334
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
1335+
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
13351336
PlaceOpenBraceOnNewLineForFunctions: false,
13361337
PlaceOpenBraceOnNewLineForControlBlocks: false,
13371338
};

src/services/formatting/rules.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,11 @@ namespace ts.formatting {
219219
public SpaceBetweenAsyncAndFunctionKeyword: Rule;
220220

221221
// Template strings
222-
public SpaceBetweenTagAndTemplateString: Rule;
222+
public NoSpaceBetweenTagAndTemplateString: Rule;
223223
public NoSpaceAfterTemplateHeadAndMiddle: Rule;
224+
public SpaceAfterTemplateHeadAndMiddle: Rule;
224225
public NoSpaceBeforeTemplateMiddleAndTail: Rule;
226+
public SpaceBeforeTemplateMiddleAndTail: Rule;
225227

226228
constructor() {
227229
///
@@ -376,9 +378,7 @@ namespace ts.formatting {
376378
this.SpaceBetweenAsyncAndFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.AsyncKeyword, SyntaxKind.FunctionKeyword), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space));
377379

378380
// template string
379-
this.SpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space));
380-
this.NoSpaceAfterTemplateHeadAndMiddle = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
381-
this.NoSpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
381+
this.NoSpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
382382

383383
// These rules are higher in priority than user-configurable rules.
384384
this.HighPriorityCommonRules = [
@@ -406,7 +406,7 @@ namespace ts.formatting {
406406
this.SpaceBeforeBinaryKeywordOperator, this.SpaceAfterBinaryKeywordOperator,
407407
this.SpaceAfterVoidOperator,
408408
this.SpaceBetweenAsyncAndOpenParen, this.SpaceBetweenAsyncAndFunctionKeyword,
409-
this.SpaceBetweenTagAndTemplateString, this.NoSpaceAfterTemplateHeadAndMiddle, this.NoSpaceBeforeTemplateMiddleAndTail,
409+
this.NoSpaceBetweenTagAndTemplateString,
410410

411411
// TypeScript-specific rules
412412
this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport,
@@ -485,6 +485,12 @@ namespace ts.formatting {
485485
this.NoSpaceAfterOpenBracket = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBracketToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
486486
this.NoSpaceBeforeCloseBracket = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBracketToken), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
487487

488+
// Insert space after opening and before closing template string braces
489+
this.NoSpaceAfterTemplateHeadAndMiddle = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
490+
this.SpaceAfterTemplateHeadAndMiddle = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.TemplateHead, SyntaxKind.TemplateMiddle]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space));
491+
this.NoSpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Delete));
492+
this.SpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsSameLineTokenContext), RuleAction.Space));
493+
488494
// Insert space after function keyword for anonymous functions
489495
this.SpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space));
490496
this.NoSpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Delete));

src/services/formatting/rulesProvider.ts

+16-7
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,24 @@ namespace ts.formatting {
7171
rules.push(this.globalRules.NoSpaceBetweenParens);
7272
}
7373

74-
if ( options.InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets ) {
75-
rules.push( this.globalRules.SpaceAfterOpenBracket );
76-
rules.push( this.globalRules.SpaceBeforeCloseBracket );
77-
rules.push( this.globalRules.NoSpaceBetweenBrackets );
74+
if (options.InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets) {
75+
rules.push(this.globalRules.SpaceAfterOpenBracket);
76+
rules.push(this.globalRules.SpaceBeforeCloseBracket);
77+
rules.push(this.globalRules.NoSpaceBetweenBrackets);
7878
}
7979
else {
80-
rules.push( this.globalRules.NoSpaceAfterOpenBracket );
81-
rules.push( this.globalRules.NoSpaceBeforeCloseBracket );
82-
rules.push( this.globalRules.NoSpaceBetweenBrackets );
80+
rules.push(this.globalRules.NoSpaceAfterOpenBracket);
81+
rules.push(this.globalRules.NoSpaceBeforeCloseBracket);
82+
rules.push(this.globalRules.NoSpaceBetweenBrackets);
83+
}
84+
85+
if (options.InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces) {
86+
rules.push(this.globalRules.SpaceAfterTemplateHeadAndMiddle);
87+
rules.push(this.globalRules.SpaceBeforeTemplateMiddleAndTail);
88+
}
89+
else {
90+
rules.push(this.globalRules.NoSpaceAfterTemplateHeadAndMiddle);
91+
rules.push(this.globalRules.NoSpaceBeforeTemplateMiddleAndTail);
8392
}
8493

8594
if (options.InsertSpaceAfterSemicolonInForStatements) {

src/services/services.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,7 @@ namespace ts {
12181218
InsertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean;
12191219
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean;
12201220
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean;
1221+
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean;
12211222
PlaceOpenBraceOnNewLineForFunctions: boolean;
12221223
PlaceOpenBraceOnNewLineForControlBlocks: boolean;
12231224
[s: string]: boolean | number | string;

tests/cases/fourslash/formatTemplateLiteral.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ verify.currentLineContentIs("let w = `bar${3}`;");
3232
goTo.marker("5");
3333
verify.currentLineContentIs(" `template`;");
3434
goTo.marker("6");
35-
verify.currentLineContentIs("String.raw `foo`;");
35+
verify.currentLineContentIs("String.raw`foo`;");
3636
goTo.marker("7");
37-
verify.currentLineContentIs("String.raw `bar${3}`;");
37+
verify.currentLineContentIs("String.raw`bar${3}`;");
3838

3939
goTo.marker("spaceInside");
4040
verify.currentLineContentIs('`Write ${JSON.stringify("")} and ${(765)} and ${346}`;');

tests/cases/fourslash/formattingOptionsChange.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
/////*InsertSpaceAfterKeywordsInControlFlowStatements*/if (true) { }
77
/////*InsertSpaceAfterFunctionKeywordForAnonymousFunctions*/(function () { })
88
/////*InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis*/(1 )
9-
/////*InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets*/[1 ]; [ ]; []; [,]
9+
/////*InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets*/[1 ]; [ ]; []; [,];
10+
/////*InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces*/`${1}`;`${ 1 }`
1011
/////*PlaceOpenBraceOnNewLineForFunctions*/class foo {
1112
////}
1213
/////*PlaceOpenBraceOnNewLineForControlBlocks*/if (true) {
@@ -18,7 +19,8 @@ runTest("InsertSpaceBeforeAndAfterBinaryOperators", "1 + 2 - 3", "1+2-3");
1819
runTest("InsertSpaceAfterKeywordsInControlFlowStatements", "if (true) { }", "if(true) { }");
1920
runTest("InsertSpaceAfterFunctionKeywordForAnonymousFunctions", "(function () { })", "(function() { })");
2021
runTest("InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis", " ( 1 )", " (1)");
21-
runTest("InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets", "[ 1 ];[];[];[ , ]", "[1];[];[];[, ]");
22+
runTest("InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets", "[ 1 ];[];[];[ , ];", "[1];[];[];[, ];");
23+
runTest("InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces", "`${ 1 }`; `${ 1 }`", "`${1}`; `${1}`");
2224
runTest("PlaceOpenBraceOnNewLineForFunctions", "class foo", "class foo {");
2325
runTest("PlaceOpenBraceOnNewLineForControlBlocks", "if ( true )", "if ( true ) {");
2426

tests/cases/fourslash/formattingTemplates.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
goTo.marker("1");
77
edit.insert(";");
8-
verify.currentLineContentIs("String.call `${123}`;");
8+
verify.currentLineContentIs("String.call`${123}`;");
99

1010
goTo.marker("2");
1111
edit.insert(";");
12-
verify.currentLineContentIs("String.call `${123} ${456}`;");
12+
verify.currentLineContentIs("String.call`${123} ${456}`;");

tests/cases/fourslash/fourslash.ts

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ declare namespace FourSlashInterface {
8181
InsertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean;
8282
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean;
8383
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean;
84+
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean;
8485
PlaceOpenBraceOnNewLineForFunctions: boolean;
8586
PlaceOpenBraceOnNewLineForControlBlocks: boolean;
8687
[s: string]: boolean | number | string;

0 commit comments

Comments
 (0)