diff --git a/content/completion.js b/content/completion.js
index c2cfdab1..9e71e24b 100644
--- a/content/completion.js
+++ b/content/completion.js
@@ -108,6 +108,7 @@ CompletionContext.prototype = {
{
delete this.cache.filtered;
delete this.cache.filter;
+ this.cache.rows = [];
this.hasItems = items.length > 0;
this._completions = items;
let self = this;
@@ -126,10 +127,14 @@ CompletionContext.prototype = {
get generate() !this._generate ? null : function ()
{
- this._completions = this._generate.call(this);
+ let updateAsync = this.updateAsync; // XXX
+ this.updateAsync = false;
+ this.completions = this._generate.call(this);
+ this.updateAsync = updateAsync;
+
this.cache.offset = this.offset;
this.cache.key = this.key;
- return this._completions;
+ return this.completions;
},
set generate(arg)
{
@@ -217,15 +222,24 @@ CompletionContext.prototype = {
{
let self = this;
let items = this.items;
- if (!items)
- return [];
-
let reverse = start > end;
start = Math.max(0, start || 0);
end = Math.min(items.length, end ? end : items.length);
return util.map(util.range(start, end, reverse), function (i) items[i]);
},
+ getRows: function (start, end, doc)
+ {
+ let self = this;
+ let items = this.items;
+ let cache = this.cache.rows;
+ let reverse = start > end;
+ start = Math.max(0, start || 0);
+ end = Math.min(items.length, end ? end : items.length);
+ return util.map(util.range(start, end, reverse),
+ function (i) cache[i] = cache[i] || util.xmlToDom(self.createRow(items[i]), doc));
+ },
+
fork: function fork(name, offset, completer, self)
{
let context = new CompletionContext(this, name, offset);
diff --git a/content/template.js b/content/template.js
index 8abe74a4..09d3effc 100644
--- a/content/template.js
+++ b/content/template.js
@@ -32,7 +32,7 @@ const template = {
return <>{xml}>;
},
- completionRow: function completionRow(context, item, class)
+ completionRow: function completionRow(item, class)
{
if (typeof icon == "function")
icon = icon();
@@ -43,8 +43,8 @@ const template = {
}
else
{
- var text = context.process[0].call(context, item, item.text || context.getKey(item, "text"));
- var desc = context.process[1].call(context, item, context.getKey(item, "description"));
+ var text = this.process[0].call(this, item, item.text || this.getKey(item, "text"));
+ var desc = this.process[1].call(this, item, this.getKey(item, "description"));
}
return
@@ -195,9 +195,9 @@ const template = {
context.format = format;
return this.generic(
- { this.completionRow(context, context.title, "hl-CompTitle") }
+ { this.completionRow(context.title, "hl-CompTitle") }
{
- this.map(items, function (item) template.completionRow(context, { text: context.getKey({item: item}, "text"), item: item }))
+ this.map(items, function (item) template.completionRow.call(context, { text: context.getKey({item: item}, "text"), item: item }))
}
);
},
diff --git a/content/ui.js b/content/ui.js
index e6df59b1..abcf6ef8 100644
--- a/content/ui.js
+++ b/content/ui.js
@@ -1289,6 +1289,8 @@ function ItemList(id) //{{{
var startIndex = -1; // The index of the first displayed item
var endIndex = -1; // The index one *after* the last displayed item
var selIndex = -1; // The index of the currently selected element
+ var div = null;
+ var noCompletions = null;
var completionBody = null;
var minHeight = 0;
var div = null;
@@ -1298,6 +1300,7 @@ function ItemList(id) //{{{
if (container.collapsed)
div.style.minWidth = document.getElementById("liberator-commandline").scrollWidth + "px";
minHeight = Math.max(minHeight, completionBody.getBoundingClientRect().bottom);
+ minHeight = 400;
container.height = minHeight;
div.style.minWidth = undefined;
// FIXME: Belongs elsewhere.
@@ -1306,6 +1309,30 @@ function ItemList(id) //{{{
function getCompletion(index) completionElements[index - startIndex];
+ function init()
+ {
+ function dom(xml) util.xmlToDom(xml, doc);
+ div = dom(
+
+
No Completions
+
+
+ {
+ template.map(util.range(0, maxItems), function (i)
+
)
+ }
+
+
);
+ noCompletions = div.childNodes[0];
+ completionBody = div.childNodes[1];
+ items.contextList.forEach(function (context) {
+ if (!context.items.length)
+ return;
+ context.cache.dom = dom({context.createRow(context.title || [], "hl-CompTitle")}
);
+ completionBody.appendChild(context.cache.dom);
+ });
+ }
+
/**
* uses the entries in "items" to fill the listbox
* does incremental filling to speed up things
@@ -1321,50 +1348,32 @@ function ItemList(id) //{{{
startIndex = offset;
endIndex = Math.min(startIndex + maxItems, items.allItems.items.length);
- // do a full refill of the list:
XML.ignoreWhitespace = true;
let off = 0;
- function getItems(context)
+ function getRows(context)
{
let len = context.items.length;
let start = off;
off += len;
- return context.getItems(offset - start, endIndex - start);
+ return context.getRows(offset - start, endIndex - start, doc);
}
- let xml =
-
- {
- items.allItems.items.length == 0 ?
- No Completions
- : <>>
- }
- {
- template.map(items.contextList, function (context) context.items.length ?
- <>
- { context.createRow(context, context.title || [], "hl-CompTitle") }
- {
- template.map(getItems(context), function (item) context.createRow(context, item))
- }
- >
- : undefined)
- }
-
-
- {
- // Hmm. The problem with not making this a CompItem is that
- // the height and padding aren't the same.
- template.map(util.range(0, maxItems), function (i)
-
)
- }
-
-
;
+ items.contextList.forEach(function (context) {
+ let dom = context.cache.dom;
+ if (!dom)
+ return;
+ while (dom.childNodes[1])
+ dom.removeChild(dom.childNodes[1]);
+ for (let [,row] in Iterator(getRows(context)))
+ dom.appendChild(row);
+ });
+
+ noCompletions.style.display = off > 0 ? "none" : "block";
+
+ let dom = div.cloneNode(true);
+ completionElements = dom.getElementsByClassName("hl-CompItem");
+ doc.body.replaceChild(dom, doc.body.firstChild);
- div = util.xmlToDom(xml, doc);
- completionBody = div.getElementsByClassName("hl-Completions")[0];
- //completionElements = completionBody.childNodes; // Kris: This is broken for things like :dia pr
- completionElements = div.getElementsByClassName("hl-CompItem");
- doc.body.replaceChild(div, doc.body.firstChild);
autoSize();
}
@@ -1395,6 +1404,7 @@ function ItemList(id) //{{{
{
startIndex = endIndex = selIndex = -1;
items = newItems;
+ init();
if (typeof selectedItem == "number")
{
this.selectItem(selectedItem);