mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-23 15:52:29 +01:00
fixed :open foo<tab> completion when writing very fast and when not using wop=auto. Many other small architectural completion improvements, more to come...
This commit is contained in:
6
TODO
6
TODO
@@ -1,6 +1,5 @@
|
|||||||
<pre>
|
|
||||||
Priority list:
|
Priority list:
|
||||||
1-9 as in Vim (9=required for next release, 5=would be nice, 1=probably not)
|
1-9 as in Vim (9 = required for next release, 5 = would be nice, 1 = probably not)
|
||||||
|
|
||||||
BUGS:
|
BUGS:
|
||||||
- add window resize support to hints
|
- add window resize support to hints
|
||||||
@@ -23,6 +22,7 @@ BUGS:
|
|||||||
- :set! browser.urlbar.clickSelectsAll=true -> clicking in the location bar unfocuses it immediately
|
- :set! browser.urlbar.clickSelectsAll=true -> clicking in the location bar unfocuses it immediately
|
||||||
- http://apcmag.com/why_os_x_106_snow_leopard_should_leave_powerpc_in_the_cold.htm - scrolls the wrong
|
- http://apcmag.com/why_os_x_106_snow_leopard_should_leave_powerpc_in_the_cold.htm - scrolls the wrong
|
||||||
window with j/k (the green slashdot thing for me).
|
window with j/k (the green slashdot thing for me).
|
||||||
|
- http://cgiirc.blitzed.org?chan=%23debug is unusable after login in
|
||||||
|
|
||||||
(recent CVS regressions):
|
(recent CVS regressions):
|
||||||
- A cached "awesomebar completion" result is still displayed, after the user removes "l" from the 'cpt' and
|
- A cached "awesomebar completion" result is still displayed, after the user removes "l" from the 'cpt' and
|
||||||
@@ -34,6 +34,7 @@ BUGS:
|
|||||||
:b a<tab> changes the (Untitled) title to "about:blank"
|
:b a<tab> changes the (Untitled) title to "about:blank"
|
||||||
- visual caret mode is broken
|
- visual caret mode is broken
|
||||||
- Tabbing between form elems triggers NORMAL mode
|
- Tabbing between form elems triggers NORMAL mode
|
||||||
|
- :bmarks, :hs output and 'cpt'=bh completions are broken
|
||||||
|
|
||||||
FEATURES:
|
FEATURES:
|
||||||
9 adaptive timeout for auto-completions, :set completions can be updated more often than
|
9 adaptive timeout for auto-completions, :set completions can be updated more often than
|
||||||
@@ -87,4 +88,3 @@ FEATURES:
|
|||||||
|
|
||||||
RANDOM IDEAS:
|
RANDOM IDEAS:
|
||||||
* hide scrollbars: (window.content.document.body.style.overflow = "hidden" has problems with the mouse wheel)
|
* hide scrollbars: (window.content.document.body.style.overflow = "hidden" has problems with the mouse wheel)
|
||||||
</pre>
|
|
||||||
|
|||||||
@@ -58,6 +58,11 @@ function Completion() //{{{
|
|||||||
var completionCache = [];
|
var completionCache = [];
|
||||||
|
|
||||||
var historyTimer = new util.Timer(50, 100, function histTimer() {
|
var historyTimer = new util.Timer(50, 100, function histTimer() {
|
||||||
|
// don't set all completions again every time the timer fires, even
|
||||||
|
// though items might not have changed
|
||||||
|
if (historyCache.length == historyResult.matchCount)
|
||||||
|
return;
|
||||||
|
|
||||||
let comp = [];
|
let comp = [];
|
||||||
for (let i in util.range(0, historyResult.matchCount))
|
for (let i in util.range(0, historyResult.matchCount))
|
||||||
comp.push([historyResult.getValueAt(i),
|
comp.push([historyResult.getValueAt(i),
|
||||||
@@ -66,8 +71,9 @@ function Completion() //{{{
|
|||||||
|
|
||||||
//let foo = ["", "IGNORED", "FAILURE", "NOMATCH", "SUCCESS", "NOMATCH_ONGOING", "SUCCESS_ONGOING"];
|
//let foo = ["", "IGNORED", "FAILURE", "NOMATCH", "SUCCESS", "NOMATCH_ONGOING", "SUCCESS_ONGOING"];
|
||||||
|
|
||||||
|
// TODO: we need to have a "completionCacheAfter" to allow cpt=slf
|
||||||
historyCache = comp;
|
historyCache = comp;
|
||||||
commandline.setCompletions({ get completions() { return completionCache.concat(historyCache); } });
|
commandline.setCompletions({ get items() { return completionCache.concat(historyCache); } });
|
||||||
});
|
});
|
||||||
|
|
||||||
function Javascript()
|
function Javascript()
|
||||||
@@ -807,7 +813,7 @@ function Completion() //{{{
|
|||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
start: 0,
|
start: 0,
|
||||||
get completions() { return bookmarks.get(filter) },
|
get items() { return bookmarks.get(filter) },
|
||||||
createRow: function (item)
|
createRow: function (item)
|
||||||
<ul class="hl-CompItem">
|
<ul class="hl-CompItem">
|
||||||
<li class="hl-CompIcon"><img src={item.icon || ""}/></li>
|
<li class="hl-CompIcon"><img src={item.icon || ""}/></li>
|
||||||
@@ -943,7 +949,7 @@ function Completion() //{{{
|
|||||||
var [count, cmd, special, args] = commands.parseCommand(str);
|
var [count, cmd, special, args] = commands.parseCommand(str);
|
||||||
var matches = str.match(/^(:*\d*)\w*$/);
|
var matches = str.match(/^(:*\d*)\w*$/);
|
||||||
if (matches)
|
if (matches)
|
||||||
return { start: matches[1].length, completions: this.command(cmd)[1] };
|
return { start: matches[1].length, items: this.command(cmd)[1] };
|
||||||
|
|
||||||
// dynamically get completions as specified with the command's completer function
|
// dynamically get completions as specified with the command's completer function
|
||||||
var compObject = { start: 0, completions: [] };
|
var compObject = { start: 0, completions: [] };
|
||||||
@@ -955,7 +961,7 @@ function Completion() //{{{
|
|||||||
exLength = matches ? matches[0].length : 0;
|
exLength = matches ? matches[0].length : 0;
|
||||||
compObject = command.completer.call(this, args, special);
|
compObject = command.completer.call(this, args, special);
|
||||||
if (compObject instanceof Array) // for now at least, let completion functions return arrays instead of objects
|
if (compObject instanceof Array) // for now at least, let completion functions return arrays instead of objects
|
||||||
compObject = { start: compObject[0], completions: compObject[1] };
|
compObject = { start: compObject[0], items: compObject[1] };
|
||||||
}
|
}
|
||||||
compObject.start += exLength;
|
compObject.start += exLength;
|
||||||
return compObject;
|
return compObject;
|
||||||
@@ -1198,8 +1204,41 @@ function Completion() //{{{
|
|||||||
// if the 'complete' argument is passed like "h", it temporarily overrides the complete option
|
// if the 'complete' argument is passed like "h", it temporarily overrides the complete option
|
||||||
url: function url(filter, complete)
|
url: function url(filter, complete)
|
||||||
{
|
{
|
||||||
|
function getMoreItems(count, maxTime)
|
||||||
|
{
|
||||||
|
maxTime = maxTime || 5000; // maximum time to wait, default 5 sec
|
||||||
|
count = count || 10;
|
||||||
|
|
||||||
|
var completions = [];
|
||||||
|
historyResult = null;
|
||||||
|
let then = new Date().getTime();
|
||||||
|
for (let now = then; now - then < maxTime; now = new Date().getTime())
|
||||||
|
{
|
||||||
|
liberator.threadYield();
|
||||||
|
if (!historyResult)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (historyResult.searchResult == historyResult.RESULT_SUCCESS ||
|
||||||
|
historyResult.searchResult == historyResult.RESULT_NOMATCH ||
|
||||||
|
(historyResult.searchResult == historyResult.RESULT_SUCCESS_ONGOING &&
|
||||||
|
historyResult.matchCount >= count + numLocationCompletions))
|
||||||
|
{
|
||||||
|
//liberator.dump("Got " + historyResult.matchCount + " more results after " + (now - then) + " ms with result: " + historyResult.searchResult);
|
||||||
|
//completionService.stopSearch();
|
||||||
|
for (let i in util.range(numLocationCompletions, historyResult.matchCount))
|
||||||
|
completions.push([historyResult.getValueAt(i),
|
||||||
|
historyResult.getCommentAt(i),
|
||||||
|
historyResult.getImageAt(i)]);
|
||||||
|
numLocationCompletions = historyResult.matchCount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return completions;
|
||||||
|
}
|
||||||
|
|
||||||
this.filterString = filter;
|
this.filterString = filter;
|
||||||
var completions = [];
|
var completions = [];
|
||||||
|
var numLocationCompletions = 0; // how many async completions did we already return to the caller?
|
||||||
var start = 0;
|
var start = 0;
|
||||||
var skip = filter.match("^(.*" + options["urlseparator"] + ")(.*)"); // start after the last 'urlseparator'
|
var skip = filter.match("^(.*" + options["urlseparator"] + ")(.*)"); // start after the last 'urlseparator'
|
||||||
if (skip)
|
if (skip)
|
||||||
@@ -1214,32 +1253,34 @@ function Completion() //{{{
|
|||||||
for (let c in util.Array.iterator(cpt))
|
for (let c in util.Array.iterator(cpt))
|
||||||
{
|
{
|
||||||
if (c == "s")
|
if (c == "s")
|
||||||
completions.push(this.search(filter)[1]);
|
completions = completions.concat(this.search(filter)[1]);
|
||||||
else if (c == "f")
|
else if (c == "f")
|
||||||
completions.push(this.file(filter, false)[1]);
|
completions = completions.concat(this.file(filter, false)[1]);
|
||||||
else if (c == "S")
|
else if (c == "S")
|
||||||
completions.push(this.searchEngineSuggest(filter, suggestEngineAlias)[1]);
|
completions = completions.concat(this.searchEngineSuggest(filter, suggestEngineAlias)[1]);
|
||||||
else if (c == "b")
|
else if (c == "b")
|
||||||
completions.push(bookmarks.get(filter));
|
completions = completions.concat(bookmarks.get(filter));
|
||||||
else if (c == "h")
|
else if (c == "h")
|
||||||
completions.push(history.get(filter));
|
completions = completions.concat(history.get(filter));
|
||||||
else if (c == "l" && completionService) // add completions like Firefox's smart location bar
|
else if (c == "l" && completionService) // add completions like Firefox's smart location bar
|
||||||
{
|
{
|
||||||
|
historyCache = [];
|
||||||
|
completionCache = completions.slice(); // make copy of current results
|
||||||
completionService.stopSearch();
|
completionService.stopSearch();
|
||||||
//dump("searching for " + filter + "\n");
|
|
||||||
completionService.startSearch(filter, "", historyResult, {
|
completionService.startSearch(filter, "", historyResult, {
|
||||||
onSearchResult: function onSearchResult(search, result) {
|
onSearchResult: function onSearchResult(search, result) {
|
||||||
historyResult = result;
|
historyResult = result;
|
||||||
|
//liberator.dump("Search result in " + historyResult.matchCount + " results with retval: " + historyResult.searchResult);
|
||||||
historyTimer.tell();
|
historyTimer.tell();
|
||||||
if (result.searchResult <= result.RESULT_SUCCESS)
|
if (result.searchResult <= result.RESULT_SUCCESS)
|
||||||
historyTimer.flush();
|
historyTimer.flush();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
completionCache = util.Array.flatten(completions);
|
return { start: start, items: completions, getMoreItems: getMoreItems };
|
||||||
return [start, completionCache.concat(historyCache)];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
userCommand: function userCommand(filter)
|
userCommand: function userCommand(filter)
|
||||||
|
|||||||
126
content/ui.js
126
content/ui.js
@@ -97,9 +97,8 @@ function CommandLine() //{{{
|
|||||||
var silent = false;
|
var silent = false;
|
||||||
|
|
||||||
var completionList = new ItemList("liberator-completions");
|
var completionList = new ItemList("liberator-completions");
|
||||||
var completions = [];
|
var completions = { start: 0, items: [] };
|
||||||
// for the example command "open sometext| othertext" (| is the cursor pos):
|
// for the example command "open sometext| othertext" (| is the cursor pos):
|
||||||
var completionStartIndex = 0; // will be 5 because we want to complete arguments for the :open command
|
|
||||||
var completionPrefix = ""; // will be: "open sometext"
|
var completionPrefix = ""; // will be: "open sometext"
|
||||||
var completionPostfix = ""; // will be: " othertext"
|
var completionPostfix = ""; // will be: " othertext"
|
||||||
var completionIndex = UNINITIALIZED;
|
var completionIndex = UNINITIALIZED;
|
||||||
@@ -108,10 +107,10 @@ function CommandLine() //{{{
|
|||||||
var startHints = false; // whether we're waiting to start hints mode
|
var startHints = false; // whether we're waiting to start hints mode
|
||||||
|
|
||||||
var statusTimer = new util.Timer(5, 100, function () {
|
var statusTimer = new util.Timer(5, 100, function () {
|
||||||
if (completionIndex >= completions.length)
|
if (completionIndex >= completions.items.length)
|
||||||
statusline.updateProgress("");
|
statusline.updateProgress("");
|
||||||
else
|
else
|
||||||
statusline.updateProgress("match " + (completionIndex + 1) + " of " + completions.length);
|
statusline.updateProgress("match " + (completionIndex + 1) + " of " + completions.items.length);
|
||||||
});
|
});
|
||||||
var autocompleteTimer = new util.Timer(201, 300, function (command) {
|
var autocompleteTimer = new util.Timer(201, 300, function (command) {
|
||||||
if (events.feedingKeys)
|
if (events.feedingKeys)
|
||||||
@@ -543,8 +542,6 @@ function CommandLine() //{{{
|
|||||||
// FORCE_MULTILINE is given, FORCE_MULTILINE takes precedence
|
// FORCE_MULTILINE is given, FORCE_MULTILINE takes precedence
|
||||||
APPEND_TO_MESSAGES : 1 << 3, // add the string to the message history
|
APPEND_TO_MESSAGES : 1 << 3, // add the string to the message history
|
||||||
|
|
||||||
get autocompleteTimer() autocompleteTimer,
|
|
||||||
|
|
||||||
get mode() (modes.extended == modes.EX) ? "cmd" : "search",
|
get mode() (modes.extended == modes.EX) ? "cmd" : "search",
|
||||||
|
|
||||||
get silent() silent,
|
get silent() silent,
|
||||||
@@ -581,9 +578,9 @@ function CommandLine() //{{{
|
|||||||
|
|
||||||
// open the completion list automatically if wanted
|
// open the completion list automatically if wanted
|
||||||
if (/\s/.test(cmd) &&
|
if (/\s/.test(cmd) &&
|
||||||
options.get("wildoptions").has("auto") >= 0 &&
|
options.get("wildoptions").has("auto") &&
|
||||||
extendedMode == modes.EX)
|
extendedMode == modes.EX)
|
||||||
autocompleteTimer.tell(cmd);
|
autocompleteTimer.tell(cmd);
|
||||||
},
|
},
|
||||||
|
|
||||||
// normally used when pressing esc, does not execute a command
|
// normally used when pressing esc, does not execute a command
|
||||||
@@ -599,9 +596,7 @@ function CommandLine() //{{{
|
|||||||
{
|
{
|
||||||
multilineInputWidget.collapsed = true;
|
multilineInputWidget.collapsed = true;
|
||||||
outputContainer.collapsed = true;
|
outputContainer.collapsed = true;
|
||||||
autocompleteTimer.reset();
|
|
||||||
completionList.hide();
|
completionList.hide();
|
||||||
completions = [];
|
|
||||||
this.resetCompletions();
|
this.resetCompletions();
|
||||||
|
|
||||||
setLine("", this.HL_NORMAL);
|
setLine("", this.HL_NORMAL);
|
||||||
@@ -731,7 +726,7 @@ function CommandLine() //{{{
|
|||||||
currentExtendedMode = null; /* Don't let modes.pop trigger "cancel" */
|
currentExtendedMode = null; /* Don't let modes.pop trigger "cancel" */
|
||||||
inputHistory.add(command);
|
inputHistory.add(command);
|
||||||
modes.pop(!commandline.silent);
|
modes.pop(!commandline.silent);
|
||||||
autocompleteTimer.reset();
|
this.resetCompletions();
|
||||||
completionList.hide();
|
completionList.hide();
|
||||||
liberator.focusContent(false);
|
liberator.focusContent(false);
|
||||||
statusline.updateProgress(""); // we may have a "match x of y" visible
|
statusline.updateProgress(""); // we may have a "match x of y" visible
|
||||||
@@ -827,31 +822,37 @@ function CommandLine() //{{{
|
|||||||
// we need to build our completion list first
|
// we need to build our completion list first
|
||||||
if (completionIndex == UNINITIALIZED)
|
if (completionIndex == UNINITIALIZED)
|
||||||
{
|
{
|
||||||
completionStartIndex = 0;
|
|
||||||
completionIndex = -1;
|
completionIndex = -1;
|
||||||
completionPrefix = command.substring(0, commandWidget.selectionStart);
|
completionPrefix = command.substring(0, commandWidget.selectionStart);
|
||||||
completionPostfix = command.substring(commandWidget.selectionStart);
|
completionPostfix = command.substring(commandWidget.selectionStart);
|
||||||
var compObject = liberator.triggerCallback("complete", currentExtendedMode, completionPrefix);
|
completions = liberator.triggerCallback("complete", currentExtendedMode, completionPrefix);
|
||||||
if (compObject)
|
|
||||||
{
|
|
||||||
completionStartIndex = compObject.start;
|
|
||||||
completions = compObject.completions;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sort the completion list
|
// sort the completion list
|
||||||
|
// TODO: might not make sense anymore with our advanced completions, we should just sort when necessary
|
||||||
if (options.get("wildoptions").has("sort"))
|
if (options.get("wildoptions").has("sort"))
|
||||||
compObject.completions.sort(function (a, b) String.localeCompare(a[0], b[0]));
|
completions.items.sort(function (a, b) String.localeCompare(a[0], b[0]));
|
||||||
|
|
||||||
completionList.setItems(compObject);
|
completionList.setItems(completions.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (completions.length == 0)
|
if (completions.items.length == 0)
|
||||||
{
|
{
|
||||||
liberator.beep();
|
// try to fetch more items, if possible
|
||||||
// prevent tab from moving to the next field:
|
// TODO: also use that code when we DO have completions but too few
|
||||||
event.preventDefault();
|
if (completions.getMoreItems)
|
||||||
event.stopPropagation();
|
{
|
||||||
return false;
|
completions.items = completions.items.concat(completions.getMoreItems(1));
|
||||||
|
completionList.setItems(completions.items);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (completions.items.length == 0) // still not more matches
|
||||||
|
{
|
||||||
|
liberator.beep();
|
||||||
|
// prevent tab from moving to the next field:
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (full)
|
if (full)
|
||||||
@@ -860,12 +861,12 @@ function CommandLine() //{{{
|
|||||||
{
|
{
|
||||||
completionIndex--;
|
completionIndex--;
|
||||||
if (completionIndex < -1)
|
if (completionIndex < -1)
|
||||||
completionIndex = completions.length - 1;
|
completionIndex = completions.items.length - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
completionIndex++;
|
completionIndex++;
|
||||||
if (completionIndex > completions.length)
|
if (completionIndex > completions.items.length)
|
||||||
completionIndex = 0;
|
completionIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -877,30 +878,31 @@ function CommandLine() //{{{
|
|||||||
if (hasList)
|
if (hasList)
|
||||||
completionList.show();
|
completionList.show();
|
||||||
|
|
||||||
if ((completionIndex == -1 || completionIndex >= completions.length) && !longest) // wrapped around matches, reset command line
|
if ((completionIndex == -1 || completionIndex >= completions.items.length) && !longest) // wrapped around matches, reset command line
|
||||||
{
|
{
|
||||||
if (full && completions.length > 1)
|
if (full)
|
||||||
setCommand(completionPrefix + completionPostfix);
|
setCommand(completionPrefix + completionPostfix);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var compl = null;
|
var compl = null;
|
||||||
if (longest && completions.length > 1)
|
if (longest && completions.items.length > 1)
|
||||||
compl = completion.getLongestSubstring();
|
compl = completion.getLongestSubstring();
|
||||||
else if (full)
|
else if (full)
|
||||||
compl = completions[completionIndex][0];
|
compl = completions.items[completionIndex][0];
|
||||||
else if (completions.length == 1)
|
else if (completions.items.length == 1)
|
||||||
compl = completions[0][0];
|
compl = completion.items[0][0];
|
||||||
|
|
||||||
if (compl)
|
if (compl)
|
||||||
{
|
{
|
||||||
setCommand(command.substring(0, completionStartIndex) + compl + completionPostfix);
|
setCommand(command.substring(0, completions.start) + compl + completionPostfix);
|
||||||
commandWidget.selectionStart = commandWidget.selectionEnd = completionStartIndex + compl.length;
|
commandWidget.selectionStart = commandWidget.selectionEnd = completions.start + compl.length;
|
||||||
if (longest)
|
if (longest)
|
||||||
liberator.triggerCallback("change", currentExtendedMode, this.getCommand());
|
liberator.triggerCallback("change", currentExtendedMode, this.getCommand());
|
||||||
|
|
||||||
// Start a new completion in the next iteration. Useful for commands like :source
|
// Start a new completion in the next iteration. Useful for commands like :source
|
||||||
// RFC: perhaps the command can indicate whether the completion should be restarted
|
// RFC: perhaps the command can indicate whether the completion should be restarted
|
||||||
|
// -> should be doable now, since the completion items are objects
|
||||||
// Needed for :source to grab another set of completions after a file/directory has been filled out
|
// Needed for :source to grab another set of completions after a file/directory has been filled out
|
||||||
// if (completions.length == 1 && !full)
|
// if (completions.length == 1 && !full)
|
||||||
// completionIndex = UNINITIALIZED;
|
// completionIndex = UNINITIALIZED;
|
||||||
@@ -1220,7 +1222,7 @@ function CommandLine() //{{{
|
|||||||
},
|
},
|
||||||
|
|
||||||
// to allow asynchronous adding of completions
|
// to allow asynchronous adding of completions
|
||||||
setCompletions: function (completionObject)
|
setCompletions: function (newCompletions)
|
||||||
{
|
{
|
||||||
if (liberator.mode != modes.COMMAND_LINE)
|
if (liberator.mode != modes.COMMAND_LINE)
|
||||||
return;
|
return;
|
||||||
@@ -1230,32 +1232,41 @@ function CommandLine() //{{{
|
|||||||
return completionList.hide();
|
return completionList.hide();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let newCompletions = completionObject.completions;
|
completionList.setItems(newCompletions.items);
|
||||||
completionList.setItems(completionObject);
|
|
||||||
|
|
||||||
if (completionIndex >= 0 && completionIndex < newCompletions.length && completionIndex < completions.length)
|
// try to keep the old item selected
|
||||||
|
if (completionIndex >= 0 && completionIndex < newCompletions.items.length && completionIndex < completions.items.length)
|
||||||
{
|
{
|
||||||
if (newCompletions[completionIndex][0] != completions[completionIndex][0])
|
if (newCompletions.items[completionIndex][0] != completions.items[completionIndex][0])
|
||||||
completionIndex = -1;
|
completionIndex = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
completionIndex = -1;
|
completionIndex = -1;
|
||||||
|
|
||||||
|
let oldStart = completions.start;
|
||||||
completions = newCompletions;
|
completions = newCompletions;
|
||||||
|
if (typeof completions.start != "number")
|
||||||
|
completions.start = oldStart;
|
||||||
|
|
||||||
completionList.selectItem(completionIndex);
|
completionList.selectItem(completionIndex);
|
||||||
if (options.get("wildoptions").has("auto"))
|
if (options.get("wildoptions").has("auto"))
|
||||||
completionList.show();
|
completionList.show();
|
||||||
|
|
||||||
|
// why do we have to set that here? Without that, we lose the
|
||||||
|
// prefix when wrapping around searches
|
||||||
|
// with that, we SOMETIMES have problems with <tab> followed by <s-tab> in :open completions
|
||||||
var command = this.getCommand();
|
var command = this.getCommand();
|
||||||
completionPrefix = command.substring(0, commandWidget.selectionStart);
|
completionPrefix = command.substring(0, commandWidget.selectionStart);
|
||||||
completionPostfix = command.substring(commandWidget.selectionStart);
|
completionPostfix = command.substring(commandWidget.selectionStart);
|
||||||
|
|
||||||
if (typeof completionObject.start == "number")
|
|
||||||
completionStartIndex = completionObject.start;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// TODO: does that function need to be public?
|
||||||
resetCompletions: function ()
|
resetCompletions: function ()
|
||||||
{
|
{
|
||||||
|
autocompleteTimer.reset();
|
||||||
|
completion.cancel();
|
||||||
|
completions = { start: 0, items: [] };
|
||||||
completionIndex = historyIndex = UNINITIALIZED;
|
completionIndex = historyIndex = UNINITIALIZED;
|
||||||
wildIndex = 0;
|
wildIndex = 0;
|
||||||
}
|
}
|
||||||
@@ -1269,8 +1280,6 @@ function CommandLine() //{{{
|
|||||||
* @param id: the id of the the XUL <iframe> which we want to fill
|
* @param id: the id of the the XUL <iframe> which we want to fill
|
||||||
* it MUST be inside a <vbox> (or any other html element,
|
* it MUST be inside a <vbox> (or any other html element,
|
||||||
* because otherwise setting the height does not work properly
|
* because otherwise setting the height does not work properly
|
||||||
*
|
|
||||||
* TODO: get rid off "completion" variables, we are dealing with variables after all
|
|
||||||
*/
|
*/
|
||||||
function ItemList(id) //{{{
|
function ItemList(id) //{{{
|
||||||
{
|
{
|
||||||
@@ -1295,8 +1304,7 @@ function ItemList(id) //{{{
|
|||||||
doc.body.id = id + "-content";
|
doc.body.id = id + "-content";
|
||||||
doc.body.appendChild(doc.createTextNode(""));
|
doc.body.appendChild(doc.createTextNode(""));
|
||||||
|
|
||||||
var completions = []; // a reference to the Array of completions
|
var items = [];
|
||||||
var completionObject = {};
|
|
||||||
var startIndex = -1; // The index of the first displayed item
|
var startIndex = -1; // The index of the first displayed item
|
||||||
var endIndex = -1; // The index one *after* the last displayed item
|
var endIndex = -1; // The index one *after* the last displayed item
|
||||||
var selIndex = -1; // The index of the currently selected element
|
var selIndex = -1; // The index of the currently selected element
|
||||||
@@ -1351,7 +1359,7 @@ function ItemList(id) //{{{
|
|||||||
function getCompletion(index) completionElements[index - startIndex];
|
function getCompletion(index) completionElements[index - startIndex];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* uses the entries in completions to fill the listbox
|
* uses the entries in "items" to fill the listbox
|
||||||
* does incremental filling to speed up things
|
* does incremental filling to speed up things
|
||||||
*
|
*
|
||||||
* @param offset: start at this index and show maxItems
|
* @param offset: start at this index and show maxItems
|
||||||
@@ -1359,12 +1367,13 @@ function ItemList(id) //{{{
|
|||||||
function fill(offset)
|
function fill(offset)
|
||||||
{
|
{
|
||||||
let diff = offset - startIndex;
|
let diff = offset - startIndex;
|
||||||
if (offset == null || offset - startIndex == 0 || offset < 0 || completions.length && offset >= completions.length)
|
if (offset == null || offset - startIndex == 0 || offset < 0 || items.length && offset >= items.length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let createRow = ("createRow" in completionObject) ? completionObject.createRow : createDefaultRow;
|
//let createRow = ("createRow" in completionObject) ? completionObject.createRow : createDefaultRow;
|
||||||
|
let createRow = createDefaultRow;
|
||||||
startIndex = offset;
|
startIndex = offset;
|
||||||
endIndex = Math.min(startIndex + maxItems, completions.length);
|
endIndex = Math.min(startIndex + maxItems, items.length);
|
||||||
|
|
||||||
if (selIndex > -1 && Math.abs(diff) == 1) /* Scroll one position */
|
if (selIndex > -1 && Math.abs(diff) == 1) /* Scroll one position */
|
||||||
{
|
{
|
||||||
@@ -1372,14 +1381,14 @@ function ItemList(id) //{{{
|
|||||||
|
|
||||||
if (diff == 1) /* Scroll down */
|
if (diff == 1) /* Scroll down */
|
||||||
{
|
{
|
||||||
let item = completions[endIndex - 1];
|
let item = items[endIndex - 1];
|
||||||
let row = createRow(item, true);
|
let row = createRow(item, true);
|
||||||
tbody.removeChild(tbody.firstChild);
|
tbody.removeChild(tbody.firstChild);
|
||||||
tbody.appendChild(row);
|
tbody.appendChild(row);
|
||||||
}
|
}
|
||||||
else /* Scroll up */
|
else /* Scroll up */
|
||||||
{
|
{
|
||||||
let item = completions[offset];
|
let item = items[offset];
|
||||||
let row = createRow(item, true);
|
let row = createRow(item, true);
|
||||||
tbody.removeChild(tbody.lastChild);
|
tbody.removeChild(tbody.lastChild);
|
||||||
tbody.insertBefore(row, tbody.firstChild);
|
tbody.insertBefore(row, tbody.firstChild);
|
||||||
@@ -1394,7 +1403,7 @@ function ItemList(id) //{{{
|
|||||||
<div class="hl-Completions">
|
<div class="hl-Completions">
|
||||||
{
|
{
|
||||||
template.map(util.range(offset, endIndex), function (i)
|
template.map(util.range(offset, endIndex), function (i)
|
||||||
createRow(completions[i]))
|
createRow(items[i]))
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="hl-Completions">
|
<div class="hl-Completions">
|
||||||
@@ -1439,11 +1448,10 @@ function ItemList(id) //{{{
|
|||||||
visible: function () !container.collapsed,
|
visible: function () !container.collapsed,
|
||||||
|
|
||||||
// if @param selectedItem is given, show the list and select that item
|
// if @param selectedItem is given, show the list and select that item
|
||||||
setItems: function setItems(items, selectedItem)
|
setItems: function setItems(newItems, selectedItem)
|
||||||
{
|
{
|
||||||
startIndex = endIndex = selIndex = -1;
|
startIndex = endIndex = selIndex = -1;
|
||||||
completionObject = items || { start: 0, completions: [] };
|
items = newItems || [];
|
||||||
completions = completionObject.completions || []; // TODO: remove?
|
|
||||||
if (typeof selectedItem == "number")
|
if (typeof selectedItem == "number")
|
||||||
{
|
{
|
||||||
this.selectItem(selectedItem);
|
this.selectItem(selectedItem);
|
||||||
@@ -1457,7 +1465,7 @@ function ItemList(id) //{{{
|
|||||||
//if (container.collapsed) // fixme
|
//if (container.collapsed) // fixme
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
if (index == -1 || index == completions.length) // wrapped around
|
if (index == -1 || index == items.length) // wrapped around
|
||||||
{
|
{
|
||||||
if (selIndex >= 0)
|
if (selIndex >= 0)
|
||||||
getCompletion(selIndex).removeAttribute("selected");
|
getCompletion(selIndex).removeAttribute("selected");
|
||||||
@@ -1474,7 +1482,7 @@ function ItemList(id) //{{{
|
|||||||
else if (index <= startIndex + CONTEXT_LINES)
|
else if (index <= startIndex + CONTEXT_LINES)
|
||||||
newOffset = index - CONTEXT_LINES;
|
newOffset = index - CONTEXT_LINES;
|
||||||
|
|
||||||
newOffset = Math.min(newOffset, completions.length - maxItems);
|
newOffset = Math.min(newOffset, items.length - maxItems);
|
||||||
newOffset = Math.max(newOffset, 0);
|
newOffset = Math.max(newOffset, 0);
|
||||||
|
|
||||||
if (selIndex > -1)
|
if (selIndex > -1)
|
||||||
|
|||||||
Reference in New Issue
Block a user