aboutsummaryrefslogtreecommitdiff
path: root/imports/codemirror/mode/smalltalk
diff options
context:
space:
mode:
Diffstat (limited to 'imports/codemirror/mode/smalltalk')
-rwxr-xr-ximports/codemirror/mode/smalltalk/index.html55
-rwxr-xr-ximports/codemirror/mode/smalltalk/smalltalk.js139
2 files changed, 194 insertions, 0 deletions
diff --git a/imports/codemirror/mode/smalltalk/index.html b/imports/codemirror/mode/smalltalk/index.html
new file mode 100755
index 00000000..8a85c39e
--- /dev/null
+++ b/imports/codemirror/mode/smalltalk/index.html
@@ -0,0 +1,55 @@
1<!doctype html>
2<html>
3 <head>
4 <title>CodeMirror: Smalltalk mode</title>
5 <link rel="stylesheet" href="../../lib/codemirror.css">
6 <script src="../../lib/codemirror.js"></script>
7 <script src="smalltalk.js"></script>
8 <link rel="stylesheet" href="../../doc/docs.css">
9 <style>
10 .CodeMirror {border: 2px solid #dee; border-right-width: 10px;}
11 .CodeMirror-gutter {border: none; background: #dee;}
12 .CodeMirror-gutter pre {color: white; font-weight: bold;}
13 </style>
14 </head>
15 <body>
16 <h1>CodeMirror: Smalltalk mode</h1>
17
18<form><textarea id="code" name="code">
19"
20 This is a test of the Smalltalk code
21"
22Seaside.WAComponent subclass: #MyCounter [
23 | count |
24 MyCounter class &gt;&gt; canBeRoot [ ^true ]
25
26 initialize [
27 super initialize.
28 count := 0.
29 ]
30 states [ ^{ self } ]
31 renderContentOn: html [
32 html heading: count.
33 html anchor callback: [ count := count + 1 ]; with: '++'.
34 html space.
35 html anchor callback: [ count := count - 1 ]; with: '--'.
36 ]
37]
38
39MyCounter registerAsApplication: 'mycounter'
40</textarea></form>
41
42 <script>
43 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
44 lineNumbers: true,
45 matchBrackets: true,
46 mode: "text/x-stsrc",
47 indentUnit: 4
48 });
49 </script>
50
51 <p>Simple Smalltalk mode.</p>
52
53 <p><strong>MIME types defined:</strong> <code>text/x-stsrc</code>.</p>
54 </body>
55</html>
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 @@
1CodeMirror.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
139CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'}); \ No newline at end of file