aboutsummaryrefslogtreecommitdiff
path: root/imports/codemirror/lib/util/javascript-hint.js
diff options
context:
space:
mode:
Diffstat (limited to 'imports/codemirror/lib/util/javascript-hint.js')
-rwxr-xr-ximports/codemirror/lib/util/javascript-hint.js83
1 files changed, 83 insertions, 0 deletions
diff --git a/imports/codemirror/lib/util/javascript-hint.js b/imports/codemirror/lib/util/javascript-hint.js
new file mode 100755
index 00000000..4e88a7e4
--- /dev/null
+++ b/imports/codemirror/lib/util/javascript-hint.js
@@ -0,0 +1,83 @@
1(function () {
2 function forEach(arr, f) {
3 for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
4 }
5
6 function arrayContains(arr, item) {
7 if (!Array.prototype.indexOf) {
8 var i = arr.length;
9 while (i--) {
10 if (arr[i] === item) {
11 return true;
12 }
13 }
14 return false;
15 }
16 return arr.indexOf(item) != -1;
17 }
18
19 CodeMirror.javascriptHint = function(editor) {
20 // Find the token at the cursor
21 var cur = editor.getCursor(), token = editor.getTokenAt(cur), tprop = token;
22 // If it's not a 'word-style' token, ignore the token.
23 if (!/^[\w$_]*$/.test(token.string)) {
24 token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
25 className: token.string == "." ? "property" : null};
26 }
27 // If it is a property, find out what it is a property of.
28 while (tprop.className == "property") {
29 tprop = editor.getTokenAt({line: cur.line, ch: tprop.start});
30 if (tprop.string != ".") return;
31 tprop = editor.getTokenAt({line: cur.line, ch: tprop.start});
32 if (!context) var context = [];
33 context.push(tprop);
34 }
35 return {list: getCompletions(token, context),
36 from: {line: cur.line, ch: token.start},
37 to: {line: cur.line, ch: token.end}};
38 }
39
40 var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
41 "toUpperCase toLowerCase split concat match replace search").split(" ");
42 var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
43 "lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
44 var funcProps = "prototype apply call bind".split(" ");
45 var keywords = ("break case catch continue debugger default delete do else false finally for function " +
46 "if in instanceof new null return switch throw true try typeof var void while with").split(" ");
47
48 function getCompletions(token, context) {
49 var found = [], start = token.string;
50 function maybeAdd(str) {
51 if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
52 }
53 function gatherCompletions(obj) {
54 if (typeof obj == "string") forEach(stringProps, maybeAdd);
55 else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
56 else if (obj instanceof Function) forEach(funcProps, maybeAdd);
57 for (var name in obj) maybeAdd(name);
58 }
59
60 if (context) {
61 // If this is a property, see if it belongs to some object we can
62 // find in the current environment.
63 var obj = context.pop(), base;
64 if (obj.className == "variable")
65 base = window[obj.string];
66 else if (obj.className == "string")
67 base = "";
68 else if (obj.className == "atom")
69 base = 1;
70 while (base != null && context.length)
71 base = base[context.pop().string];
72 if (base != null) gatherCompletions(base);
73 }
74 else {
75 // If not, just look in the window object and any local scope
76 // (reading into JS mode internals to get at the local variables)
77 for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
78 gatherCompletions(window);
79 forEach(keywords, maybeAdd);
80 }
81 return found;
82 }
83})();