         else 'apl-glb'
       else 'apl-err'
 
-  indent: (state, textAfter) -> config.indentUnit * (state.dfnDepth - /^\s*\}/.test textAfter)
+  electricInput: /:(?:else|end|andif|orif)$/
+
+  indent: (state, textAfter) ->
+    config.indentUnit *
+      if state.dfnDepth
+        state.dfnDepth - /^\s*\}/.test textAfter
+      else
+        state.kwStack.length - /^\s*:(?:end|else|andif|orif)/i.test textAfter

      else if /[\+\-×÷⌈⌊\|⍳\?\*⍟○!⌹<≤=>≥≠≡≢∊⍷∪∩~∨∧⍱⍲⍴,⍪⌽⊖⍉↑↓⊂⊃⌷⍋⍒⊤⊥⍕⍎⊣⊢→]/.test c then 'apl-fn'
      else if state.dfnDepth && /[⍺⍵∇:]/.test c then "apl-dfn apl-dfn#{state.dfnDepth}"
      else if c == '∇' then state.isHeader = 1; 'apl-trad'
      else if c == ':' then (if stream.match(/\w*/)?[0]?.toLowerCase() in keywords then 'apl-kw' else 'apl-err')
      else if c == '⎕' then (if stream.match(/[áa-z0-9]*/i)?[0].toLowerCase() in quadNames then 'apl-quad' else 'apl-err')
      else if c == '⍞' then 'apl-quad'
      else if c == '#' then 'apl-ns'


CodeMirror.defineMIME 'text/apl', 'apl'
CodeMirror.defineMode 'apl', (config) -> # https://codemirror.net/doc/manual.html#modeapi
  startState: -> isHeader: 1, stack: '', dfnDepth: 0, kwStack: []
  token: (stream, state) ->
    if state.isHeader
      delete state.isHeader; stream.match /[^⍝\n\r]*/; s = stream.current()
