context-hint.js
83 lines
| 2.6 KiB
| application/javascript
|
JavascriptLexer
Matthias BUSSONNIER
|
r7131 | // highly adapted for codemiror jshint | ||
(function () { | ||||
Matthias BUSSONNIER
|
r7133 | "use strict"; | ||
function forEach(arr, f) { | ||||
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); | ||||
Matthias BUSSONNIER
|
r7131 | } | ||
Matthias BUSSONNIER
|
r7133 | |||
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; | ||||
Matthias BUSSONNIER
|
r7131 | } | ||
Matthias BUSSONNIER
|
r7133 | |||
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; | ||||
Matthias BUSSONNIER
|
r7131 | } | ||
Matthias BUSSONNIER
|
r7133 | // find all 'words' of current cell | ||
Matthias BUSSONNIER
|
r7140 | var getAllTokens = function(editor) | ||
Matthias BUSSONNIER
|
r7131 | { | ||
Matthias BUSSONNIER
|
r7133 | var found = []; | ||
Matthias BUSSONNIER
|
r7140 | |||
// add to found if not already in it | ||||
Matthias BUSSONNIER
|
r7133 | function maybeAdd(str) { | ||
if (!arrayContains(found, str)) found.push(str); | ||||
} | ||||
Matthias BUSSONNIER
|
r7140 | |||
// loop through all token on all lines | ||||
var lineCount = editor.lineCount(); | ||||
// loop on line | ||||
for( var l=0; l< lineCount ; l++) | ||||
Matthias BUSSONNIER
|
r7133 | { | ||
Matthias BUSSONNIER
|
r7140 | 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; | ||||
} | ||||
Matthias BUSSONNIER
|
r7133 | } | ||
return found; | ||||
Matthias BUSSONNIER
|
r7131 | } | ||
Matthias BUSSONNIER
|
r7140 | |||
Matthias BUSSONNIER
|
r7133 | function getCompletions(token,editor) | ||
Matthias BUSSONNIER
|
r7131 | { | ||
Matthias BUSSONNIER
|
r7133 | 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; | ||||
Matthias BUSSONNIER
|
r7131 | } | ||
})(); | ||||