diff --git a/content/completion.js b/content/completion.js
index bf3646ac..ba109249 100644
--- a/content/completion.js
+++ b/content/completion.js
@@ -225,6 +225,8 @@ liberator.Completion = function () //{{{
{
if (top[CHAR] != arg)
throw new Error("Invalid JS");
+ if (i == str.length - 1)
+ liberator.completion.parenMatch = top[OFFSET];
// The closing character of this stack frame will have pushed a new
// statement, leaving us with an empty statement. This doesn't matter,
// now, as we simply throw away the frame when we pop it, but it may later.
@@ -798,6 +800,8 @@ liberator.Completion = function () //{{{
// provides completions for ex commands, including their arguments
ex: function (str)
{
+ this.filterString = "";
+ this.parenMatch = null;
substrings = [];
if (str.indexOf(cacheFilter["ex"]) != 0)
{
@@ -935,7 +939,7 @@ liberator.Completion = function () //{{{
if (h[0].indexOf(begin) == 0 && (!end.length || h[0].substr(-end.length) == end))
{
let query = h[0].substring(begin.length, h[0].length - end.length);
- searches.push([decodeURIComponent(query),
+ searches.push([decodeURIComponent(query.replace("+", "%20")),
<>{begin}{query}{end}>,
k[2]]);
}
diff --git a/content/ui.js b/content/ui.js
index 4be8c005..d442caf9 100644
--- a/content/ui.js
+++ b/content/ui.js
@@ -1150,13 +1150,33 @@ liberator.CommandLine = function () //{{{
}
},
- // to allow asynchronous adding of completions, broken
- // since the completion -> ItemList rewrite
+ // to allow asynchronous adding of completions
setCompletions: function (compl, start)
{
if (liberator.mode != liberator.modes.COMMAND_LINE)
return;
+ // FIXME: Kludge.
+ try // Firefox <3.1 doesn't have repaintSelection
+ {
+ const SEL_TYPE = Components.interfaces.nsISelectionController.SELECTION_FIND;
+ let editor = document.getElementById("liberator-commandline-command")
+ .inputField.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor;
+ let sel = editor.selectionController.getSelection(SEL_TYPE);
+ sel.removeAllRanges();
+ if (liberator.completion.parenMatch != null)
+ {
+ let range = editor.selection.getRangeAt(0).cloneRange();
+ let paren = liberator.completion.parenMatch + this.getCommand().indexOf(" ") + 1;
+ let node = range.startContainer;
+ range.setStart(node, paren);
+ range.setEnd(node, paren + 1);
+ sel.addRange(range);
+ editor.selectionController.repaintSelection(SEL_TYPE);
+ }
+ }
+ catch (e) {}
+
/* Only hide if not pending.
if (compl.length == 0)
return completionList.hide();
diff --git a/content/util.js b/content/util.js
index 7485953b..60f7ea77 100644
--- a/content/util.js
+++ b/content/util.js
@@ -256,6 +256,7 @@ liberator.util = { //{{{
obj = {obj}.toXMLString();
string += obj + "::\n";
+ let keys = [];
try // window.content often does not want to be queried with "var i in object"
{
for (let i in object)
@@ -273,12 +274,12 @@ liberator.util = { //{{{
value = value.toXMLString();
i = {i}.toXMLString();
}
- string += i + ": " + value + "\n";
+ keys.push(i + ": " + value);
}
}
catch (e) {}
- return string;
+ return string + keys.sort().join("\n") + "\n";
},
range: function (start, end)