|
40 | 40 | indent: state.indent && state.indent.slice(0)}; |
41 | 41 | if (state.localState) |
42 | 42 | s.localState = CodeMirror.copyState(state.local.mode, state.localState); |
| 43 | + if (state.stack) |
| 44 | + s.stack = state.stack.slice(0); |
43 | 45 | for (var pers = state.persistentStates; pers; pers = pers.next) |
44 | 46 | s.persistentStates = {mode: pers.mode, |
45 | 47 | spec: pers.spec, |
|
83 | 85 | } |
84 | 86 |
|
85 | 87 | function Rule(data, states) { |
86 | | - if (data.next) ensureState(states, data.next); |
| 88 | + if (data.next || data.push) ensureState(states, data.next || data.push); |
87 | 89 | this.regex = toRegex(data.regex); |
88 | 90 | this.token = asToken(data.token); |
89 | 91 | this.data = data; |
|
116 | 118 | var rule = curState[i]; |
117 | 119 | var matches = stream.match(rule.regex); |
118 | 120 | if (matches) { |
119 | | - if (rule.data.next) |
| 121 | + if (rule.data.next) { |
120 | 122 | state.state = rule.data.next; |
| 123 | + } else if (rule.data.push) { |
| 124 | + (state.stack || (state.stack = [])).push(state.state); |
| 125 | + state.state = rule.data.push; |
| 126 | + } else if (rule.data.pop && state.stack && state.stack.length) { |
| 127 | + state.state = state.stack.pop(); |
| 128 | + } |
| 129 | + |
121 | 130 | if (rule.data.mode) |
122 | 131 | enterLocalMode(config, state, rule.data.mode, rule.token); |
123 | 132 | if (rule.data.indent) |
|
127 | 136 | if (matches.length > 2) { |
128 | 137 | state.pending = []; |
129 | 138 | for (var j = 2; j < matches.length; j++) |
130 | | - state.pending.push({text: matches[j], token: rule.token[j - 1]}); |
131 | | - stream.backUp(matches[0].length - matches[1].length); |
| 139 | + if (matches[j]) |
| 140 | + state.pending.push({text: matches[j], token: rule.token[j - 1]}); |
| 141 | + stream.backUp(matches[0].length - (matches[1] ? matches[1].length : 0)); |
132 | 142 | return rule.token[0]; |
133 | 143 | } else if (rule.token && rule.token.join) { |
134 | 144 | return rule.token[0]; |
|
185 | 195 | scan: for (;;) { |
186 | 196 | for (var i = 0; i < rules.length; i++) { |
187 | 197 | var rule = rules[i], m = rule.regex.exec(textAfter); |
188 | | - if (m) { |
| 198 | + if (m && m[0]) { |
189 | 199 | if (rule.data.dedent && rule.data.dedentIfLineStart !== false) pos--; |
190 | | - if (rule.next) rules = states[rule.next]; |
| 200 | + if (rule.next || rule.push) rules = states[rule.next || rule.push]; |
191 | 201 | textAfter = textAfter.slice(m[0].length); |
192 | 202 | continue scan; |
193 | 203 | } |
|
0 commit comments