mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-20 08:07:59 +01:00
Completion internals work.
This commit is contained in:
@@ -1093,6 +1093,8 @@ var CommandLine = Module("commandline", {
|
|||||||
|
|
||||||
lastSubstring: "",
|
lastSubstring: "",
|
||||||
|
|
||||||
|
get activeContexts() this.context.activeContexts,
|
||||||
|
|
||||||
get completion() {
|
get completion() {
|
||||||
let str = commandline.command;
|
let str = commandline.command;
|
||||||
return str.substring(this.prefix.length, str.length - this.suffix.length);
|
return str.substring(this.prefix.length, str.length - this.suffix.length);
|
||||||
@@ -1144,15 +1146,40 @@ var CommandLine = Module("commandline", {
|
|||||||
haveType: function haveType(type)
|
haveType: function haveType(type)
|
||||||
this.wildmode.checkHas(this.wildtype, type == "first" ? "" : type),
|
this.wildmode.checkHas(this.wildtype, type == "first" ? "" : type),
|
||||||
|
|
||||||
|
getItem: function getItem(tuple) {
|
||||||
|
tuple = tuple || this.selected;
|
||||||
|
return tuple[0].items[tuple[1]];
|
||||||
|
},
|
||||||
|
|
||||||
|
nextItem: function nextItem(tuple, offset, noWrap) {
|
||||||
|
if (!this.activeContexts.length)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (tuple === undefined)
|
||||||
|
tuple = this.selected;
|
||||||
|
if (!tuple) {
|
||||||
|
// kludge.
|
||||||
|
noWrap = false;
|
||||||
|
if (offset < 0)
|
||||||
|
tuple = [this.activeContexts[0], 0];
|
||||||
|
else {
|
||||||
|
let ctxt = this.activeContexts.slice(-1)[0];
|
||||||
|
tuple = [ctxt, ctxt.items.length - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.itemList.getRelativeItem(offset || 1, tuple, noWrap);
|
||||||
|
},
|
||||||
|
|
||||||
preview: function preview() {
|
preview: function preview() {
|
||||||
this.previewClear();
|
this.previewClear();
|
||||||
if (this.wildIndex < 0 || this.suffix || !this.items.length)
|
if (this.wildIndex < 0 || this.suffix || !this.activeContexts.length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let substring = "";
|
let substring = "";
|
||||||
switch (this.wildtype.replace(/.*:/, "")) {
|
switch (this.wildtype.replace(/.*:/, "")) {
|
||||||
case "":
|
case "":
|
||||||
substring = this.items[0].result;
|
substring = this.getItem(this.nextItem(null)).result;
|
||||||
break;
|
break;
|
||||||
case "longest":
|
case "longest":
|
||||||
if (this.items.length > 1) {
|
if (this.items.length > 1) {
|
||||||
@@ -1161,9 +1188,9 @@ var CommandLine = Module("commandline", {
|
|||||||
}
|
}
|
||||||
// Fallthrough
|
// Fallthrough
|
||||||
case "full":
|
case "full":
|
||||||
let item = this.items[this.selected != null ? this.selected + 1 : 0];
|
let item = this.nextItem();
|
||||||
if (item)
|
if (item)
|
||||||
substring = item.result;
|
substring = this.getItem(item).result;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1237,9 +1264,9 @@ var CommandLine = Module("commandline", {
|
|||||||
if (group && group.context == context && this.completion) {
|
if (group && group.context == context && this.completion) {
|
||||||
this.selected = null;
|
this.selected = null;
|
||||||
if (group.selectedIdx != null)
|
if (group.selectedIdx != null)
|
||||||
this.selected = group.getOffset(group.selectedIdx);
|
this.selected = [group.context, group.selectedIdx];
|
||||||
|
|
||||||
this.completion = this.selected in this.items ? this.items[this.selected].result
|
this.completion = this.selected ? this.getItem().result
|
||||||
: this.value;
|
: this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1248,102 +1275,78 @@ var CommandLine = Module("commandline", {
|
|||||||
|
|
||||||
_select: function _select(dir, idx) {
|
_select: function _select(dir, idx) {
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
case this.CTXT_UP:
|
|
||||||
case this.CTXT_DOWN:
|
|
||||||
let groups = this.itemList.activeGroups;
|
|
||||||
let i = Math.max(0, groups.indexOf(this.itemList.selectedGroup));
|
|
||||||
|
|
||||||
i += dir == this.CTXT_DOWN ? 1 : -1;
|
|
||||||
i %= groups.length;
|
|
||||||
if (i < 0)
|
|
||||||
i += groups.length;
|
|
||||||
|
|
||||||
var position = 0;
|
|
||||||
var group = groups[i];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case this.PAGE_UP:
|
|
||||||
case this.PAGE_DOWN:
|
|
||||||
[group, idx] = this.itemList.getRelativePage(dir == this.PAGE_DOWN ? 1 : -1);
|
|
||||||
group = this.itemList.getGroup(group);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.wildIndex = this.wildtypes.length - 1;
|
this.selected = [group.context, idx];
|
||||||
this.selected = group.offsets.start + idx;
|
this.completion = this.getItem().result;
|
||||||
this.completion = this.items[this.selected].result;
|
|
||||||
|
|
||||||
this.itemList.select(group.context, idx, position);
|
this.itemList.select(group.context, idx, position);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
select: function select(idx, count) {
|
select: function select(idx, count, fromTab) {
|
||||||
|
count = count || 1;
|
||||||
|
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case this.UP:
|
case this.UP:
|
||||||
if (this.selected == null)
|
|
||||||
idx = -1 - count;
|
|
||||||
else
|
|
||||||
idx = this.selected - count;
|
|
||||||
break;
|
|
||||||
case this.DOWN:
|
case this.DOWN:
|
||||||
if (this.selected == null)
|
idx = this.nextItem(this.selected, idx == this.UP ? -count : count,
|
||||||
idx = count - 1;
|
true);
|
||||||
else
|
|
||||||
idx = this.selected + count;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case this.CTXT_UP:
|
||||||
|
case this.CTXT_DOWN:
|
||||||
|
let groups = this.itemList.activeGroups;
|
||||||
|
let i = Math.max(0, groups.indexOf(this.itemList.selectedGroup));
|
||||||
|
|
||||||
|
i += idx == this.CTXT_DOWN ? 1 : -1;
|
||||||
|
i %= groups.length;
|
||||||
|
if (i < 0)
|
||||||
|
i += groups.length;
|
||||||
|
|
||||||
|
var position = 0;
|
||||||
|
idx = [groups[i].context, 0];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case this.PAGE_UP:
|
||||||
|
case this.PAGE_DOWN:
|
||||||
|
idx = this.itemList.getRelativePage(idx == this.PAGE_DOWN ? 1 : -1);
|
||||||
|
break;
|
||||||
|
|
||||||
case this.RESET:
|
case this.RESET:
|
||||||
idx = null;
|
idx = null;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (this._select(idx, 0))
|
|
||||||
return;
|
|
||||||
idx = Math.constrain(idx, 0, this.items.length - 1);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx == -1 || this.items.length && idx >= this.items.length || idx == null) {
|
if (!fromTab)
|
||||||
|
this.wildIndex = this.wildtypes.length - 1;
|
||||||
|
|
||||||
|
if (idx == null || !this.activeContexts.length) {
|
||||||
// Wrapped. Start again.
|
// Wrapped. Start again.
|
||||||
this.selected = null;
|
this.selected = null;
|
||||||
this.completion = this.value;
|
this.completion = this.value;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Wait for contexts to complete if necessary.
|
|
||||||
// FIXME: Need to make idx relative to individual contexts.
|
|
||||||
let list = this.context.contextList;
|
|
||||||
if (idx == -2)
|
|
||||||
list = list.slice().reverse();
|
|
||||||
let n = 0;
|
|
||||||
try {
|
|
||||||
this.waiting = true;
|
|
||||||
for (let [, context] in Iterator(list)) {
|
|
||||||
let done = function done() !(idx >= n + context.items.length || idx == -2 && !context.items.length);
|
|
||||||
|
|
||||||
util.waitFor(function () !context.incomplete || done());
|
|
||||||
if (done())
|
|
||||||
break;
|
|
||||||
|
|
||||||
n += context.items.length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
this.waiting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// See previous FIXME. This will break if new items in
|
|
||||||
// a previous context come in.
|
|
||||||
if (idx < 0)
|
|
||||||
idx = this.items.length - 1;
|
|
||||||
if (this.items.length == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.selected = idx;
|
this.selected = idx;
|
||||||
this.completion = this.items[idx].result;
|
this.completion = this.getItem().result;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.itemList.selectItem(idx);
|
this.itemList.select(idx, null, position);
|
||||||
|
|
||||||
|
this.preview();
|
||||||
|
|
||||||
|
if (this.selected == null)
|
||||||
|
statusline.progress = "";
|
||||||
|
else
|
||||||
|
statusline.progress = _("completion.matchIndex",
|
||||||
|
this.itemList.getOffset(idx),
|
||||||
|
this.itemList.itemCount);
|
||||||
},
|
},
|
||||||
|
|
||||||
tabs: [],
|
tabs: [],
|
||||||
@@ -1361,16 +1364,19 @@ var CommandLine = Module("commandline", {
|
|||||||
this.complete(true, true);
|
this.complete(true, true);
|
||||||
|
|
||||||
this.tabs.push([count, wildmode || options["wildmode"]]);
|
this.tabs.push([count, wildmode || options["wildmode"]]);
|
||||||
if (this.waiting)
|
if (this.waiting && false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (this.tabs.length) {
|
while (this.tabs.length) {
|
||||||
[count, this.wildtypes] = this.tabs.shift();
|
[count, this.wildtypes] = this.tabs.shift();
|
||||||
|
let steps = Math.constrain(this.wildtypes.length - this.wildIndex, 1, count);
|
||||||
|
count = Math.max(1, count - steps);
|
||||||
|
|
||||||
|
while (steps--) {
|
||||||
this.wildIndex = Math.min(this.wildIndex, this.wildtypes.length - 1);
|
this.wildIndex = Math.min(this.wildIndex, this.wildtypes.length - 1);
|
||||||
switch (this.wildtype.replace(/.*:/, "")) {
|
switch (this.wildtype.replace(/.*:/, "")) {
|
||||||
case "":
|
case "":
|
||||||
this.select(0);
|
this.select(this.nextItem(null));
|
||||||
break;
|
break;
|
||||||
case "longest":
|
case "longest":
|
||||||
if (this.items.length > 1) {
|
if (this.items.length > 1) {
|
||||||
@@ -1380,7 +1386,8 @@ var CommandLine = Module("commandline", {
|
|||||||
}
|
}
|
||||||
// Fallthrough
|
// Fallthrough
|
||||||
case "full":
|
case "full":
|
||||||
this.select(count < 0 ? this.UP : this.DOWN, Math.abs(count));
|
let c = steps ? 1 : count;
|
||||||
|
this.select(c < 0 ? this.UP : this.DOWN, Math.abs(c), true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1388,12 +1395,7 @@ var CommandLine = Module("commandline", {
|
|||||||
this.itemList.visible = true;
|
this.itemList.visible = true;
|
||||||
|
|
||||||
this.wildIndex++;
|
this.wildIndex++;
|
||||||
this.preview();
|
}
|
||||||
|
|
||||||
if (this.selected == null)
|
|
||||||
statusline.progress = "";
|
|
||||||
else
|
|
||||||
statusline.progress = _("completion.matchIndex", this.selected + 1, this.items.length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.items.length == 0)
|
if (this.items.length == 0)
|
||||||
@@ -1732,30 +1734,43 @@ var ItemList = Class("ItemList", {
|
|||||||
|| c.hasItems && c.items.length)
|
|| c.hasItems && c.items.length)
|
||||||
.map(this.getGroup, this),
|
.map(this.getGroup, this),
|
||||||
|
|
||||||
getRelativePage: function getRelativePage(offset) {
|
getRelativeItem: function getRelativeItem(offset, tuple, noWrap) {
|
||||||
let groups = this.activeGroups;
|
let groups = this.activeGroups;
|
||||||
let group = this.selectedGroup || groups[0];
|
|
||||||
|
|
||||||
let start = group.offsets.start + (group.selectedIdx || 0);
|
let group = this.selectedGroup || groups[0];
|
||||||
start = (start + (this.maxItems * offset)) % this.itemCount;;
|
let start = group.selectedIdx || 0;
|
||||||
|
if (tuple)
|
||||||
|
[group, start] = tuple;
|
||||||
|
group = this.getGroup(group);
|
||||||
|
|
||||||
|
start = (group.offsets.start + start + offset);
|
||||||
|
if (!noWrap)
|
||||||
|
start %= this.itemCount;
|
||||||
if (start < 0)
|
if (start < 0)
|
||||||
start += this.itemCount;
|
start += this.itemCount;
|
||||||
|
|
||||||
|
if (start < 0 || start >= this.itemCount)
|
||||||
|
return null;
|
||||||
|
|
||||||
group = array.nth(groups, function (g) let (i = start - g.offsets.start) i >= 0 && i < g.itemCount, 0)
|
group = array.nth(groups, function (g) let (i = start - g.offsets.start) i >= 0 && i < g.itemCount, 0)
|
||||||
return [group.context, start - group.offsets.start];
|
return [group.context, start - group.offsets.start];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getRelativePage: function getRelativePage(offset, tuple, noWrap) {
|
||||||
|
return this.getRelativeItem(offset * this.maxItems, tuple);
|
||||||
|
},
|
||||||
|
|
||||||
open: function open(context) {
|
open: function open(context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.nodes = {};
|
this.nodes = {};
|
||||||
this.maxHeight = 0;
|
this.container.height = 0;
|
||||||
|
this.minHeight = 0;
|
||||||
this.maxItems = options["maxitems"];
|
this.maxItems = options["maxitems"];
|
||||||
|
|
||||||
DOM(this.rootXML, this.doc, this.nodes)
|
DOM(this.rootXML, this.doc, this.nodes)
|
||||||
.appendTo(DOM(this.body).empty());
|
.appendTo(DOM(this.body).empty());
|
||||||
|
|
||||||
this.update();
|
this.update();
|
||||||
this.visible = true;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
updateOffsets: function updateOffsets() {
|
updateOffsets: function updateOffsets() {
|
||||||
@@ -1853,7 +1868,9 @@ var ItemList = Class("ItemList", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
select: function select(group, index, position) {
|
select: function select(group, index, position) {
|
||||||
if (group && !(group instanceof ItemList.Group))
|
if (isArray(group))
|
||||||
|
[group, index] = group;
|
||||||
|
|
||||||
group = this.getGroup(group);
|
group = this.getGroup(group);
|
||||||
|
|
||||||
if (this.selectedGroup && (!group || group != this.selectedGroup))
|
if (this.selectedGroup && (!group || group != this.selectedGroup))
|
||||||
@@ -1915,8 +1932,12 @@ var ItemList = Class("ItemList", {
|
|||||||
this.select(group && group.context, idx);
|
this.select(group && group.context, idx);
|
||||||
},
|
},
|
||||||
|
|
||||||
getGroup: function getGroup(context) context &&
|
getGroup: function getGroup(context)
|
||||||
context.getCache("itemlist-group", bind("Group", ItemList, this, context))
|
context instanceof ItemList.Group ? context
|
||||||
|
: context && context.getCache("itemlist-group",
|
||||||
|
bind("Group", ItemList, this, context)),
|
||||||
|
|
||||||
|
getOffset: function getOffset(tuple) this.getGroup(tuple[0]).getOffset(tuple[1])
|
||||||
}, {
|
}, {
|
||||||
RESIZE_BRIEF: 1 << 0,
|
RESIZE_BRIEF: 1 << 0,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user