diff options
Diffstat (limited to 'imports/codemirror/mode/smalltalk/smalltalk.js')
-rwxr-xr-x | imports/codemirror/mode/smalltalk/smalltalk.js | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/imports/codemirror/mode/smalltalk/smalltalk.js b/imports/codemirror/mode/smalltalk/smalltalk.js new file mode 100755 index 00000000..e002e666 --- /dev/null +++ b/imports/codemirror/mode/smalltalk/smalltalk.js | |||
@@ -0,0 +1,139 @@ | |||
1 | CodeMirror.defineMode('smalltalk', function(config, modeConfig) { | ||
2 | |||
3 | var specialChars = /[+\-/\\*~<>=@%|&?!.:;^]/; | ||
4 | var keywords = /true|false|nil|self|super|thisContext/; | ||
5 | |||
6 | var Context = function(tokenizer, parent) { | ||
7 | this.next = tokenizer; | ||
8 | this.parent = parent; | ||
9 | }; | ||
10 | |||
11 | var Token = function(name, context, eos) { | ||
12 | this.name = name; | ||
13 | this.context = context; | ||
14 | this.eos = eos; | ||
15 | }; | ||
16 | |||
17 | var State = function() { | ||
18 | this.context = new Context(next, null); | ||
19 | this.expectVariable = true; | ||
20 | this.indentation = 0; | ||
21 | this.userIndentationDelta = 0; | ||
22 | }; | ||
23 | |||
24 | State.prototype.userIndent = function(indentation) { | ||
25 | this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0; | ||
26 | }; | ||
27 | |||
28 | var next = function(stream, context, state) { | ||
29 | var token = new Token(null, context, false); | ||
30 | var char = stream.next(); | ||
31 | |||
32 | if (char === '"') { | ||
33 | token = nextComment(stream, new Context(nextComment, context)); | ||
34 | |||
35 | } else if (char === '\'') { | ||
36 | token = nextString(stream, new Context(nextString, context)); | ||
37 | |||
38 | } else if (char === '#') { | ||
39 | stream.eatWhile(/[^ .]/); | ||
40 | token.name = 'string-2'; | ||
41 | |||
42 | } else if (char === '$') { | ||
43 | stream.eatWhile(/[^ ]/); | ||
44 | token.name = 'string-2'; | ||
45 | |||
46 | } else if (char === '|' && state.expectVariable) { | ||
47 | token.context = new Context(nextTemporaries, context); | ||
48 | |||
49 | } else if (/[\[\]{}()]/.test(char)) { | ||
50 | token.name = 'bracket'; | ||
51 | token.eos = /[\[{(]/.test(char); | ||
52 | |||
53 | if (char === '[') { | ||
54 | state.indentation++; | ||
55 | } else if (char === ']') { | ||
56 | state.indentation = Math.max(0, state.indentation - 1); | ||
57 | } | ||
58 | |||
59 | } else if (specialChars.test(char)) { | ||
60 | stream.eatWhile(specialChars); | ||
61 | token.name = 'operator'; | ||
62 | token.eos = char !== ';'; // ; cascaded message expression | ||
63 | |||
64 | } else if (/\d/.test(char)) { | ||
65 | stream.eatWhile(/[\w\d]/); | ||
66 | token.name = 'number' | ||
67 | |||
68 | } else if (/[\w_]/.test(char)) { | ||
69 | stream.eatWhile(/[\w\d_]/); | ||
70 | token.name = state.expectVariable ? (keywords.test(stream.current()) ? 'keyword' : 'variable') : null; | ||
71 | |||
72 | } else { | ||
73 | token.eos = state.expectVariable; | ||
74 | } | ||
75 | |||
76 | return token; | ||
77 | }; | ||
78 | |||
79 | var nextComment = function(stream, context) { | ||
80 | stream.eatWhile(/[^"]/); | ||
81 | return new Token('comment', stream.eat('"') ? context.parent : context, true); | ||
82 | }; | ||
83 | |||
84 | var nextString = function(stream, context) { | ||
85 | stream.eatWhile(/[^']/); | ||
86 | return new Token('string', stream.eat('\'') ? context.parent : context, false); | ||
87 | }; | ||
88 | |||
89 | var nextTemporaries = function(stream, context, state) { | ||
90 | var token = new Token(null, context, false); | ||
91 | var char = stream.next(); | ||
92 | |||
93 | if (char === '|') { | ||
94 | token.context = context.parent; | ||
95 | token.eos = true; | ||
96 | |||
97 | } else { | ||
98 | stream.eatWhile(/[^|]/); | ||
99 | token.name = 'variable'; | ||
100 | } | ||
101 | |||
102 | return token; | ||
103 | } | ||
104 | |||
105 | return { | ||
106 | startState: function() { | ||
107 | return new State; | ||
108 | }, | ||
109 | |||
110 | token: function(stream, state) { | ||
111 | state.userIndent(stream.indentation()); | ||
112 | |||
113 | if (stream.eatSpace()) { | ||
114 | return null; | ||
115 | } | ||
116 | |||
117 | var token = state.context.next(stream, state.context, state); | ||
118 | state.context = token.context; | ||
119 | state.expectVariable = token.eos; | ||
120 | |||
121 | state.lastToken = token; | ||
122 | return token.name; | ||
123 | }, | ||
124 | |||
125 | blankLine: function(state) { | ||
126 | state.userIndent(0); | ||
127 | }, | ||
128 | |||
129 | indent: function(state, textAfter) { | ||
130 | var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta; | ||
131 | return (state.indentation + i) * config.indentUnit; | ||
132 | }, | ||
133 | |||
134 | electricChars: ']' | ||
135 | }; | ||
136 | |||
137 | }); | ||
138 | |||
139 | CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'}); \ No newline at end of file | ||