1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2026-03-17 09:33:31 +01:00

- fixed commandline focus/blur behavior

- could be buggy, so please report any bugs
- text selection is not possible anymore for :echo'ed things, should come later when holding shift
- cleared commandline on scroll events
This commit is contained in:
Martin Stubenschrott
2007-06-12 10:48:35 +00:00
parent 745035e1eb
commit 7af9664ac0
6 changed files with 120 additions and 42 deletions

View File

@@ -1,6 +1,7 @@
<pre> <pre>
2007-05-02: 2007-05-02:
* version ??? * version ???
* Command line is now cleared on most redraws like in vim
* The RSS feed button in the address bar works again * The RSS feed button in the address bar works again
* reload/stop buttons update enabled state again * reload/stop buttons update enabled state again
* added marks support (thanks Viktor Kojouharov) * added marks support (thanks Viktor Kojouharov)

4
TODO
View File

@@ -14,7 +14,6 @@ BUGS:
webpage, saving only the html works just fine.. webpage, saving only the html works just fine..
- <ESC> key closes :addons and other XUL windows - <ESC> key closes :addons and other XUL windows
FEATURES: FEATURES:
9 :map commands to keys 9 :map commands to keys
9 :command for new commands 9 :command for new commands
@@ -56,9 +55,6 @@ RANDOM IDEAS:
* 16:06:04 bartman| maxauthority: feature idea: what if :n and :N searched the * 16:06:04 bartman| maxauthority: feature idea: what if :n and :N searched the
page and if they found a unique <a href=...>.*next.*</a> or <a page and if they found a unique <a href=...>.*next.*</a> or <a
href=...>.*prev.*<a/> they would follow that link? href=...>.*prev.*<a/> they would follow that link?
* 20:12:26 skaar| so, I think get_history_completion effectively will put the oldest
history entry at the top of the completion list
20:12:48 skaar| since you're counting down in the for loop
* hide scrollbars: http://rafb.net/p/YHRhEe47.html (window.content.document.body.style.overflow = "hidden") * hide scrollbars: http://rafb.net/p/YHRhEe47.html (window.content.document.body.style.overflow = "hidden")
</pre> </pre>

View File

@@ -461,14 +461,11 @@ function Search()
logMessage("Search initialized"); logMessage("Search initialized");
} }
// @todo nicer way to register commands? // @TODO should be moved into commands.js
vimperator.commands.add(new Command(["noh[lsearch]"], vimperator.commands.add(new Command(["noh[lsearch]"],
clearSelection, clearSelection,
{ {
usage: ["noh[lsearch]"], short_help: "Clear the current selection"
short_help: "Clear the current selection",
help: null,
completer: null
} }
)); ));

View File

