Skip to content
This repository was archived by the owner on Apr 16, 2026. It is now read-only.

Commit 981888e

Browse files
committed
[clike mode] Add switchIndent option for deep indentation of switch blocks
Enable it for the languages that have switch. Issue #3252
1 parent 8ba727a commit 981888e

1 file changed

Lines changed: 29 additions & 13 deletions

File tree

mode/clike/clike.js

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
2121
atoms = parserConfig.atoms || {},
2222
hooks = parserConfig.hooks || {},
2323
multiLineStrings = parserConfig.multiLineStrings,
24-
indentStatements = parserConfig.indentStatements !== false;
24+
indentStatements = parserConfig.indentStatements !== false,
25+
indentSwitch = parserConfig.indentSwitch !== false;
2526
var isOperatorChar = /[+\-*&%=<>!?|\/]/;
2627

2728
var curPunc;
@@ -104,9 +105,12 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
104105
this.align = align;
105106
this.prev = prev;
106107
}
108+
function isStatement(context) {
109+
return context.type == "statement" || context.type == "switchstatement";
110+
}
107111
function pushContext(state, col, type) {
108112
var indent = state.indented;
109-
if (state.context && state.context.type == "statement")
113+
if (state.context && isStatement(state.context))
110114
indent = state.context.indented;
111115
return state.context = new Context(indent, col, type, null, state.context);
112116
}
@@ -142,36 +146,46 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
142146
if (style == "comment" || style == "meta") return style;
143147
if (ctx.align == null) ctx.align = true;
144148

145-
if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
149+
if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && isStatement(ctx)) popContext(state);
146150
else if (curPunc == "{") pushContext(state, stream.column(), "}");
147151
else if (curPunc == "[") pushContext(state, stream.column(), "]");
148152
else if (curPunc == "(") pushContext(state, stream.column(), ")");
149153
else if (curPunc == "}") {
150-
while (ctx.type == "statement") ctx = popContext(state);
154+
while (isStatement(ctx)) ctx = popContext(state);
151155
if (ctx.type == "}") ctx = popContext(state);
152-
while (ctx.type == "statement") ctx = popContext(state);
156+
while (isStatement(ctx)) ctx = popContext(state);
153157
}
154158
else if (curPunc == ctx.type) popContext(state);
155159
else if (indentStatements &&
156160
(((ctx.type == "}" || ctx.type == "top") && curPunc != ';') ||
157-
(ctx.type == "statement" && curPunc == "newstatement")))
158-
pushContext(state, stream.column(), "statement");
161+
(isStatement(ctx) && curPunc == "newstatement"))) {
162+
var type = "statement"
163+
if (curPunc == "newstatement" && indentSwitch && stream.current() == "switch")
164+
type = "switchstatement"
165+
pushContext(state, stream.column(), type);
166+
}
159167
state.startOfLine = false;
160168
return style;
161169
},
162170

163171
indent: function(state, textAfter) {
164172
if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
165173
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
166-
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
174+
if (isStatement(ctx) && firstChar == "}") ctx = ctx.prev;
167175
var closing = firstChar == ctx.type;
168-
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
169-
else if (ctx.align && (!dontAlignCalls || ctx.type != ")")) return ctx.column + (closing ? 0 : 1);
170-
else if (ctx.type == ")" && !closing) return ctx.indented + statementIndentUnit;
171-
else return ctx.indented + (closing ? 0 : indentUnit);
176+
var switchBlock = ctx.prev && ctx.prev.type == "switchstatement";
177+
if (isStatement(ctx))
178+
return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
179+
if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
180+
return ctx.column + (closing ? 0 : 1);
181+
if (ctx.type == ")" && !closing)
182+
return ctx.indented + statementIndentUnit;
183+
184+
return ctx.indented + (closing ? 0 : indentUnit) +
185+
(!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0);
172186
},
173187

174-
electricChars: "{}",
188+
electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{|\})$/ : /^\s*[{}]$/,
175189
blockCommentStart: "/*",
176190
blockCommentEnd: "*/",
177191
lineComment: "//",
@@ -389,6 +403,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
389403
blockKeywords: words("catch class do else finally for forSome if match switch try while"),
390404
atoms: words("true false null"),
391405
indentStatements: false,
406+
indentSwitch: false,
392407
hooks: {
393408
"@": function(stream) {
394409
stream.eatWhile(/[\w\$_]/);
@@ -461,6 +476,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
461476
"gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
462477
"gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
463478
"gl_MaxDrawBuffers"),
479+
indentSwitch: false,
464480
hooks: {"#": cppHook},
465481
modeProps: {fold: ["brace", "include"]}
466482
});

0 commit comments

Comments
 (0)