You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

116 lines
4.0 KiB

/**
* @fileOverview Completion request handler for skewer.js
* @requires skewer
* @version 1.0
*/
/**
* Handles a completion request from Emacs.
* @param request The request object sent by Emacs
* @returns The completions and init values to be returned to Emacs
*/
skewer.fn.complete = function(request) {
var result = {
type : request.type,
id : request.id,
strict : request.strict,
status : "success"
},
/**
* Methods for generating candidates
*/
METHOD = {
EVAL : 0,
GLOBAL : 1
},
/**
* Add the properties from object to extendObject. Properties
* may be from the prototype but we still want to add them.
*/
extend = function(extendObject, object) {
for(var key in object) {
extendObject[key] = object[key];
}
},
globalCompletion = function() {
var global = Function('return this')(),
keys = Object.keys(global);
candidates = buildCandidates(global, keys);
},
evalCompletion = function(evalObject) {
var obj = (eval, eval)(evalObject);
if (typeof obj === "object") {
candidates = buildCandidates(obj) || {};
while (request.prototypes && (obj = Object.getPrototypeOf(obj)) !== null) {
extend(candidates, buildCandidates(obj));
}
} else if (typeof obj === "function"){
candidates = buildCandidates(obj) || {};
extend(candidates, buildCandidates(Object.getPrototypeOf(obj)));
if (request.prototypes) {
var protoObject = Object.getPrototypeOf(obj.prototype);
if (protoObject !== null) {
extend(candidates, buildCandidates(protoObject));
} else {
extend(candidates, buildCandidates(obj.prototype));
}
}
}
},
/**
* Completion candidates sent back to Emacs. Keys are
* completion candidates the values are the inital items or
* function interfaces.
*/
candidates = {},
/**
* Build the candiates to return to Emacs.
* @param obj The object to get candidates from
* @param items The selected keys from obj to create candidates for
* @return object containing completion candidates and documentation strings
*/
buildCandidates = function(obj, items) {
var keys = items || Object.getOwnPropertyNames(obj), values = {};
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (key === "callee" || key === "caller" || key === "arguments") continue;
if (Object.prototype.toString.call(obj[key]) === "[object Function]") {
values[key] = obj[key].toString();
} else if (typeof obj[key] === "object"){
values[key] = "[object Object]";
} else if (typeof obj[key] === "number") {
if (!(obj instanceof Array)) {
values[key] = obj[key].toString();
}
} else if (typeof obj[key] === "string") {
values[key] = obj[key].toString();
} else if(obj[key] === true) {
values[key] = "true";
} else if (obj[key] === false) {
values[key] = "false";
} else {
values[key] = "";
}
}
return values;
};
try {
switch (request.method) {
case METHOD.GLOBAL:
globalCompletion();
break;
default:
evalCompletion(request.eval);
}
result.value = candidates;
} catch (error){
skewer.errorResult(error, result, request);
}
return result;
};