@@ -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 && ! / ^ (?: c a s e | d e f a u l t ) \b / . test ( textAfter ) ? indentUnit : 0 ) ;
172186 } ,
173187
174- electricChars : "{}" ,
188+ electricInput : indentSwitch ? / ^ \s * (?: c a s e . * ? : | d e f a u l t : | \{ | \} ) $ / : / ^ \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