diff --git a/liberator/content/ui.js b/liberator/content/ui.js
index d1c62422..5a3dda32 100644
--- a/liberator/content/ui.js
+++ b/liberator/content/ui.js
@@ -134,9 +134,14 @@ function CommandLine() //{{{
this.editor.selection.focusNode.textContent = commandWidget.value;
// Reset the caret to one position after the completion.
- let range = this.editor.selection.getRangeAt(0);
- range.setStart(range.startContainer, this.prefix.length + completion.length);
- range.collapse(true);
+ this.caret = this.prefix.length + completion.length;
+ },
+
+ get caret() this.editor.selection.focusOffset,
+ set caret(offset)
+ {
+ commandWidget.selectionStart = offset;
+ commandWidget.selectionEnd = offset;
},
get start() this.context.allItems.start,
@@ -154,40 +159,72 @@ function CommandLine() //{{{
full: this.wildmode.checkHas(this.wildtype, "full")
}),
+ complete: function (show, tabPressed)
+ {
+ this.context.reset();
+ this.context.tabPressed = tabPressed;
+ liberator.triggerCallback("complete", currentExtendedMode, this.context);
+ this.reset(show, tabPressed);
+ },
+
preview: function preview()
{
- // This will only work with autocomplete.
- if (!options.get("wildoptions").has("auto") || !completions)
+ if (this.wildtype < 0 || this.suffix || !this.items.length)
return;
+ this.previewClear();
- if (this.type.longest && !this.suffix)
+ let substring = "";
+ switch (this.wildtype.replace(/.*:/, ""))
{
- let start = commandWidget.selectionStart;
- let substring = this.substring;
-
- // Don't show 1-character substrings unless we've just hit backspace
- if (substring.length < 2 && (!this.lastSubstring || this.lastSubstring.indexOf(substring) != 0))
- return;
- this.lastSubstring = substring;
- // Chop off the bits we already have.
- substring = substring.substr(completions.value.length);
-
- // highlight="Preview" won't work in the editor.
- let node = util.xmlToDom({substring},
- document);
- this.editor.insertNode(node, this.editor.rootElement, 1);
- commandWidget.selectionStart = commandWidget.selectionEnd = start;
+ case "":
+ substring = this.items[0].text;
+ break;
+ case "longest":
+ if (this.items.length > 1)
+ {
+ substring = this.substring;
+ break;
+ }
+ // Fallthrough
+ case "full":
+ let item = this.items[this.selected != null ? this.selected + 1 : 0];
+ if (item)
+ substring = item.text;
+ break;
}
+
+ // Don't show 1-character substrings unless we've just hit backspace
+ if (substring.length < 2 && (!this.lastSubstring || this.lastSubstring.indexOf(substring) != 0))
+ return;
+ this.lastSubstring = substring;
+
+ let value = this.completion;
+ if (util.compareIgnoreCase(value, substring.substr(0, value.length)))
+ return;
+ substring = substring.substr(value.length);
+ this.removeSubstring = substring;
+
+ // highlight="Preview" won't work in the editor.
+ let node = util.xmlToDom({substring},
+ document);
+ let start = this.caret;
+ this.editor.insertNode(node, this.editor.rootElement, 1);
+ this.caret = start;
},
previewClear: function previewClear()
{
- try
+ let node = this.editor.rootElement.firstChild;
+ if (node && node.nextSibling)
+ this.editor.deleteNode(node.nextSibling);
+ else if (this.removeSubstring)
{
- let node = this.editor.rootElement;
- this.editor.deleteNode(node.firstChild.nextSibling);
+ let str = this.removeSubstring;
+ let cmd = commandWidget.value;
+ if (cmd.substr(cmd.length - str.length) == str)
+ commandWidget.value = cmd.substr(0, cmd.length - str.length);
}
- catch (e) {}
+ delete this.removeSubstring;
},
reset: function reset(show)
@@ -203,7 +240,6 @@ function CommandLine() //{{{
{
this.itemList.reset();
this.select(this.RESET);
- this.itemList.show();
this.wildIndex = 0;
}
@@ -249,12 +285,7 @@ function CommandLine() //{{{
{
// Check if we need to run the completer.
if (this.context.waitingForTab || this.wildIndex == -1)
- {
- this.context.reset();
- this.context.tabPressed = true;
- liberator.triggerCallback("complete", currentExtendedMode, this.context);
- this.reset(true);
- }
+ this.complete(true, true);
if (this.items.length == 0)
{
@@ -292,6 +323,7 @@ function CommandLine() //{{{
completionList.show();
this.wildIndex = Math.max(0, Math.min(this.wildtypes.length - 1, this.wildIndex + 1));
+ this.preview();
statusTimer.tell();
}
@@ -311,9 +343,7 @@ function CommandLine() //{{{
var autocompleteTimer = new util.Timer(201, 300, function autocompleteTell(tabPressed) {
if (events.feedingKeys || !completions)
return;
- completions.context.reset();
- liberator.triggerCallback("complete", currentExtendedMode, completions.context);
- completions.reset(true);
+ completions.complete(true, false);
completions.itemList.show();
});
@@ -499,7 +529,7 @@ function CommandLine() //{{{
if (lines == 0)
lines = 1;
- multilineInputWidget.setAttribute("rows", lines.toString());
+ multilineInputWidget.setAttribute("rows", String(lines));
}
// used for the :echo[err] commands
@@ -1542,18 +1572,7 @@ function ItemList(id) //{{{
clear: function clear() { this.setItems(); doc.body.innerHTML = ""; },
hide: function hide() { container.collapsed = true; },
- show: function show()
- {
- /* FIXME: Should only happen with autocomplete,
- * possibly only with async entries.
- */
- if (container.collapsed)
- {
- minHeight = 0;
- setTimeout(function () { fill(null); }, 0);
- }
- container.collapsed = false;
- },
+ show: function show() { container.collapsed = false; },
visible: function visible() !container.collapsed,
reset: function ()
@@ -1566,6 +1585,8 @@ function ItemList(id) //{{{
// if @param selectedItem is given, show the list and select that item
setItems: function setItems(newItems, selectedItem)
{
+ if (container.collapsed)
+ minHeight = 0;
startIndex = endIndex = selIndex = -1;
items = newItems;
this.reset();