mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2026-04-01 22:53:33 +02:00
Fix rapid succession <Tab><Tab> when busy. Don't wait for all contexts to complete when processing <Tab>
This commit is contained in:
@@ -155,7 +155,9 @@ function CompletionContext(editor, name, offset) //{{{
|
|||||||
/**
|
/**
|
||||||
* @property {Object} A map of all contexts, keyed on their names.
|
* @property {Object} A map of all contexts, keyed on their names.
|
||||||
* Names are assigned when a context is forked, with its specified
|
* Names are assigned when a context is forked, with its specified
|
||||||
* name appended, after a '/', to its parent's name.
|
* name appended, after a '/', to its parent's name. May
|
||||||
|
* contain inactive contexts. For active contexts, see
|
||||||
|
* {@link #contextList}.
|
||||||
*/
|
*/
|
||||||
this.contexts = { "/": this };
|
this.contexts = { "/": this };
|
||||||
/**
|
/**
|
||||||
@@ -638,6 +640,11 @@ CompletionContext.prototype = {
|
|||||||
for (let type in this.selectionTypes)
|
for (let type in this.selectionTypes)
|
||||||
this.highlight(0, 0, type);
|
this.highlight(0, 0, type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {[CompletionContext]} A list of active
|
||||||
|
* completion contexts, in the order in which they were
|
||||||
|
* instantiated.
|
||||||
|
*/
|
||||||
this.contextList = [];
|
this.contextList = [];
|
||||||
this.offset = 0;
|
this.offset = 0;
|
||||||
this.process = [];
|
this.process = [];
|
||||||
|
|||||||
@@ -1014,7 +1014,7 @@ function Events() //{{{
|
|||||||
if (event.metaKey)
|
if (event.metaKey)
|
||||||
modifier += "M-";
|
modifier += "M-";
|
||||||
|
|
||||||
if (event.type == "keypress")
|
if (/^key/.test(event.type))
|
||||||
{
|
{
|
||||||
if (event.charCode == 0)
|
if (event.charCode == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
|||||||
<label class="plain" id="liberator-commandline-prompt" flex="0" crop="end" value="" collapsed="true"/>
|
<label class="plain" id="liberator-commandline-prompt" flex="0" crop="end" value="" collapsed="true"/>
|
||||||
<textbox class="plain" id="liberator-commandline-command" flex="1" type="timed" timeout="100"
|
<textbox class="plain" id="liberator-commandline-command" flex="1" type="timed" timeout="100"
|
||||||
oninput="liberator.modules.commandline.onEvent(event);"
|
oninput="liberator.modules.commandline.onEvent(event);"
|
||||||
|
onkeyup="liberator.modules.commandline.onEvent(event);"
|
||||||
onfocus="liberator.modules.commandline.onEvent(event);"
|
onfocus="liberator.modules.commandline.onEvent(event);"
|
||||||
onblur="liberator.modules.commandline.onEvent(event);"/>
|
onblur="liberator.modules.commandline.onEvent(event);"/>
|
||||||
</hbox>
|
</hbox>
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ function CommandLine() //{{{
|
|||||||
{
|
{
|
||||||
case this.UP:
|
case this.UP:
|
||||||
if (this.selected == null)
|
if (this.selected == null)
|
||||||
idx = this.items.length - 1;
|
idx = -2
|
||||||
else
|
else
|
||||||
idx = this.selected - 1;
|
idx = this.selected - 1;
|
||||||
break;
|
break;
|
||||||
@@ -369,8 +369,8 @@ function CommandLine() //{{{
|
|||||||
idx = Math.max(0, Math.min(this.items.length - 1, idx));
|
idx = Math.max(0, Math.min(this.items.length - 1, idx));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.itemList.selectItem(idx);
|
|
||||||
if (idx < 0 || idx >= this.items.length || idx == null)
|
if (idx == -1 || this.items.length && idx >= this.items.length || idx == null)
|
||||||
{
|
{
|
||||||
// Wrapped. Start again.
|
// Wrapped. Start again.
|
||||||
this.selected = null;
|
this.selected = null;
|
||||||
@@ -378,9 +378,32 @@ function CommandLine() //{{{
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Wait for contexts to complete if necessary.
|
||||||
|
// FIXME: Need to make idx relative to individual contexts.
|
||||||
|
let list = this.context.contextList.reverse();
|
||||||
|
if (idx == -2)
|
||||||
|
list = list.slice().reverse();
|
||||||
|
let n = 0;
|
||||||
|
for (let [,context] in Iterator(list))
|
||||||
|
{
|
||||||
|
function done() !(idx >= n + context.items.length || idx == -2 && !context.items.length);
|
||||||
|
while (context.incomplete && !done())
|
||||||
|
liberator.threadYield(true, true);
|
||||||
|
if (done())
|
||||||
|
break;
|
||||||
|
n += context.items.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// See previous FIXME. This will break if new items in
|
||||||
|
// a previous context come in.
|
||||||
|
if (idx < 0)
|
||||||
|
idx = this.items.length - 1;
|
||||||
|
|
||||||
this.selected = idx;
|
this.selected = idx;
|
||||||
this.completion = this.items[idx].text;
|
this.completion = this.items[idx].text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.itemList.selectItem(idx);
|
||||||
},
|
},
|
||||||
|
|
||||||
tab: function tab(reverse)
|
tab: function tab(reverse)
|
||||||
@@ -390,19 +413,6 @@ function CommandLine() //{{{
|
|||||||
if (this.context.waitingForTab || this.wildIndex == -1)
|
if (this.context.waitingForTab || this.wildIndex == -1)
|
||||||
this.complete(true, true);
|
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.
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (this.wildtype.replace(/.*:/, ""))
|
switch (this.wildtype.replace(/.*:/, ""))
|
||||||
{
|
{
|
||||||
case "":
|
case "":
|
||||||
@@ -421,6 +431,9 @@ function CommandLine() //{{{
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.items.length == 0)
|
||||||
|
return void liberator.beep();
|
||||||
|
|
||||||
if (this.type.list)
|
if (this.type.list)
|
||||||
completionList.show();
|
completionList.show();
|
||||||
|
|
||||||
@@ -1276,6 +1289,7 @@ function CommandLine() //{{{
|
|||||||
}
|
}
|
||||||
else if (event.type == "keyup")
|
else if (event.type == "keyup")
|
||||||
{
|
{
|
||||||
|
let key = events.toString(event);
|
||||||
if (key == "<Tab>" || key == "<S-Tab>")
|
if (key == "<Tab>" || key == "<S-Tab>")
|
||||||
tabTimer.flush();
|
tabTimer.flush();
|
||||||
}
|
}
|
||||||
@@ -1608,7 +1622,6 @@ function CommandLine() //{{{
|
|||||||
if (completions)
|
if (completions)
|
||||||
{
|
{
|
||||||
completions.context.cancelAll();
|
completions.context.cancelAll();
|
||||||
|
|
||||||
completions.wildIndex = -1;
|
completions.wildIndex = -1;
|
||||||
completions.previewClear();
|
completions.previewClear();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user