diff --git a/IPython/frontend/html/notebook/static/codemirror-2.12/mode/python/python.js b/IPython/frontend/html/notebook/static/codemirror/mode/python/python.js
similarity index 94%
rename from IPython/frontend/html/notebook/static/codemirror-2.12/mode/python/python.js
rename to IPython/frontend/html/notebook/static/codemirror/mode/python/python.js
index 0cda2aafe..fc9a5037f 100644
--- a/IPython/frontend/html/notebook/static/codemirror-2.12/mode/python/python.js
+++ b/IPython/frontend/html/notebook/static/codemirror/mode/python/python.js
@@ -1,11 +1,15 @@
-CodeMirror.defineMode("python", function(conf) {
+CodeMirror.defineMode("python", function(conf, parserConf) {
var ERRORCLASS = 'error';
-
+
function wordRegexp(words) {
return new RegExp("^((" + words.join(")|(") + "))\\b");
}
-
+
+ // IPython-specific changes: add '?' as recognized character.
+ //var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");
var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\\?]");
+ // End IPython changes.
+
var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
var doubleOperators = new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
var doubleDelimiters = new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
@@ -29,7 +33,7 @@ CodeMirror.defineMode("python", function(conf) {
'open', 'range', 'zip'],
'keywords': ['nonlocal']};
- if (!!conf.mode.version && parseInt(conf.mode.version, 10) === 3) {
+ if (!!parserConf.version && parseInt(parserConf.version, 10) === 3) {
commonkeywords = commonkeywords.concat(py3.keywords);
commontypes = commontypes.concat(py3.types);
var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i");
@@ -65,15 +69,15 @@ CodeMirror.defineMode("python", function(conf) {
if (stream.eatSpace()) {
return null;
}
-
+
var ch = stream.peek();
-
+
// Handle Comments
if (ch === '#') {
stream.skipToEnd();
return 'comment';
}
-
+
// Handle Number Literals
if (stream.match(/^[0-9\.]/, false)) {
var floatLiteral = false;
@@ -109,13 +113,13 @@ CodeMirror.defineMode("python", function(conf) {
return 'number';
}
}
-
+
// Handle Strings
if (stream.match(stringPrefixes)) {
state.tokenize = tokenStringFactory(stream.current());
return state.tokenize(stream, state);
}
-
+
// Handle operators and Delimiters
if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) {
return null;
@@ -128,32 +132,31 @@ CodeMirror.defineMode("python", function(conf) {
if (stream.match(singleDelimiters)) {
return null;
}
-
+
if (stream.match(types)) {
return 'builtin';
}
-
+
if (stream.match(keywords)) {
return 'keyword';
}
-
+
if (stream.match(identifiers)) {
return 'variable';
}
-
+
// Handle non-detected items
stream.next();
return ERRORCLASS;
}
-
+
function tokenStringFactory(delimiter) {
- while ('rub'.indexOf(delimiter[0].toLowerCase()) >= 0) {
+ while ('rub'.indexOf(delimiter.charAt(0).toLowerCase()) >= 0) {
delimiter = delimiter.substr(1);
}
- var delim_re = new RegExp(delimiter);
var singleline = delimiter.length == 1;
var OUTCLASS = 'string';
-
+
return function tokenString(stream, state) {
while (!stream.eol()) {
stream.eatWhile(/[^'"\\]/);
@@ -162,7 +165,7 @@ CodeMirror.defineMode("python", function(conf) {
if (singleline && stream.eol()) {
return OUTCLASS;
}
- } else if (stream.match(delim_re)) {
+ } else if (stream.match(delimiter)) {
state.tokenize = tokenBase;
return OUTCLASS;
} else {
@@ -170,8 +173,8 @@ CodeMirror.defineMode("python", function(conf) {
}
}
if (singleline) {
- if (conf.mode.singleLineStringErrors) {
- OUTCLASS = ERRORCLASS
+ if (parserConf.singleLineStringErrors) {
+ return ERRORCLASS;
} else {
state.tokenize = tokenBase;
}
@@ -179,7 +182,7 @@ CodeMirror.defineMode("python", function(conf) {
return OUTCLASS;
};
}
-
+
function indent(stream, state, type) {
type = type || 'py';
var indentUnit = 0;
@@ -198,7 +201,7 @@ CodeMirror.defineMode("python", function(conf) {
type: type
});
}
-
+
function dedent(stream, state) {
if (state.scopes.length == 1) return;
if (state.scopes[0].type === 'py') {
@@ -238,7 +241,7 @@ CodeMirror.defineMode("python", function(conf) {
return ERRORCLASS;
}
}
-
+
// Handle decorators
if (current === '@') {
style = state.tokenize(stream, state);
@@ -251,7 +254,7 @@ CodeMirror.defineMode("python", function(conf) {
return ERRORCLASS;
}
}
-
+
// Handle scope changes.
if (current === 'pass' || current === 'return') {
state.dedent += 1;
@@ -279,7 +282,7 @@ CodeMirror.defineMode("python", function(conf) {
if (state.scopes.length > 1) state.scopes.shift();
state.dedent -= 1;
}
-
+
return style;
}
@@ -293,27 +296,27 @@ CodeMirror.defineMode("python", function(conf) {
dedent: 0
};
},
-
+
token: function(stream, state) {
var style = tokenLexer(stream, state);
-
+
state.lastToken = {style:style, content: stream.current()};
-
+
if (stream.eol() && stream.lambda) {
state.lambda = false;
}
-
+
return style;
},
-
+
indent: function(state, textAfter) {
if (state.tokenize != tokenBase) {
return 0;
}
-
+
return state.scopes[0].offset;
}
-
+
};
return external;
});
diff --git a/IPython/frontend/html/notebook/templates/notebook.html b/IPython/frontend/html/notebook/templates/notebook.html
index e82cf7b08..86017eb93 100644
--- a/IPython/frontend/html/notebook/templates/notebook.html
+++ b/IPython/frontend/html/notebook/templates/notebook.html
@@ -21,10 +21,11 @@
}
-
-
-
-
+
+
+
+
+
@@ -208,13 +209,14 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+