// highly adapted for codemiror jshint (function () { "use strict"; function forEach(arr, f) { for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); } function arrayContains(arr, item) { if (!Array.prototype.indexOf) { var i = arr.length; while (i--) { if (arr[i] === item) { return true; } } return false; } return arr.indexOf(item) != -1; } CodeMirror.contextHint = function (editor) { // Find the token at the cursor var cur = editor.getCursor(), token = editor.getTokenAt(cur), tprop = token; // If it's not a 'word-style' token, ignore the token. // If it is a property, find out what it is a property of. var list = new Array(); var clist = getCompletions(token, editor); for (var i = 0; i < clist.length; i++) { list.push({ str: clist[i], type: "context", from: { line: cur.line, ch: token.start }, to: { line: cur.line, ch: token.end } }) } return list; } // find all 'words' of current cell var getAllTokens = function (editor) { var found = []; // add to found if not already in it function maybeAdd(str) { if (!arrayContains(found, str)) found.push(str); } // loop through all token on all lines var lineCount = editor.lineCount(); // loop on line for (var l = 0; l < lineCount; l++) { var line = editor.getLine(l); //loop on char for (var c = 1; c < line.length; c++) { var tk = editor.getTokenAt({ line: l, ch: c }); // if token has a class, it has geat chances of beeing // of interest. Add it to the list of possible completions. // we could skip token of ClassName 'comment' // or 'number' and 'operator' if (tk.className != null) { maybeAdd(tk.string); } // jump to char after end of current token c = tk.end; } } return found; } function getCompletions(token, editor) { var candidates = getAllTokens(editor); // filter all token that have a common start (but nox exactly) the lenght of the current token var lambda = function (x) { return (x.indexOf(token.string) == 0 && x != token.string) }; var filterd = candidates.filter(lambda); return filterd; } })();