1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2026-01-06 17:54:13 +01:00

fixed :open completions for slow computers. We now yield

incremental results, and the user gets more completion, the more often
he presses tab. Need to find out, how to change the "Waiting..." message
to "More results...". Also reminds me, how ugly the completion context
code is partly. We should try to clean it up and remove/merge useless
function to make it's interface smaller and more side-effect free.
This commit is contained in:
Martin Stubenschrott
2009-01-07 03:04:42 +01:00
parent db97184fa4
commit 473c461d3f
3 changed files with 55 additions and 26 deletions

View File

@@ -528,7 +528,9 @@ CompletionContext.prototype = {
cancelAll: function () cancelAll: function ()
{ {
for (let [,context] in Iterator(this.contextList)) // Kris: contextList gives undefined. And why do we have contexts and contextList?
// I am not too much of a fan of a huge API for classes
for (let [,context] in Iterator(this.top.contexts))
{ {
if (context.cancel) if (context.cancel)
context.cancel(); context.cancel();
@@ -1576,6 +1578,7 @@ function Completion() //{{{
context.filterFunc = null; context.filterFunc = null;
context.cancel = function () services.get("autoCompleteSearch").stopSearch(); context.cancel = function () services.get("autoCompleteSearch").stopSearch();
context.compare = null; context.compare = null;
// TODO: shouldn't this timer be deleted by context.cancel?
let timer = new Timer(50, 100, function (result) { let timer = new Timer(50, 100, function (result) {
context.incomplete = result.searchResult >= result.RESULT_NOMATCH_ONGOING; context.incomplete = result.searchResult >= result.RESULT_NOMATCH_ONGOING;
context.completions = [ context.completions = [
@@ -1583,16 +1586,28 @@ function Completion() //{{{
for (i in util.range(0, result.matchCount)) for (i in util.range(0, result.matchCount))
]; ];
}); });
services.get("autoCompleteSearch").stopSearch(); context.generate = function () {
services.get("autoCompleteSearch").startSearch(context.filter, "", context.result, { let minItems = context.minItems || 1;
onSearchResult: function onSearchResult(search, result) services.get("autoCompleteSearch").stopSearch();
{ services.get("autoCompleteSearch").startSearch(context.filter, "", context.result, {
context.result = result; onSearchResult: function (search, result)
timer.tell(result); {
if (result.searchResult <= result.RESULT_SUCCESS) context.result = result;
timer.flush(); timer.tell(result);
} if (result.searchResult <= result.RESULT_SUCCESS)
}); timer.flush();
}
});
let end = Date.now() + 5000;
while (context.incomplete && context.completions.length < minItems && Date.now() < end)
liberator.threadYield(false, true);
// context.message = "More results..."; // very very strange, if I enable this line, completions don't work;
services.get("autoCompleteSearch").stopSearch();
return context.completions;
}
}, },
macro: function macro(context) macro: function macro(context)

View File

@@ -1362,6 +1362,7 @@ const liberator = (function () //{{{
callback.call(self); callback.call(self);
}, },
// TODO: interruptable not used?
threadYield: function (flush, interruptable) threadYield: function (flush, interruptable)
{ {
let mainThread = services.get("threadManager").mainThread; let mainThread = services.get("threadManager").mainThread;

View File

@@ -336,7 +336,7 @@ function CommandLine() //{{{
else else
idx = this.selected + 1; idx = this.selected + 1;
break; break;
case this.RESET: case this.RESET: // TODO: never used for now
idx = null; idx = null;
break; break;
default: default:
@@ -360,22 +360,37 @@ function CommandLine() //{{{
tab: function tab(reverse) tab: function tab(reverse)
{ {
autocompleteTimer.flush(); autocompleteTimer.flush();
// Check if we need to run the completer. // Check if we need to run the completer.
let numElementsNeeded;
if (this.selected == null)
numElementsNeeded = reverse ? 100000 : 1; // better way to specify give me all items than setting to a very large number?
else
numElementsNeeded = reverse ? this.selected : this.selected + 2; // this.selected is zero-based
if (this.context.waitingForTab || this.wildIndex == -1) if (this.context.waitingForTab || this.wildIndex == -1)
this.complete(true, true);
// Would prefer to only do this check when no completion
// is available, but there are complications.
if (this.items.length == 0 || this.context.incomplete)
{ {
// No items. Wait for any unfinished completers. this.complete(true, true);
let end = Date.now() + 5000;
while (this.context.incomplete && /* this.items.length == 0 && */ Date.now() < end)
liberator.threadYield(true, true);
if (this.items.length == 0)
return liberator.beep();
} }
else if (this.context.incomplete && numElementsNeeded > this.items.length)
{
for (let [, context] in Iterator(this.context.contexts))
{
if (context.incomplete && context.generate)
{
// regenerate twice as many items as needed, as regenerating
// to often looks visually bad
context.minItems = numElementsNeeded * 2; // TODO: document minItems, or find a better way
context.regenerate = true;
context._generate(); // HACK
}
if (this.items.length >= numElementsNeeded)
break;
}
}
if (this.items.length == 0)
return liberator.beep();
switch (this.wildtype.replace(/.*:/, "")) switch (this.wildtype.replace(/.*:/, ""))
{ {
@@ -1435,11 +1450,9 @@ function CommandLine() //{{{
{ {
autocompleteTimer.reset(); autocompleteTimer.reset();
// liberator.dump("Resetting completions...");
if (completions) if (completions)
{ {
completions.context.cancelAll(); completions.context.cancelAll();
completions.wildIndex = -1; completions.wildIndex = -1;
completions.previewClear(); completions.previewClear();
} }