@@ -63,7 +63,7 @@ function CommandLine ()
var history_index = UNINITIALIZED; var history_index = UNINITIALIZED;
var history_start = ""; var history_start = "";
// for the example command "open sometext| othertext" (| is the cursor pos) // for the example command "open sometext| othertext" (| is the cursor pos):
var completion_start_index = 0; // will be 5 because we want to complete arguments for the :open command var completion_start_index = 0; // will be 5 because we want to complete arguments for the :open command
var completion_prefix = "" // will be: "open sometext" var completion_prefix = "" // will be: "open sometext"
var completion_postfix = ""; // will be: " othertext" var completion_postfix = ""; // will be: " othertext"
@@ -76,14 +76,32 @@ function CommandLine ()
// The command bar which contains the current command // The command bar which contains the current command
var command_widget = document.getElementById('vimperator-commandline-command'); var command_widget = document.getElementById('vimperator-commandline-command');
// load the history // we need to save the mode which were in before opening the command line
// this is then used if we focus the command line again without the "official"
// way of calling "open"
var cur_extended_mode = null; // the extended mode which we last openend the command line for
var cur_prompt = null;
var cur_command = null;
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;
// load the commandline history
var hist = get_pref("commandline_history", ""); var hist = get_pref("commandline_history", "");
history = hist.split("\n"); history = hist.split("\n");
// TODO: these styles should be moved to the .css file
function setNormalStyle() function setNormalStyle()
{ {
command_widget.inputField.setAttribute("style","font-family: monospace;"); command_widget.inputField.setAttribute("style","font-family: monospace;");
} }
function setMessageStyle()
{
command_widget.inputField.setAttribute("style", "font-family: monospace; color:magenta; font-weight: bold");
}
function setErrorStyle() function setErrorStyle()
{ {
command_widget.inputField.setAttribute("style", "font-family: monospace; color:white; background-color:red; font-weight: bold"); command_widget.inputField.setAttribute("style", "font-family: monospace; color:white; background-color:red; font-weight: bold");
@@ -118,13 +136,16 @@ function CommandLine ()
function addToHistory(str) function addToHistory(str)
{ {
if(str.length < 1)
return;
// first remove all old history elements which have this string // first remove all old history elements which have this string
history = history.filter(function(elem) { history = history.filter(function(elem) {
return elem != str; return elem != str;
}); });
// add string to the command line history // add string to the command line history
if (str.length >= 1 && history.push(str) > HISTORY_SIZE) if (history.push(str) > HISTORY_SIZE) //remove the first 10% of the history
history.shift(); history = history.slice(HISTORY_SIZE / 10);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -137,47 +158,64 @@ function CommandLine ()
}; };
/** /**
* All arguments can be ommited and will be defaulted to "" * All arguments can be ommited and will be defaulted to "" or null
*/ */
this.open = function(prompt, cmd, minor_mode) this.open = function(prompt, cmd, ext_mode)
{ {
if (!prompt) // save the current prompts, we need it later if the command widget
prompt = ""; // receives focus without calling the this.open() method
if (!cmd) cur_prompt = prompt || "";
cmd = ""; cur_command = cmd || "";
//if (minor_mode) cur_extended_mode = ext_mode || null;
vimperator.setMode(vimperator.modes.COMMAND_LINE, minor_mode);
setNormalStyle(); setNormalStyle();
setPrompt(prompt);
setCommand(cmd);
history_index = UNINITIALIZED; history_index = UNINITIALIZED;
completion_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
command_widget.focus(); command_widget.focus();
}; };
this.echo = function(str) this.echo = function(str)
{ {
var focused = document.commandDispatcher.focusedElement; var focused = document.commandDispatcher.focusedElement;
if (focused && focused == command_widget.inputField) if (!echo_allowed && focused && focused == command_widget.inputField)
return; return false;
setNormalStyle(); setNormalStyle();
setPrompt(""); setPrompt("");
setCommand(str); setCommand(str);
cur_extended_mode = null;
return true;
}; };
this.echoErr = function(str) this.echoErr = function(str)
{ {
var focused = document.commandDispatcher.focusedElement; var focused = document.commandDispatcher.focusedElement;
if (focused && focused == command_widget.inputField) if (!echo_allowed && focused && focused == command_widget.inputField)
return; return false;
setErrorStyle(); setErrorStyle();
setPrompt(""); setPrompt("");
setCommand(str); setCommand(str);
cur_extended_mode = null;
return true;
}; };
// this will prompt the user for a string
// vimperator.commandline.input("(s)ave or (o)pen the file?")
this.input = function(str)
{
// TODO: unfinished, need to find out how/if we can block the execution of code
// to make this code synchronous
setPrompt("");
setMessageStyle();
setCommand(str);
return "not implemented";
}
this.clear = function() this.clear = function()
{ {
setPrompt(" "); // looks faster than an empty string setPrompt(" "); // looks faster than an empty string
@@ -188,20 +226,55 @@ function CommandLine ()
this.onEvent = function(event) this.onEvent = function(event)
{ {
//var end = false;
var command = this.getCommand(); var command = this.getCommand();
if(event.type == "blur") if(event.type == "blur")
{ {
logMessage("blur");
// when we do a command_widget.focus() we get a blur event immediately, // when we do a command_widget.focus() we get a blur event immediately,
// so check if the target is the actualy input field // so check if the target is the actualy input field
if (event.target == command_widget.inputField) if (event.target == command_widget.inputField)
{ {
addToHistory(command); 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 <cr>, the
// command is saved right into the kepress handler
if(!echo_allowed)
addToHistory(command);
completionlist.hide(); completionlist.hide();
vimperator.statusline.updateProgress(""); // we may have a "match x of y" visible vimperator.statusline.updateProgress(""); // we may have a "match x of y" visible
} }
} }
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
// 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;
event.target.blur();
echo_allowed = false;
return false;
}
}
else if(event.type == "input") else if(event.type == "input")
{ {
vimperator.triggerCallback("change", command); vimperator.triggerCallback("change", command);
@@ -213,6 +286,7 @@ function CommandLine ()
if (key == "<Return>" || key == "<C-j>" || key == "<C-m>") if (key == "<Return>" || key == "<C-j>" || key == "<C-m>")
{ {
// FIXME: move to execute() in commands.js // FIXME: move to execute() in commands.js
// var end = false;
// try { // try {
// [prev_match, heredoc, end] = multiliner(command, prev_match, heredoc); // [prev_match, heredoc, end] = multiliner(command, prev_match, heredoc);
// } catch(e) { // } catch(e) {
@@ -225,19 +299,20 @@ function CommandLine ()
// if (!end) // if (!end)
// command_line.value = ""; // command_line.value = "";
// NOTE: the command is saved to the history in the blur() handler echo_allowed = true;
vimperator.focusContent(); addToHistory(command);
var res = vimperator.triggerCallback("submit", command); var res = vimperator.triggerCallback("submit", command);
vimperator.setMode(vimperator.modes.NORMAL, null, true); vimperator.focusContent();
echo_allowed = false;
return res; return res;
} }
/* user pressed ESCAPE to cancel this prompt */ /* user pressed ESCAPE to cancel this prompt */
else if (key == "<Esc>" || key == "<C-[>" || key == "<C-c>") else if (key == "<Esc>" || key == "<C-[>" || key == "<C-c>")
{ {
var res = vimperator.triggerCallback("cancel"); var res = vimperator.triggerCallback("cancel");
addToHistory(command); // the command history item is saved in the blur() handler
this.clear();
vimperator.focusContent(); vimperator.focusContent();
this.clear();
return res; return res;
} }
@@ -423,7 +498,7 @@ function CommandLine ()
} }
// it would be better if we had a destructor in javascript ... // it would be better if we had a destructor in javascript ...
this.saveHistory = function() this.destroy = function()
{ {
set_pref("commandline_history", history.join("\n")); set_pref("commandline_history", history.join("\n"));
} }

View File

@@ -64,20 +64,17 @@ function init()
Vimperator.prototype.mappings = new Mappings; Vimperator.prototype.mappings = new Mappings;
Vimperator.prototype.marks = new Marks; Vimperator.prototype.marks = new Marks;
// XXX: move into Vimperator() ?
vimperator.input = { vimperator.input = {
buffer: "", // partial command storage buffer: "", // partial command storage
pendingMap: null, // pending map storage pendingMap: null, // pending map storage
count: -1, // parsed count from the input buffer count: -1, // parsed count from the input buffer
}; };
// XXX: move elsewhere // XXX: move elsewhere
vimperator.registerCallback("submit", vimperator.modes.EX, function(command) { /*vimperator.*/execute(command); } ); vimperator.registerCallback("submit", vimperator.modes.EX, function(command) { /*vimperator.*/execute(command); } );
vimperator.registerCallback("complete", vimperator.modes.EX, function(str) { return exTabCompletion(str); } ); vimperator.registerCallback("complete", vimperator.modes.EX, function(str) { return exTabCompletion(str); } );
// this function adds all our required listeners to react on events
// also stuff like window.onScroll is handled there.
//addEventListeners();
//vimperator.events();
set_showtabline(get_pref("showtabline")); set_showtabline(get_pref("showtabline"));
set_guioptions(get_pref("guioptions")); set_guioptions(get_pref("guioptions"));
set_titlestring(); set_titlestring();
@@ -121,7 +118,7 @@ function init()
function unload() function unload()
{ {
/*** save our preferences ***/ /*** save our preferences ***/
vimperator.commandline.saveHistory(); vimperator.commandline.destroy();
vimperator.events.destroy(); vimperator.events.destroy();
@@ -233,6 +230,12 @@ function Vimperator() //{{{1
this.echo = this.commandline.echo; this.echo = this.commandline.echo;
this.echoerr = this.commandline.echoErr; this.echoerr = this.commandline.echoErr;
this.getMode = function()
{
return [mode, extended_mode];
}
// set current mode // set current mode
// use "null" if you only want to set one of those modes // use "null" if you only want to set one of those modes
this.setMode = function(main, extended, silent) this.setMode = function(main, extended, silent)
@@ -314,14 +317,17 @@ function Events() //{{{1
tabcontainer.addEventListener("TabOpen", function(event) { tabcontainer.addEventListener("TabOpen", function(event) {
vimperator.statusline.updateTabCount(); vimperator.statusline.updateTabCount();
updateBufferList(); updateBufferList();
vimperator.setMode(); // trick to reshow the mode in the command line
}, false); }, false);
tabcontainer.addEventListener("TabClose", function(event) { tabcontainer.addEventListener("TabClose", function(event) {
vimperator.statusline.updateTabCount() vimperator.statusline.updateTabCount()
updateBufferList(); updateBufferList();
vimperator.setMode(); // trick to reshow the mode in the command line
}, false); }, false);
tabcontainer.addEventListener("TabSelect", function(event) { tabcontainer.addEventListener("TabSelect", function(event) {
vimperator.statusline.updateTabCount(); vimperator.statusline.updateTabCount();
updateBufferList(); updateBufferList();
vimperator.setMode(); // trick to reshow the mode in the command line
}, false); }, false);
// this adds an event which is is called on each page load, even if the // this adds an event which is is called on each page load, even if the
@@ -332,6 +338,7 @@ function Events() //{{{1
window.onscroll = function (event) window.onscroll = function (event)
{ {
vimperator.statusline.updateBufferPosition(); vimperator.statusline.updateBufferPosition();
vimperator.setMode(); // trick to reshow the mode in the command line
}; };
window.document.addEventListener("DOMTitleChanged", function(event) window.document.addEventListener("DOMTitleChanged", function(event)

View File

@@ -97,7 +97,9 @@ the terms of any one of the MPL, the GPL or the LGPL.
<textbox class="plain" id="vimperator-commandline-command" flex="1" hidden="false" type="timed" timeout="100" <textbox class="plain" id="vimperator-commandline-command" flex="1" hidden="false" type="timed" timeout="100"
onkeypress="vimperator.commandline.onEvent(event);" onkeypress="vimperator.commandline.onEvent(event);"
oninput="vimperator.commandline.onEvent(event);" oninput="vimperator.commandline.onEvent(event);"
onblur="vimperator.commandline.onEvent(event);" style="font-family: monospace"/> onfocus="vimperator.commandline.onEvent(event);"
onblur="vimperator.commandline.onEvent(event);"
style="font-family: monospace; -moz-user-focus:ignore;"/>
</hbox> </hbox>
</vbox> </vbox>
</toolbar> </toolbar>