diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 9106c0ef442a6..819c4797084fc 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -3418,6 +3418,7 @@ export interface FormatCodeSettings extends EditorSettings { placeOpenBraceOnNewLineForControlBlocks?: boolean; insertSpaceBeforeTypeAnnotation?: boolean; semicolons?: SemicolonPreference; + indentSwitchCase?: boolean; } export interface UserPreferences { diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index b48051e8a651d..1ab72e8c99bb2 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -653,9 +653,6 @@ export namespace SmartIndenter { case SyntaxKind.TypeLiteral: case SyntaxKind.MappedType: case SyntaxKind.TupleType: - case SyntaxKind.CaseBlock: - case SyntaxKind.DefaultClause: - case SyntaxKind.CaseClause: case SyntaxKind.ParenthesizedExpression: case SyntaxKind.PropertyAccessExpression: case SyntaxKind.CallExpression: @@ -684,7 +681,11 @@ export namespace SmartIndenter { case SyntaxKind.ExportSpecifier: case SyntaxKind.ImportSpecifier: case SyntaxKind.PropertyDeclaration: + case SyntaxKind.CaseClause: + case SyntaxKind.DefaultClause: return true; + case SyntaxKind.CaseBlock: + return settings.indentSwitchCase ?? true; case SyntaxKind.VariableDeclaration: case SyntaxKind.PropertyAssignment: case SyntaxKind.BinaryExpression: diff --git a/src/services/types.ts b/src/services/types.ts index cf3205a88afb0..08d983b8691c9 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -1118,6 +1118,7 @@ export interface FormatCodeSettings extends EditorSettings { readonly insertSpaceBeforeTypeAnnotation?: boolean; readonly indentMultiLineObjectLiteralBeginningOnBlankLine?: boolean; readonly semicolons?: SemicolonPreference; + readonly indentSwitchCase?: boolean; } export function getDefaultFormatCodeSettings(newLineCharacter?: string): FormatCodeSettings { @@ -1142,7 +1143,8 @@ export function getDefaultFormatCodeSettings(newLineCharacter?: string): FormatC placeOpenBraceOnNewLineForFunctions: false, placeOpenBraceOnNewLineForControlBlocks: false, semicolons: SemicolonPreference.Ignore, - trimTrailingWhitespace: true + trimTrailingWhitespace: true, + indentSwitchCase: true }; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5355faa1d1b99..4bf70d659b1ff 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2718,6 +2718,7 @@ declare namespace ts { placeOpenBraceOnNewLineForControlBlocks?: boolean; insertSpaceBeforeTypeAnnotation?: boolean; semicolons?: SemicolonPreference; + indentSwitchCase?: boolean; } interface UserPreferences { readonly disableSuggestions?: boolean; @@ -10524,6 +10525,7 @@ declare namespace ts { readonly insertSpaceBeforeTypeAnnotation?: boolean; readonly indentMultiLineObjectLiteralBeginningOnBlankLine?: boolean; readonly semicolons?: SemicolonPreference; + readonly indentSwitchCase?: boolean; } interface DefinitionInfo extends DocumentSpan { kind: ScriptElementKind; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index b923402b208b8..6acc0c5bc906e 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -6594,6 +6594,7 @@ declare namespace ts { readonly insertSpaceBeforeTypeAnnotation?: boolean; readonly indentMultiLineObjectLiteralBeginningOnBlankLine?: boolean; readonly semicolons?: SemicolonPreference; + readonly indentSwitchCase?: boolean; } interface DefinitionInfo extends DocumentSpan { kind: ScriptElementKind; diff --git a/tests/baselines/reference/tsserver/formatSettings/works-when-extends-is-specified-with-a-case-insensitive-file-system.js b/tests/baselines/reference/tsserver/formatSettings/works-when-extends-is-specified-with-a-case-insensitive-file-system.js index 55fbbd968dd19..2f303757fd4f4 100644 --- a/tests/baselines/reference/tsserver/formatSettings/works-when-extends-is-specified-with-a-case-insensitive-file-system.js +++ b/tests/baselines/reference/tsserver/formatSettings/works-when-extends-is-specified-with-a-case-insensitive-file-system.js @@ -76,7 +76,8 @@ Info seq [hh:mm:ss:mss] request: "placeOpenBraceOnNewLineForFunctions": false, "placeOpenBraceOnNewLineForControlBlocks": true, "semicolons": "ignore", - "trimTrailingWhitespace": true + "trimTrailingWhitespace": true, + "indentSwitchCase": true } }, "seq": 2, @@ -112,7 +113,8 @@ FormatCodeOptions should be global:: /a/b/app.ts:: { "placeOpenBraceOnNewLineForFunctions": false, "placeOpenBraceOnNewLineForControlBlocks": true, "semicolons": "ignore", - "trimTrailingWhitespace": true + "trimTrailingWhitespace": true, + "indentSwitchCase": true } Before request @@ -141,7 +143,8 @@ Info seq [hh:mm:ss:mss] request: "placeOpenBraceOnNewLineForFunctions": false, "placeOpenBraceOnNewLineForControlBlocks": false, "semicolons": "ignore", - "trimTrailingWhitespace": true + "trimTrailingWhitespace": true, + "indentSwitchCase": true }, "file": "/a/b/app.ts" }, @@ -178,7 +181,8 @@ FormatCodeOptions should be per file:: /a/b/app.ts:: { "placeOpenBraceOnNewLineForFunctions": false, "placeOpenBraceOnNewLineForControlBlocks": false, "semicolons": "ignore", - "trimTrailingWhitespace": true + "trimTrailingWhitespace": true, + "indentSwitchCase": true } Before request @@ -207,7 +211,8 @@ Info seq [hh:mm:ss:mss] request: "placeOpenBraceOnNewLineForFunctions": false, "placeOpenBraceOnNewLineForControlBlocks": false, "semicolons": "ignore", - "trimTrailingWhitespace": true + "trimTrailingWhitespace": true, + "indentSwitchCase": true } }, "seq": 4, @@ -243,5 +248,6 @@ FormatCodeOptions should be per file:: /a/b/app.ts:: { "placeOpenBraceOnNewLineForFunctions": false, "placeOpenBraceOnNewLineForControlBlocks": false, "semicolons": "ignore", - "trimTrailingWhitespace": true + "trimTrailingWhitespace": true, + "indentSwitchCase": true } \ No newline at end of file diff --git a/tests/cases/fourslash/formattingIndentSwitchCase.ts b/tests/cases/fourslash/formattingIndentSwitchCase.ts new file mode 100644 index 0000000000000..90535e3680c09 --- /dev/null +++ b/tests/cases/fourslash/formattingIndentSwitchCase.ts @@ -0,0 +1,31 @@ +/// + +////let foo = 1; +////switch (foo) { +/////*1*/case 0: +/////*2*/break; +/////*3*/default: +/////*4*/break; +////} + +format.setOption('indentSwitchCase', true); +format.document(); +goTo.marker('1'); +verify.indentationIs(4); +goTo.marker('2'); +verify.indentationIs(8); +goTo.marker('3'); +verify.indentationIs(4); +goTo.marker('4'); +verify.indentationIs(8); + +format.setOption('indentSwitchCase', false); +format.document(); +goTo.marker('1'); +verify.indentationIs(0); +goTo.marker('2'); +verify.indentationIs(4); +goTo.marker('3'); +verify.indentationIs(0); +goTo.marker('4'); +verify.indentationIs(4); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index b9f1fecbc2b34..2bf83ba52e5f7 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -196,6 +196,7 @@ declare namespace FourSlashInterface { readonly insertSpaceBeforeTypeAnnotation?: boolean; readonly indentMultiLineObjectLiteralBeginningOnBlankLine?: boolean; readonly semicolons?: ts.SemicolonPreference; + readonly indentSwitchCase?: boolean; } interface Range { fileName: string;