diff --git a/content/bookmarks.js b/content/bookmarks.js
index 1818f159..9702dc8e 100644
--- a/content/bookmarks.js
+++ b/content/bookmarks.js
@@ -233,11 +233,8 @@ function Bookmarks() //{{{
"Set the default search engine",
"string", "google",
{
- completer: function (filter) completion._url(filter, "s").items,
- validator: function (value)
- {
- return completion._url("", "s").items.some(function (s) s.text == value);
- }
+ completer: function (filter) completion.runCompleter("search", filter, true),
+ validator: function (value) completion.runCompleter("search", "", true).some(function ([s]) s == value)
});
options.add(["preload"],
@@ -560,7 +557,7 @@ function Bookmarks() //{{{
list: function (filter, tags, openItems)
{
if (!openItems)
- return template.listCompleter("bookmark", filter, tags);
+ return completion.listCompleter("bookmark", filter, tags);
let items = this.get(filter, tags, false);
if (items.length)
@@ -802,7 +799,7 @@ function History() //{{{
list: function (filter, openItems)
{
if (!openItems)
- return template.listCompleter("history", filter);
+ return completion.listCompleter("history", filter);
var items = this.get({ searchTerms: filter }, 1000);
if (items.length)
diff --git a/content/completion.js b/content/completion.js
index 7a0fa9df..aa7f151e 100644
--- a/content/completion.js
+++ b/content/completion.js
@@ -34,6 +34,8 @@ modules._cleanEval = function _cleanEval(__liberator_eval_arg, __liberator_eval_
function CompletionContext(editor, name, offset)
{
+ if (!(this instanceof arguments.callee))
+ return new arguments.callee(editor, name, offset);
if (!name)
name = "";
@@ -949,10 +951,10 @@ function Completion() //{{{
runCompleter: function (name, filter)
{
- let context = new CompletionContext(filter);
- context.__defineGetter__("background", function () false);
- context.__defineSetter__("background", function () false);
- this[name](context);
+ let context = CompletionContext(filter);
+ this[name].apply(this, [context].concat(Array.slice(arguments, 1)));
+ while (context.incomplete)
+ liberator.threadYield(true, true);
return context.items.map(function (i) i.item);
},
@@ -1060,6 +1062,23 @@ function Completion() //{{{
return filter.split(/\s+/).every(function strIndex(str) itemsStr.indexOf(str) > -1);
},
+ listCompleter: function (name, filter)
+ {
+ let context = CompletionContext(filter || "");
+ context.fork.apply(context, ["list", 0, completion, name].concat(Array.slice(arguments, 2)));
+ context = context.contexts["/list"];
+
+ while (context.incomplete)
+ liberator.threadYield(true, true);
+
+ let list = template.generic(
+
+ { template.completionRow(context.title, "hl-CompTitle") }
+ { template.map(context.items, function (item) context.createRow(item)) }
+
);
+ commandline.echo(list, commandline.HL_NORMAL, commandline.FORCE_MULTILINE);
+ },
+
////////////////////////////////////////////////////////////////////////////////
////////////////////// COMPLETION TYPES ////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
@@ -1275,10 +1294,7 @@ function Completion() //{{{
get javascriptCompleter() javascript,
- javascript: function _javascript(context)
- {
- return javascript.complete(context);
- },
+ javascript: function _javascript(context) javascript.complete(context),
location: function (context)
{
@@ -1309,11 +1325,10 @@ function Completion() //{{{
});
},
- macro: function macro(filter)
+ macro: function macro(context)
{
- var macros = [item for (item in events.getMacros())];
-
- return [0, this.filter(macros, filter)];
+ context.title = ["Macro", "Keys"];
+ context.completions = [item for (item in events.getMacros())];
},
menuItem: function menuItem(filter) commands.get("emenu").completer(filter), // XXX
@@ -1322,7 +1337,7 @@ function Completion() //{{{
preference: function preference(filter) commands.get("set").completer(filter, true), // XXX
- search: function search(context)
+ search: function search(context, noSuggest)
{
let [, keyword, space, args] = context.filter.match(/^\s*(\S*)(\s*)(.*)$/);
let keywords = bookmarks.getKeywords();
@@ -1333,7 +1348,7 @@ function Completion() //{{{
context.completions = keywords.concat(engines);
context.anchored = true;
- if (!space)
+ if (!space || noSuggest)
return;
context.fork("suggest", keyword.length + space.length, this, "searchEngineSuggest",
@@ -1467,14 +1482,6 @@ function Completion() //{{{
this.urlCompleters[opt] = UrlCompleter.apply(null, Array.slice(arguments));
},
- // FIXME: Temporary
- _url: function _url(filter, complete)
- {
- let context = new CompletionContext(filter);
- this.url(context, complete);
- return context.allItems;
- },
-
userCommand: function userCommand(filter)
{
let cmds = commands.getUserCommands();
diff --git a/content/events.js b/content/events.js
index 346913ea..0c4b0fcd 100644
--- a/content/events.js
+++ b/content/events.js
@@ -719,21 +719,16 @@ function Events() //{{{
},
{
bang: true,
- completer: function (context) completion.macro(context.filter),
+ completer: function (context) completion.macro(context),
literal: true
});
commands.add(["macros"],
"List all macros",
- function (args)
+ function (args) { completion.listCompleter("macro", args.arguments[0]) },
{
- XML.prettyPrinting = false;
- var str = template.tabular(["Macro", "Keys"], [], events.getMacros(args.string));
- liberator.echo(str, commandline.FORCE_MULTILINE);
- },
- {
- completer: function (context) completion.macro(context.filter),
- literal: true
+ argCount: "1",
+ completer: function (context) completion.macro(context),
});
commands.add(["pl[ay]"],
@@ -741,7 +736,7 @@ function Events() //{{{
function (args) { events.playMacro(args.arguments[0]); },
{
argCount: "1",
- completer: function (context) completion.macro(context.filter)
+ completer: function (context) completion.macro(context)
});
/////////////////////////////////////////////////////////////////////////////}}}
diff --git a/content/liberator.js b/content/liberator.js
index 4afd11e5..aec7758b 100644
--- a/content/liberator.js
+++ b/content/liberator.js
@@ -208,30 +208,28 @@ const liberator = (function () //{{{
// TODO: move this
function getMenuItems()
{
- var menubar = document.getElementById(config.guioptions["m"]);
- var items = [];
-
- for (let i = 0; i < menubar.childNodes.length; i++)
+ function addChildren(node, parent)
{
- (function (item, path)
+ for (let [,item] in Iterator(node.childNodes))
{
if (item.childNodes.length == 0 && item.localName == "menuitem"
&& !/rdf:http:/.test(item.label)) // FIXME
{
- item.fullMenuPath = path += item.label;
+ item.fullMenuPath = parent + item.label;
items.push(item);
}
else
{
+ path = parent;
if (item.localName == "menu")
path += item.label + ".";
-
- for (let j = 0; j < item.childNodes.length; j++)
- arguments.callee(item.childNodes[j], path);
+ addChildren(item, path);
}
- })(menubar.childNodes[i], "");
+ }
}
+ let items = [];
+ addChildren(document.getElementById(config.guioptions["m"]), "");
return items;
}
@@ -259,8 +257,9 @@ const liberator = (function () //{{{
// TODO: add this as a standard menu completion function
completer: function (context)
{
- let completions = getMenuItems().map(function (item) [item.fullMenuPath, item.label]);
- return [0, completion.filter(completions, context.filter)];
+ context.title = ["Menu Path", "Label"];
+ context.keys = { text: "fullMenuPath", description: "label" };
+ context.completions = getMenuItems();
},
literal: true
});
diff --git a/content/tabs.js b/content/tabs.js
index 0bafeafb..c77fce08 100644
--- a/content/tabs.js
+++ b/content/tabs.js
@@ -748,7 +748,7 @@ function Tabs() //{{{
list: function (filter)
{
- template.listCompleter("buffer", filter);
+ completion.listCompleter("buffer", filter);
},
// wrap causes the movement to wrap around the start and end of the tab list
diff --git a/content/template.js b/content/template.js
index b8c28499..682a2512 100644
--- a/content/template.js
+++ b/content/template.js
@@ -32,23 +32,6 @@ const template = {
return <>{xml}>;
},
- listCompleter: function (name, filter)
- {
- let context = new CompletionContext(filter || "");
- context.fork.apply(context, ["list", 0, completion, name].concat(Array.slice(arguments, 2)));
- context = context.contexts["/list"];
-
- while (context.incomplete)
- liberator.threadYield(true, true);
-
- let list = this.generic(
-
- { this.completionRow(context.title, "hl-CompTitle") }
- { template.map(context.items, function (item) context.createRow(item)) }
-
);
- commandline.echo(list, commandline.HL_NORMAL, commandline.FORCE_MULTILINE);
- },
-
completionRow: function completionRow(item, class)
{
if (typeof icon == "function")
diff --git a/content/ui.js b/content/ui.js
index 30ba5f75..3a7f7cd4 100644
--- a/content/ui.js
+++ b/content/ui.js
@@ -143,12 +143,6 @@ function CommandLine() //{{{
completionPostfix = command.substring(commandWidget.selectionStart);
completions = liberator.triggerCallback("complete", currentExtendedMode, completionPrefix);
- // sort the completion list
- // TODO: might not make sense anymore with our advanced completions, we should just sort when necessary
- // FIXME: CompletionContext
- //if (options.get("wildoptions").has("sort"))
- // completions.items.sort(function (a, b) String.localeCompare(a[0], b[0]));
-
completionList.setItems(completionContext);
}
@@ -682,7 +676,7 @@ function CommandLine() //{{{
commandWidget.focus();
- completionContext = new CompletionContext(commandWidget.inputField.editor);
+ completionContext = CompletionContext(commandWidget.inputField.editor);
completionContext.onUpdate = function ()
{
commandline.setCompletions(this.allItems);