Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
| Download
Views: 39598
1
###
2
Multiplexing mode -- exactly like the original CodeMirror multiplexingMode,
3
https://codemirror.net/demo/multiplex.html,
4
except use the option start:true to make it so the mode switch pattern
5
must be at the beginning of the line.
6
7
Original copyright on https://codemirror.net/addon/mode/multiplex.js:
8
CodeMirror, copyright (c) by Marijn Haverbeke and others
9
Distributed under an MIT license: http://codemirror.net/LICENSE
10
###
11
12
13
CodeMirror.smc_multiplexing_mode = (outer) ->
14
# Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects
15
others = Array::slice.call(arguments, 1)
16
17
indexOf = (string, pattern, from, returnEnd) ->
18
if typeof pattern == 'string'
19
found = string.indexOf(pattern, from)
20
if returnEnd and found > -1
21
return found + pattern.length
22
else
23
return found
24
m = pattern.exec(if from then string.slice(from) else string)
25
if m
26
return m.index + from + (if returnEnd then m[0].length else 0)
27
else
28
return -1
29
30
31
obj =
32
33
startState: ->
34
outer : CodeMirror.startState(outer)
35
innerActive : null
36
inner : null
37
38
copyState: (state) ->
39
outer : CodeMirror.copyState(outer, state.outer)
40
innerActive : state.innerActive
41
inner : state.innerActive and CodeMirror.copyState(state.innerActive.mode, state.inner)
42
43
token: (stream, state) ->
44
oldContent = found = undefined
45
if not state.innerActive
46
cutOff = Infinity
47
oldContent = stream.string
48
for other in others
49
if other.start and oldContent.slice(0,other.open.length) != other.open
50
continue
51
found = indexOf(oldContent, other.open, stream.pos)
52
if found == stream.pos
53
if not other.parseDelimiters
54
stream.match other.open
55
state.innerActive = other
56
state.inner = CodeMirror.startState(other.mode, if outer.indent then outer.indent(state.outer, '') else 0)
57
return other.delimStyle and other.delimStyle + ' ' + other.delimStyle + '-open'
58
else if found != -1 and found < cutOff
59
cutOff = found
60
if cutOff != Infinity
61
stream.string = oldContent.slice(0, cutOff)
62
outerToken = outer.token(stream, state.outer)
63
if cutOff != Infinity
64
stream.string = oldContent
65
return outerToken
66
else
67
curInner = state.innerActive
68
oldContent = stream.string
69
if not curInner.close and stream.sol()
70
state.innerActive = state.inner = null
71
return @token(stream, state)
72
found = if curInner.close then indexOf(oldContent, curInner.close, stream.pos, curInner.parseDelimiters) else -1
73
if found == stream.pos and not curInner.parseDelimiters
74
stream.match curInner.close
75
state.innerActive = state.inner = null
76
return curInner.delimStyle and curInner.delimStyle + ' ' + curInner.delimStyle + '-close'
77
if found > -1
78
stream.string = oldContent.slice(0, found)
79
innerToken = curInner.mode.token(stream, state.inner)
80
if found > -1
81
stream.string = oldContent
82
if found == stream.pos and curInner.parseDelimiters
83
state.innerActive = state.inner = null
84
if curInner.innerStyle
85
if innerToken
86
innerToken = innerToken + ' ' + curInner.innerStyle
87
else
88
innerToken = curInner.innerStyle
89
return innerToken
90
91
indent: (state, textAfter) ->
92
mode = if state.innerActive then state.innerActive.mode else outer
93
if not mode.indent
94
return CodeMirror.Pass
95
return mode.indent((if state.innerActive then state.inner else state.outer), textAfter)
96
97
blankLine: (state) ->
98
mode = if state.innerActive then state.innerActive.mode else outer
99
if mode.blankLine
100
mode.blankLine if state.innerActive then state.inner else state.outer
101
if not state.innerActive
102
i = 0
103
while i < others.length
104
other = others[i]
105
if other.open == '\n'
106
state.innerActive = other
107
state.inner = CodeMirror.startState(other.mode, if mode.indent then mode.indent(state.outer, '') else 0)
108
++i
109
else if state.innerActive.close == '\n'
110
state.innerActive = state.inner = null
111
return
112
113
electricChars: outer.electricChars
114
115
innerMode: (state) ->
116
if state.inner
117
state : state.inner
118
mode : state.innerActive.mode
119
else
120
state : state.outer
121
mode : outer
122
123
return obj
124
125