##// END OF EJS Templates
tweak history prefix search (up/^p) in qtconsole...
tweak history prefix search (up/^p) in qtconsole moving the cursor around the line could result in weird inconsistencies in the prefix. This simplifies the logic by always using the cursor position to set the history prefix, and better determine when the history prefix has actually changed.

File last commit:

r8053:58574fbf
r9205:ef8c14cd
Show More
smarty.js
147 lines | 3.8 KiB | application/javascript | JavascriptLexer
CodeMirror.defineMode("smarty", function(config, parserConfig) {
var keyFuncs = ["debug", "extends", "function", "include", "literal"];
var last;
var regs = {
operatorChars: /[+\-*&%=<>!?]/,
validIdentifier: /[a-zA-Z0-9\_]/,
stringChar: /[\'\"]/
}
var leftDelim = (typeof config.mode.leftDelimiter != 'undefined') ? config.mode.leftDelimiter : "{";
var rightDelim = (typeof config.mode.rightDelimiter != 'undefined') ? config.mode.rightDelimiter : "}";
function ret(style, lst) { last = lst; return style; }
function tokenizer(stream, state) {
function chain(parser) {
state.tokenize = parser;
return parser(stream, state);
}
if (stream.match(leftDelim, true)) {
if (stream.eat("*")) {
return chain(inBlock("comment", "*" + rightDelim));
}
else {
state.tokenize = inSmarty;
return "tag";
}
}
else {
// I'd like to do an eatWhile() here, but I can't get it to eat only up to the rightDelim string/char
stream.next();
return null;
}
}
function inSmarty(stream, state) {
if (stream.match(rightDelim, true)) {
state.tokenize = tokenizer;
return ret("tag", null);
}
var ch = stream.next();
if (ch == "$") {
stream.eatWhile(regs.validIdentifier);
return ret("variable-2", "variable");
}
else if (ch == ".") {
return ret("operator", "property");
}
else if (regs.stringChar.test(ch)) {
state.tokenize = inAttribute(ch);
return ret("string", "string");
}
else if (regs.operatorChars.test(ch)) {
stream.eatWhile(regs.operatorChars);
return ret("operator", "operator");
}
else if (ch == "[" || ch == "]") {
return ret("bracket", "bracket");
}
else if (/\d/.test(ch)) {
stream.eatWhile(/\d/);
return ret("number", "number");
}
else {
if (state.last == "variable") {
if (ch == "@") {
stream.eatWhile(regs.validIdentifier);
return ret("property", "property");
}
else if (ch == "|") {
stream.eatWhile(regs.validIdentifier);
return ret("qualifier", "modifier");
}
}
else if (state.last == "whitespace") {
stream.eatWhile(regs.validIdentifier);
return ret("attribute", "modifier");
}
else if (state.last == "property") {
stream.eatWhile(regs.validIdentifier);
return ret("property", null);
}
else if (/\s/.test(ch)) {
last = "whitespace";
return null;
}
var str = "";
if (ch != "/") {
str += ch;
}
var c = "";
while ((c = stream.eat(regs.validIdentifier))) {
str += c;
}
var i, j;
for (i=0, j=keyFuncs.length; i<j; i++) {
if (keyFuncs[i] == str) {
return ret("keyword", "keyword");
}
}
if (/\s/.test(ch)) {
return null;
}
return ret("tag", "tag");
}
}
function inAttribute(quote) {
return function(stream, state) {
while (!stream.eol()) {
if (stream.next() == quote) {
state.tokenize = inSmarty;
break;
}
}
return "string";
};
}
function inBlock(style, terminator) {
return function(stream, state) {
while (!stream.eol()) {
if (stream.match(terminator)) {
state.tokenize = tokenizer;
break;
}
stream.next();
}
return style;
};
}
return {
startState: function() {
return { tokenize: tokenizer, mode: "smarty", last: null };
},
token: function(stream, state) {
var style = state.tokenize(stream, state);
state.last = last;
return style;
},
electricChars: ""
}
});
CodeMirror.defineMIME("text/x-smarty", "smarty");