diff --git a/NEWS b/NEWS index 122bb7c6..8857f046 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@
2007-08-*:
* version 0.5
+ * the command line keeps focus now, even when clicking outside of it
* vimperator.events.feedkeys("2zi") support for scripts
* Ctrl-U/Ctrl-D for scrolling the window up/down and the associated
'scroll' option
diff --git a/chrome/content/vimperator/events.js b/chrome/content/vimperator/events.js
index b8649a7e..90cee437 100644
--- a/chrome/content/vimperator/events.js
+++ b/chrome/content/vimperator/events.js
@@ -46,18 +46,19 @@ function Events() //{{{
tabcontainer.addEventListener("TabOpen", function(event) {
vimperator.statusline.updateTabCount();
vimperator.buffer.updateBufferList();
- vimperator.setMode(); // trick to reshow the mode in the command line
+ //vimperator.setMode(); // trick to reshow the mode in the command line
}, false);
tabcontainer.addEventListener("TabClose", function(event) {
vimperator.statusline.updateTabCount()
vimperator.buffer.updateBufferList();
- vimperator.setMode(); // trick to reshow the mode in the command line
+ //vimperator.setMode(); // trick to reshow the mode in the command line
}, false);
tabcontainer.addEventListener("TabSelect", function(event) {
vimperator.statusline.updateTabCount();
vimperator.buffer.updateBufferList();
- vimperator.setMode(); // trick to reshow the mode in the command line
+ //vimperator.setMode(); // trick to reshow the mode in the command line
vimperator.tabs.updateSelectionHistory();
+ setTimeout(vimperator.focusContent, 10); // just make sure, that no widget has focus
}, false);
// this adds an event which is is called on each page load, even if the
@@ -205,7 +206,9 @@ function Events() //{{{
this.destroy = function()
{
// BIG TODO: removeEventListeners() to avoid mem leaks
- window.dump("TODO: remove eventlisteners");
+ window.dump("TODO: remove all eventlisteners");
+
+ getBrowser().removeProgressListener(this.progressListener);
}
// This method pushes keys into the event queue from vimperator
@@ -337,16 +340,15 @@ function Events() //{{{
if (!vimperator.hasMode(vimperator.modes.ESCAPE_ONE_KEY))
{
vimperator.setMode(vimperator.modes.NORMAL);
- vimperator.echo("");
+ vimperator.commandline.clear();
vimperator.hints.disableHahMode();
- vimperator.focusContent();
vimperator.statusline.updateUrl();
+ vimperator.focusContent();
}
}
this.onKeyPress = function(event)
{
- //var key = event.toString()
var key = vimperator.events.toString(event);
if (!key)
return false;
@@ -562,7 +564,6 @@ function Events() //{{{
}
window.addEventListener("keypress", this.onKeyPress, true);
-
this.progressListener =
{
QueryInterface: function(aIID)
diff --git a/chrome/content/vimperator/ui.js b/chrome/content/vimperator/ui.js
index 2f59815b..a476283e 100644
--- a/chrome/content/vimperator/ui.js
+++ b/chrome/content/vimperator/ui.js
@@ -69,7 +69,7 @@ function CommandLine() //{{{
multiline_output_widget.collapsed = false;
setTimeout(function() { multiline_output_widget.collapsed = true; }, 0);
- // The widget used for multiline output
+ // The widget used for multiline iutput
var multiline_input_widget = document.getElementById("vimperator-multiline-input");
// we need to save the mode which were in before opening the command line
@@ -81,10 +81,6 @@ function CommandLine() //{{{
var old_mode = null; // when we leave the command prompt this mode is restored
var old_extended_mode = null;
- // an ugly hack that we allow the :echo(err) commands after hitting enter
- // and before the blur() event gets fired
- var echo_allowed = false;
-
// save the arguments for the inputMultiline method which are needed in the event handler
var multiline_regexp = null;
var multiline_callback = null;
@@ -100,7 +96,8 @@ function CommandLine() //{{{
}
function setMessageStyle()
{
- command_widget.inputField.setAttribute("style", "font-family: monospace; color:magenta; font-weight: bold");
+ prompt_widget.setAttribute("style", "font-family: monospace; color:magenta; font-weight: bold");
+ command_widget.inputField.setAttribute("style","font-family: monospace;");
}
function setErrorStyle()
{
@@ -142,14 +139,14 @@ function CommandLine() //{{{
multiline_input_widget.collapsed = true;
- vimperator.log(content_height);
+ // vimperator.log(content_height);
cmd = cmd.replace(/\n|\\n/g, "
") + "
Press ENTER or type command to continue";
multiline_output_widget.contentDocument.body.innerHTML = cmd;
// TODO: resize upon a window resize
var available_height = getBrowser().mPanelContainer.boxObject.height;
var content_height = multiline_output_widget.contentDocument.height;
- vimperator.log(content_height);
+ // vimperator.log(content_height);
var height = content_height < available_height ? content_height : available_height;
multiline_output_widget.style.height = height + "px";
@@ -157,10 +154,26 @@ function CommandLine() //{{{
setTimeout(function() {
multiline_output_widget.focus();
}, 10);
- vimperator.log(content_height);
+ //vimperator.log(content_height);
multiline_output_widget.contentWindow.scrollTo(0, content_height); // scroll to the end when 'nomore' is set
}
+ function autosizeMultilineInputWidget()
+ {
+ // XXX: faster/better method?
+
+ var lines = 0;
+ var str = multiline_input_widget.value;
+ for (var i = 0; i < str.length; i++)
+ {
+ if (str[i] == "\n")
+ lines++;
+ }
+ if (lines == 0)
+ lines = 1;
+ multiline_input_widget.setAttribute("rows", lines.toString());
+ }
+
function addToHistory(str)
{
if (str.length < 1)
@@ -199,9 +212,12 @@ function CommandLine() //{{{
history_index = UNINITIALIZED;
completion_index = UNINITIALIZED;
- // the command_widget.focus() method calls setPrompt() and setCommand()
- // this is done, because for follow-mouse window managers, we receive
- // blur and focus events once the user leaves the Firefox window with the mouse
+ // save the mode, because we need to restore it
+ [old_mode, old_extended_mode] = vimperator.getMode();
+ vimperator.setMode(vimperator.modes.COMMAND_LINE, cur_extended_mode, true);
+ setPrompt(cur_prompt);
+ setCommand(cur_command);
+
command_widget.focus();
};
@@ -209,7 +225,7 @@ function CommandLine() //{{{
this.echo = function(str, flags)
{
var focused = document.commandDispatcher.focusedElement;
- if (!echo_allowed && focused && focused == command_widget.inputField)
+ if (/*!echo_allowed && focused && */focused == command_widget.inputField)
return false;
if (typeof str != "string")
@@ -222,8 +238,6 @@ function CommandLine() //{{{
}
else
{
- multiline_output_widget.collapsed = true;
- multiline_input_widget.collapsed = true;
setPrompt("");
setCommand(str);
}
@@ -234,7 +248,7 @@ function CommandLine() //{{{
this.echoErr = function(str)
{
var focused = document.commandDispatcher.focusedElement;
- if (!echo_allowed && focused && focused == command_widget.inputField)
+ if (/*!echo_allowed && focused && */focused == command_widget.inputField)
return false;
setErrorStyle();
@@ -250,9 +264,9 @@ function CommandLine() //{{{
{
// TODO: unfinished, need to find out how/if we can block the execution of code
// to make this code synchronous or at least use a callback
- setPrompt("");
setMessageStyle();
- setCommand(str);
+ setPrompt(str);
+ setCommand("");
return "not implemented";
};
@@ -261,8 +275,8 @@ function CommandLine() //{{{
this.inputMultiline = function(until_regexp, callback_func)
{
// save the mode, because we need to restore it on blur()
-// [old_mode, old_extended_mode] = vimperator.getMode();
-// vimperator.setMode(vimperator.modes.COMMAND_LINE, vimperator.modes.READ_MULTLINE, true);
+ [old_mode, old_extended_mode] = vimperator.getMode();
+ vimperator.setMode(vimperator.modes.COMMAND_LINE, vimperator.modes.READ_MULTILINE, true);
// save the arguments, they are needed in the event handler onEvent
multiline_regexp = until_regexp;
@@ -270,15 +284,19 @@ function CommandLine() //{{{
multiline_input_widget.collapsed = false;
multiline_input_widget.value = "";
+ autosizeMultilineInputWidget();
+
setTimeout(function() {
multiline_input_widget.focus();
}, 10);
-
};
this.clear = function()
{
- setPrompt(" "); // looks faster than an empty string
+ multiline_input_widget.collapsed = true;
+ multiline_output_widget.collapsed = true;
+
+ setPrompt(" "); // looks faster than an empty string as most prompts are 1 char long
setCommand("");
setNormalStyle();
};
@@ -289,53 +307,18 @@ function CommandLine() //{{{
if (event.type == "blur")
{
- // when we do a command_widget.focus() we get a blur event immediately,
- // so check if the target is the actualy input field
- if (event.target == command_widget.inputField)
- {
- var silent = false;
- if (old_mode == vimperator.modes.NORMAL)
- silent = true;
- vimperator.setMode(old_mode || vimperator.modes.NORMAL, old_extended_mode || null, silent);
- cur_command = command;
-
- // don't add the echoed command to the history, on pressing , the
- // command is saved right into the kepress handler
- if (!echo_allowed)
- addToHistory(command);
-
- completionlist.hide();
- vimperator.statusline.updateProgress(""); // we may have a "match x of y" visible
- }
+ // prevent losing focus, there should be a better way, but it just didn't work otherwise
+ if (vimperator.hasMode(vimperator.modes.COMMAND_LINE))
+ setTimeout(function() { command_widget.inputField.focus(); }, 0);
}
else if (event.type == "focus")
{
- // if we manually click into the command line, don't open it
- if (event.target == command_widget.inputField && cur_extended_mode != null)
- {
- // save the mode, because we need to restore it on blur()
- [old_mode, old_extended_mode] = vimperator.getMode();
- vimperator.setMode(vimperator.modes.COMMAND_LINE, cur_extended_mode);
-
- setPrompt(cur_prompt);
- setCommand(cur_command);
- }
- else
- {
- //event.stopPropagation(); // XXX: doesnt seem to work
- //event.preventDefault(); // so we need to use the hack below --mst
-
- // NOTE: echo_allowed is a misleading name here, actually this flag is set
- // so that we don't save a history entry if the user clicks into the text field
- echo_allowed = true;
+ if (!cur_extended_mode)
event.target.blur();
- echo_allowed = false;
- return false;
- }
}
else if (event.type == "input")
{
- vimperator.triggerCallback("change", command);
+ vimperator.triggerCallback("change", cur_extended_mode, command);
}
else if (event.type == "keypress")
{
@@ -344,20 +327,24 @@ function CommandLine() //{{{
/* user pressed ENTER to carry out a command */
if (vimperator.events.isAcceptKey(key))
{
- echo_allowed = true;
+ var mode = cur_extended_mode; // save it here, as setMode() resets it
addToHistory(command);
- var res = vimperator.triggerCallback("submit", command);
+ vimperator.setMode(old_mode, old_extended_mode);
vimperator.focusContent();
- echo_allowed = false;
- return res;
+ completionlist.hide();
+ vimperator.statusline.updateProgress(""); // we may have a "match x of y" visible
+ return vimperator.triggerCallback("submit", mode, command);
}
/* user pressed ESCAPE to cancel this prompt */
else if (vimperator.events.isCancelKey(key))
{
- var res = vimperator.triggerCallback("cancel");
- // the command history item is saved in the blur() handler
+ var res = vimperator.triggerCallback("cancel", cur_extended_mode);
+ addToHistory(command);
+ vimperator.setMode(old_mode, old_extended_mode);
vimperator.focusContent();
+ completionlist.hide();
+ vimperator.statusline.updateProgress(""); // we may have a "match x of y" visible
this.clear();
return res;
}
@@ -422,12 +409,12 @@ function CommandLine() //{{{
completion_prefix = command.substring(0, command_widget.selectionStart);
completion_postfix = command.substring(command_widget.selectionStart);
- var res = vimperator.triggerCallback("complete", completion_prefix);
+ var res = vimperator.triggerCallback("complete", cur_extended_mode, completion_prefix);
if (res)
[completion_start_index, completions] = res;
// Sort the completion list
- if (vimperator.options["wildoptions"].match(/\bsort\b/))
+ if (vimperator.options["wildoptions"].search(/\bsort\b/))
{
completions.sort(function(a, b) {
if (a[0] < b[0])
@@ -545,24 +532,42 @@ function CommandLine() //{{{
this.onMultilineInputEvent = function(event)
{
- var key = vimperator.events.toString(event);
- if (vimperator.events.isAcceptKey(key))
+ if (event.type == "keypress")
{
- //var lines = multiline_input_widget.value.substr(0, multiline_input_widget.selectionStart).split(/\n/);
- var text = multiline_input_widget.value.substr(0, multiline_input_widget.selectionStart);
- if (text.match(multiline_regexp))
+ var key = vimperator.events.toString(event);
+ if (vimperator.events.isAcceptKey(key))
{
- text = text.replace(multiline_regexp, "");
- multiline_callback.call(this, text);
+ //var lines = multiline_input_widget.value.substr(0, multiline_input_widget.selectionStart).split(/\n/);
+ var text = multiline_input_widget.value.substr(0, multiline_input_widget.selectionStart);
+ if (text.match(multiline_regexp))
+ {
+ text = text.replace(multiline_regexp, "");
+ vimperator.setMode(old_mode, old_extended_mode);
+ multiline_input_widget.collapsed = true;
+ multiline_callback.call(this, text);
+ }
+ }
+ else if (vimperator.events.isCancelKey(key))
+ {
+ vimperator.setMode(old_mode, old_extended_mode);
multiline_input_widget.collapsed = true;
}
}
+ else if (event.type == "blur")
+ {
+ if (vimperator.hasMode(vimperator.modes.READ_MULTILINE))
+ setTimeout(function() { multiline_input_widget.inputField.focus(); }, 0);
+ }
+ else if (event.type == "input")
+ {
+ autosizeMultilineInputWidget();
+ }
}
this.onMultilineOutputEvent = function(event)
{
var key = vimperator.events.toString(event);
- if (vimperator.events.isAcceptKey(key))
+ if (vimperator.events.isAcceptKey(key) || vimperator.events.isCancelKey(key))
{
multiline_output_widget.collapsed = true;
vimperator.focusContent();
diff --git a/chrome/content/vimperator/vimperator.js b/chrome/content/vimperator/vimperator.js
index fc337fb9..36ebdf56 100644
--- a/chrome/content/vimperator/vimperator.js
+++ b/chrome/content/vimperator/vimperator.js
@@ -42,7 +42,7 @@ const vimperator = (function() //{{{
COMMAND_LINE: 1 << 4,
// extended modes
EX: 1 << 10,
- READ_MULTLINE: 1 << 11,
+ READ_MULTILINE: 1 << 11,
SEARCH_FORWARD: 1 << 12,
SEARCH_BACKWARD: 1 << 13,
ESCAPE_ONE_KEY: 1 << 14,
@@ -125,12 +125,13 @@ const vimperator = (function() //{{{
count: -1 // parsed count from the input buffer
},
- /** TODO: for now, these callbacks are mostly for the command line, move there?
- * @param type Can be:
+ /**
+ * @param type can be:
* "submit": when the user pressed enter in the command line
* "change"
* "cancel"
* "complete"
+ * TODO: "zoom": if the zoom value of the current buffer changed
*/
registerCallback: function(type, mode, func)
{
@@ -138,12 +139,12 @@ const vimperator = (function() //{{{
callbacks.push([type, mode, func]);
},
- triggerCallback: function(type, data)
+ triggerCallback: function(type, mode, data)
{
for (var i in callbacks)
{
var [thistype, thismode, thisfunc] = callbacks[i];
- if (vimperator.hasMode(thismode) && type == thistype)
+ if (mode == thismode && type == thistype)
return thisfunc.call(this, data);
}
return false;
diff --git a/chrome/content/vimperator/vimperator.xul b/chrome/content/vimperator/vimperator.xul
index f69a3516..2d6be2ad 100644
--- a/chrome/content/vimperator/vimperator.xul
+++ b/chrome/content/vimperator/vimperator.xul
@@ -105,12 +105,14 @@ the terms of any one of the MPL, the GPL or the LGPL.
onkeypress="vimperator.commandline.onMultilineOutputEvent(event)"/>
+ onkeypress="vimperator.commandline.onMultilineInputEvent(event);"
+ oninput="vimperator.commandline.onMultilineInputEvent(event);"
+ onblur="vimperator.commandline.onMultilineInputEvent(event);"/>
-
+