mirror of https://github.com/vector-im/riot-web
Add allowLooping opt for tab completion. Make peeking work.
parent
ab0a277d94
commit
4e79c3c4c8
|
@ -26,6 +26,7 @@ class TabComplete {
|
||||||
constructor(opts) {
|
constructor(opts) {
|
||||||
opts.startingWordSuffix = opts.startingWordSuffix || "";
|
opts.startingWordSuffix = opts.startingWordSuffix || "";
|
||||||
opts.wordSuffix = opts.wordSuffix || "";
|
opts.wordSuffix = opts.wordSuffix || "";
|
||||||
|
opts.allowLooping = opts.allowLooping || false;
|
||||||
this.opts = opts;
|
this.opts = opts;
|
||||||
this.completing = false;
|
this.completing = false;
|
||||||
this.list = []; // full set of tab-completable things
|
this.list = []; // full set of tab-completable things
|
||||||
|
@ -57,6 +58,12 @@ class TabComplete {
|
||||||
return this.completing;
|
return this.completing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stopTabCompleting() {
|
||||||
|
this.completing = false;
|
||||||
|
this.currentIndex = 0;
|
||||||
|
this._notifyStateChange();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Number} numAheadToPeek Return *up to* this many elements.
|
* @param {Number} numAheadToPeek Return *up to* this many elements.
|
||||||
* @return {TabComplete.Entry[]}
|
* @return {TabComplete.Entry[]}
|
||||||
|
@ -65,25 +72,25 @@ class TabComplete {
|
||||||
if (this.matchedList.length === 0) {
|
if (this.matchedList.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
var peekList = [];
|
||||||
|
|
||||||
var peekList = [
|
|
||||||
this.matchedList[this.currentIndex]
|
|
||||||
];
|
|
||||||
// return the current match item and then one with an index higher, and
|
// return the current match item and then one with an index higher, and
|
||||||
// so on until we've reached the requested limit OR we've looped back
|
// so on until we've reached the requested limit. If we hit the end of
|
||||||
// around to our starting index.
|
// the list of options we're done.
|
||||||
for (var i = 1; i < numAheadToPeek; i++) {
|
for (var i = 0; i < numAheadToPeek; i++) {
|
||||||
var nextIndex = this.currentIndex + i;
|
var nextIndex;
|
||||||
if (nextIndex >= this.matchedList.length) {
|
if (this.opts.allowLooping) {
|
||||||
// wrap around and take account of how far we've wrapped
|
nextIndex = (this.currentIndex + i) % this.matchedList.length;
|
||||||
nextIndex -= this.matchedList.length;
|
|
||||||
}
|
}
|
||||||
// check for looping back to start
|
else {
|
||||||
if (nextIndex === this.currentIndex) {
|
nextIndex = this.currentIndex + i;
|
||||||
break; // no more items to return without looping
|
if (nextIndex === this.matchedList.length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
peekList.push(this.matchedList[nextIndex]);
|
peekList.push(this.matchedList[nextIndex]);
|
||||||
}
|
}
|
||||||
|
// console.log("Peek list(%s): %s", numAheadToPeek, JSON.stringify(peekList));
|
||||||
return peekList;
|
return peekList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,9 +103,7 @@ class TabComplete {
|
||||||
if (ev.keyCode !== KEY_TAB) {
|
if (ev.keyCode !== KEY_TAB) {
|
||||||
if (ev.keyCode !== KEY_SHIFT && this.completing) {
|
if (ev.keyCode !== KEY_SHIFT && this.completing) {
|
||||||
// they're resuming typing; reset tab complete state vars.
|
// they're resuming typing; reset tab complete state vars.
|
||||||
this.completing = false;
|
this.stopTabCompleting();
|
||||||
this.currentIndex = 0;
|
|
||||||
this._notifyStateChange();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -137,16 +142,15 @@ class TabComplete {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var looped = false;
|
|
||||||
// work out the new index, wrapping if necessary.
|
// work out the new index, wrapping if necessary.
|
||||||
this.currentIndex += offset;
|
this.currentIndex += offset;
|
||||||
if (this.currentIndex >= this.matchedList.length) {
|
if (this.currentIndex >= this.matchedList.length) {
|
||||||
this.currentIndex = 0;
|
this.currentIndex = 0;
|
||||||
looped = true;
|
|
||||||
}
|
}
|
||||||
else if (this.currentIndex < 0) {
|
else if (this.currentIndex < 0) {
|
||||||
this.currentIndex = this.matchedList.length - 1;
|
this.currentIndex = this.matchedList.length - 1;
|
||||||
}
|
}
|
||||||
|
var looped = this.currentIndex === 0; // catch forward and backward looping
|
||||||
|
|
||||||
var suffix = "";
|
var suffix = "";
|
||||||
|
|
||||||
|
@ -165,6 +169,10 @@ class TabComplete {
|
||||||
setTimeout(() => { // yay for lexical 'this'!
|
setTimeout(() => { // yay for lexical 'this'!
|
||||||
this.textArea.style["background-color"] = "";
|
this.textArea.style["background-color"] = "";
|
||||||
}, 150);
|
}, 150);
|
||||||
|
|
||||||
|
if (!this.opts.allowLooping) {
|
||||||
|
this.stopTabCompleting();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.textArea.style["background-color"] = ""; // cancel blinks TODO: required?
|
this.textArea.style["background-color"] = ""; // cancel blinks TODO: required?
|
||||||
|
|
|
@ -91,6 +91,7 @@ module.exports = React.createClass({
|
||||||
this.tabComplete = new TabComplete({
|
this.tabComplete = new TabComplete({
|
||||||
startingWordSuffix: ": ",
|
startingWordSuffix: ": ",
|
||||||
wordSuffix: " ",
|
wordSuffix: " ",
|
||||||
|
allowLooping: false,
|
||||||
onStateChange: (isCompleting) => {
|
onStateChange: (isCompleting) => {
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue