mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-20 10:37:59 +01:00
Use context.split for JavaScript completions for better performance and less hair raising, gut wrenching horror.
This commit is contained in:
@@ -319,115 +319,109 @@ var JavaScript = Module("javascript", {
|
|||||||
return [dot + 1 + space.length, obj, key];
|
return [dot + 1 + space.length, obj, key];
|
||||||
},
|
},
|
||||||
|
|
||||||
_fill: function (context, args) {
|
|
||||||
context.title = [args.name];
|
|
||||||
context.anchored = args.anchored;
|
|
||||||
context.filter = args.filter;
|
|
||||||
context.itemCache = context.parent.itemCache;
|
|
||||||
context.key = args.name + args.last;
|
|
||||||
|
|
||||||
if (args.last == null)
|
|
||||||
// We're not looking for a quoted string, so filter out anything that's not a valid identifier
|
|
||||||
context.filters.push(function (item) /^[a-zA-Z_$][\w$]*$/.test(item.text));
|
|
||||||
else {
|
|
||||||
context.quote = [args.last, function (text) util.escapeString(text, ""), args.last];
|
|
||||||
if (args.prefix)
|
|
||||||
context.filters.push(function (item) item.item.indexOf(args.prefix) === 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
args.completer.call(this, context, args);
|
|
||||||
},
|
|
||||||
|
|
||||||
_complete: function (objects, key, compl, string, last) {
|
_complete: function (objects, key, compl, string, last) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
if (!this.window.Object.getOwnPropertyNames && !services.debugger.isOn && !this.context.message)
|
if (!this.window.Object.getOwnPropertyNames && !services.debugger.isOn && !this.context.message)
|
||||||
this.context.message = "For better completion data, please enable the JavaScript debugger (:set jsdebugger)";
|
this.context.message = "For better completion data, please enable the JavaScript debugger (:set jsdebugger)";
|
||||||
|
|
||||||
let orig = compl;
|
let base = this.context.fork("js", this._top.offset);
|
||||||
|
base.forceAnchored = true;
|
||||||
|
base.filter = last == null ? key : string;
|
||||||
|
let prefix = last != null ? key : "";
|
||||||
|
|
||||||
|
if (last == null) // We're not looking for a quoted string, so filter out anything that's not a valid identifier
|
||||||
|
base.filters.push(function (item) /^[a-zA-Z_$][\w$]*$/.test(item.text));
|
||||||
|
else {
|
||||||
|
base.quote = [last, function (text) util.escapeString(text, ""), last];
|
||||||
|
if (prefix)
|
||||||
|
base.filters.push(function (item) item.item.indexOf(prefix) === 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (!compl) {
|
if (!compl) {
|
||||||
compl = function (context, args, recurse) {
|
base.process[1] = function highlight(item, v)
|
||||||
|
template.highlight(typeof v == "xml" ? new String(v.toXMLString()) : v, true, 200);
|
||||||
|
|
||||||
context.process[1] = function highlight(item, v)
|
// Sort in a logical fashion for object keys:
|
||||||
template.highlight(typeof v == "xml" ? new String(v.toXMLString()) : v, true, 200);
|
// Numbers are sorted as numbers, rather than strings, and appear first.
|
||||||
|
// Constants are unsorted, and appear before other non-null strings.
|
||||||
|
// Other strings are sorted in the default manner.
|
||||||
|
|
||||||
// Sort in a logical fashion for object keys:
|
let isnan = function isnan(item) item != '' && isNaN(item);
|
||||||
// Numbers are sorted as numbers, rather than strings, and appear first.
|
let compare = base.compare;
|
||||||
// Constants are unsorted, and appear before other non-null strings.
|
|
||||||
// Other strings are sorted in the default manner.
|
|
||||||
let compare = context.compare;
|
|
||||||
function isnan(item) item != '' && isNaN(item);
|
|
||||||
context.compare = function (a, b) {
|
|
||||||
if (!isnan(a.key) && !isnan(b.key))
|
|
||||||
return a.key - b.key;
|
|
||||||
return isnan(b.key) - isnan(a.key) || compare(a, b);
|
|
||||||
};
|
|
||||||
context.keys = {
|
|
||||||
text: args.prefix ? function (text) text.substr(args.prefix.length) : util.identity,
|
|
||||||
description: function (item) self.getKey(args.obj, item),
|
|
||||||
key: function (item) {
|
|
||||||
if (!isNaN(key))
|
|
||||||
return parseInt(key);
|
|
||||||
if (/^[A-Z_][A-Z0-9_]*$/.test(key))
|
|
||||||
return "";
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!context.anchored) // We've already listed anchored matches, so don't list them again here.
|
base.compare = function (a, b) {
|
||||||
context.filters.push(function (item) util.compareIgnoreCase(item.text.substr(0, this.filter.length), this.filter));
|
if (!isnan(a.key) && !isnan(b.key))
|
||||||
if (args.obj == self.cache.evalContext)
|
return a.key - b.key;
|
||||||
context.regenerate = true;
|
return isnan(b.key) - isnan(a.key) || compare(a, b);
|
||||||
context.generate = function () self.objectKeys(args.obj, !recurse);
|
};
|
||||||
|
|
||||||
|
base.keys = {
|
||||||
|
text: prefix ? function (text) text.substr(prefix.length) : util.identity,
|
||||||
|
description: function (item) self.getKey(this.obj, item),
|
||||||
|
key: function (item) {
|
||||||
|
if (!isNaN(key))
|
||||||
|
return parseInt(key);
|
||||||
|
if (/^[A-Z_][A-Z0-9_]*$/.test(key))
|
||||||
|
return "";
|
||||||
|
return item;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = {
|
// We've already listed anchored matches, so don't list them again here.
|
||||||
filter: last == null ? key : string,
|
function unanchored(item) util.compareIgnoreCase(item.text.substr(0, this.filter.length), this.filter);
|
||||||
last: last,
|
|
||||||
prefix: last != null ? key : ""
|
objects.forEach(function (obj) {
|
||||||
};
|
let context = base.fork(obj[1]);
|
||||||
|
context.title = [obj[1]];
|
||||||
|
context.keys.obj = function () obj[0];
|
||||||
|
context.key = obj[1] + last;
|
||||||
|
if (obj[0] == this.cache.evalContext)
|
||||||
|
context.regenerate = true;
|
||||||
|
|
||||||
|
obj.ctxt_t = context.fork("toplevel");
|
||||||
|
if (!compl) {
|
||||||
|
obj.ctxt_p = context.fork("prototypes");
|
||||||
|
obj.ctxt_t.generate = function () self.objectKeys(obj[0], true);
|
||||||
|
obj.ctxt_p.generate = function () self.objectKeys(obj[0], false);
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
this.context.forceAnchored = true;
|
|
||||||
// TODO: Make this a generic completion helper function.
|
// TODO: Make this a generic completion helper function.
|
||||||
for (let [, obj] in Iterator(objects))
|
objects.forEach(function (obj) {
|
||||||
this.context.fork(obj[1], this._top.offset, this, this._fill,
|
obj.ctxt_t.split(obj[1] + "/anchored", this, function (context) {
|
||||||
update({
|
context.anchored = true;
|
||||||
obj: obj[0],
|
if (compl)
|
||||||
name: obj[1],
|
compl(context, obj[0]);
|
||||||
anchored: true,
|
});
|
||||||
completer: compl
|
});
|
||||||
}, args));
|
|
||||||
|
|
||||||
if (orig)
|
if (compl)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (let [, obj] in Iterator(objects))
|
objects.forEach(function (obj) {
|
||||||
this.context.fork(obj[1] + "/prototypes", this._top.offset, this, this._fill,
|
obj.ctxt_p.split(obj[1] + "/anchored", this, function (context) {
|
||||||
update({
|
context.anchored = true;
|
||||||
obj: obj[0],
|
context.title[0] += " (prototypes)";
|
||||||
name: obj[1] + " (prototypes)",
|
});
|
||||||
anchored: true,
|
});
|
||||||
completer: function (a, b) compl(a, b, true)
|
|
||||||
}, args));
|
|
||||||
|
|
||||||
for (let [, obj] in Iterator(objects))
|
objects.forEach(function (obj) {
|
||||||
this.context.fork(obj[1] + "/substrings", this._top.offset, this, this._fill,
|
obj.ctxt_t.split(obj[1] + "/unanchored", this, function (context) {
|
||||||
update({
|
context.anchored = false;
|
||||||
obj: obj[0],
|
context.title[0] += " (substrings)";
|
||||||
name: obj[1] + " (substrings)",
|
context.filters.push(unanchored);
|
||||||
anchored: false,
|
});
|
||||||
completer: compl
|
});
|
||||||
}, args));
|
|
||||||
|
|
||||||
for (let [, obj] in Iterator(objects))
|
objects.forEach(function (obj) {
|
||||||
this.context.fork(obj[1] + "/prototypes/substrings", this._top.offset, this, this._fill,
|
obj.ctxt_p.split(obj[1] + "/unanchored", this, function (context) {
|
||||||
update({
|
context.anchored = false;
|
||||||
obj: obj[0],
|
context.title[0] += " (prototype substrings)";
|
||||||
name: obj[1] + " (prototype substrings)",
|
context.filters.push(unanchored);
|
||||||
anchored: false,
|
});
|
||||||
completer: function (a, b) compl(a, b, true)
|
});
|
||||||
}, args));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_getKey: function () {
|
_getKey: function () {
|
||||||
@@ -561,7 +555,7 @@ var JavaScript = Module("javascript", {
|
|||||||
args.push(key + string);
|
args.push(key + string);
|
||||||
|
|
||||||
let compl = function (context, obj) {
|
let compl = function (context, obj) {
|
||||||
let res = completer.call(self, context, funcName, obj.obj, args);
|
let res = completer.call(self, context, funcName, obj, args);
|
||||||
if (res)
|
if (res)
|
||||||
context.completions = res;
|
context.completions = res;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user