Spaces:
Running
Running
CodeMirror.defineMode('smalltalk', function(config) { | |
var specialChars = /[+\-/\\*~<>=@%|&?!.:;^]/; | |
var keywords = /true|false|nil|self|super|thisContext/; | |
var Context = function(tokenizer, parent) { | |
this.next = tokenizer; | |
this.parent = parent; | |
}; | |
var Token = function(name, context, eos) { | |
this.name = name; | |
this.context = context; | |
this.eos = eos; | |
}; | |
var State = function() { | |
this.context = new Context(next, null); | |
this.expectVariable = true; | |
this.indentation = 0; | |
this.userIndentationDelta = 0; | |
}; | |
State.prototype.userIndent = function(indentation) { | |
this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0; | |
}; | |
var next = function(stream, context, state) { | |
var token = new Token(null, context, false); | |
var aChar = stream.next(); | |
if (aChar === '"') { | |
token = nextComment(stream, new Context(nextComment, context)); | |
} else if (aChar === '\'') { | |
token = nextString(stream, new Context(nextString, context)); | |
} else if (aChar === '#') { | |
stream.eatWhile(/[^ .]/); | |
token.name = 'string-2'; | |
} else if (aChar === '$') { | |
stream.eatWhile(/[^ ]/); | |
token.name = 'string-2'; | |
} else if (aChar === '|' && state.expectVariable) { | |
token.context = new Context(nextTemporaries, context); | |
} else if (/[\[\]{}()]/.test(aChar)) { | |
token.name = 'bracket'; | |
token.eos = /[\[{(]/.test(aChar); | |
if (aChar === '[') { | |
state.indentation++; | |
} else if (aChar === ']') { | |
state.indentation = Math.max(0, state.indentation - 1); | |
} | |
} else if (specialChars.test(aChar)) { | |
stream.eatWhile(specialChars); | |
token.name = 'operator'; | |
token.eos = aChar !== ';'; // ; cascaded message expression | |
} else if (/\d/.test(aChar)) { | |
stream.eatWhile(/[\w\d]/); | |
token.name = 'number'; | |
} else if (/[\w_]/.test(aChar)) { | |
stream.eatWhile(/[\w\d_]/); | |
token.name = state.expectVariable ? (keywords.test(stream.current()) ? 'keyword' : 'variable') : null; | |
} else { | |
token.eos = state.expectVariable; | |
} | |
return token; | |
}; | |
var nextComment = function(stream, context) { | |
stream.eatWhile(/[^"]/); | |
return new Token('comment', stream.eat('"') ? context.parent : context, true); | |
}; | |
var nextString = function(stream, context) { | |
stream.eatWhile(/[^']/); | |
return new Token('string', stream.eat('\'') ? context.parent : context, false); | |
}; | |
var nextTemporaries = function(stream, context) { | |
var token = new Token(null, context, false); | |
var aChar = stream.next(); | |
if (aChar === '|') { | |
token.context = context.parent; | |
token.eos = true; | |
} else { | |
stream.eatWhile(/[^|]/); | |
token.name = 'variable'; | |
} | |
return token; | |
}; | |
return { | |
startState: function() { | |
return new State; | |
}, | |
token: function(stream, state) { | |
state.userIndent(stream.indentation()); | |
if (stream.eatSpace()) { | |
return null; | |
} | |
var token = state.context.next(stream, state.context, state); | |
state.context = token.context; | |
state.expectVariable = token.eos; | |
state.lastToken = token; | |
return token.name; | |
}, | |
blankLine: function(state) { | |
state.userIndent(0); | |
}, | |
indent: function(state, textAfter) { | |
var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta; | |
return (state.indentation + i) * config.indentUnit; | |
}, | |
electricChars: ']' | |
}; | |
}); | |
CodeMirror.defineMIME('text/x-stsrc', {name: 'smalltalk'}); |