mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-23 00:27:57 +01:00
* Initial code for "waiting" macros. Still buggy/incomplete, but commiting, before merging other patches becomes even more tedious.
* Also a new attempt that pages don't have input focus after load, probably buggy as well
This commit is contained in:
@@ -228,7 +228,7 @@ vimperator.Buffer = function () //{{{
|
|||||||
if (typeof window.content.document.pageIsFullyLoaded != "undefined")
|
if (typeof window.content.document.pageIsFullyLoaded != "undefined")
|
||||||
return window.content.document.pageIsFullyLoaded;
|
return window.content.document.pageIsFullyLoaded;
|
||||||
else
|
else
|
||||||
return 1; // in doubt return "loaded"
|
return 0; // in doubt return "loading"
|
||||||
},
|
},
|
||||||
set loaded(value)
|
set loaded(value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -388,7 +388,7 @@ vimperator.Editor = function () //{{{
|
|||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// blink the textbox after returning
|
// blink the textbox after returning - TODO: could use setInterval
|
||||||
var timeout = 100;
|
var timeout = 100;
|
||||||
textBox.style.backgroundColor = tmpBg;
|
textBox.style.backgroundColor = tmpBg;
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
|
|||||||
@@ -32,10 +32,12 @@ vimperator.Events = function () //{{{
|
|||||||
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////{{{
|
/////////////////////////////////////////////////////////////////////////////{{{
|
||||||
|
|
||||||
// this handler is for middle click only in the content
|
var inputBufferLength = 0; // counts the number of keys in v.input.buffer (can be different from v.input.buffer.length)
|
||||||
//window.addEventListener("mousedown", onVimperatorKeypress, true);
|
var skipMap = false; // while feeding the keys (stored in v.input.buffer | no map found) - ignore mappings
|
||||||
//content.mPanelContainer.addEventListener("mousedown", onVimperatorKeypress, true);
|
|
||||||
//document.getElementById("content").onclick = function (event) { alert("foo"); };
|
var macros = {};
|
||||||
|
var currentMacro = "";
|
||||||
|
var lastMacro = "";
|
||||||
|
|
||||||
// any tab related events
|
// any tab related events
|
||||||
var tabcontainer = getBrowser().mTabContainer;
|
var tabcontainer = getBrowser().mTabContainer;
|
||||||
@@ -79,6 +81,12 @@ vimperator.Events = function () //{{{
|
|||||||
vimperator.modes.show();
|
vimperator.modes.show();
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
|
// getBrowser().addEventListener("submit", function (event)
|
||||||
|
// {
|
||||||
|
// // reset buffer loading state as early as possible, important for macros
|
||||||
|
// dump("submit\n");
|
||||||
|
// vimperator.buffer.loaded = 0;
|
||||||
|
// }, null);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////
|
||||||
// track if a popup is open or the menubar is active
|
// track if a popup is open or the menubar is active
|
||||||
@@ -228,30 +236,82 @@ vimperator.Events = function () //{{{
|
|||||||
var title = vimperator.buffer.title;
|
var title = vimperator.buffer.title;
|
||||||
vimperator.history.add(url, title);
|
vimperator.history.add(url, title);
|
||||||
|
|
||||||
|
// mark the buffer as loaded, we can't use vimperator.buffer.loaded
|
||||||
|
// since that always refers to the current buffer, while doc can be
|
||||||
|
// any buffer, even in a background tab
|
||||||
|
doc.pageIsFullyLoaded = 1;
|
||||||
|
|
||||||
// code which is only relevant if the page load is the current tab goes here:
|
// code which is only relevant if the page load is the current tab goes here:
|
||||||
//if (doc == getBrowser().selectedBrowser.contentDocument)
|
if (doc == getBrowser().selectedBrowser.contentDocument)
|
||||||
//{
|
{
|
||||||
// // TODO: remember the last focused input widget, so we can go there with 'gi'
|
|
||||||
// // FIXME: this currently causes window map events which is _very_ annoying
|
// // FIXME: this currently causes window map events which is _very_ annoying
|
||||||
// // we want to stay in command mode after a page has loaded
|
// // we want to stay in command mode after a page has loaded
|
||||||
// //setTimeout(vimperator.focusContent, 10);
|
setTimeout(function () {
|
||||||
// // setTimeout(function () {
|
var focused = document.commandDispatcher.focusedElement;
|
||||||
// // if (doc.commandDispatcher.focusedElement)
|
if (focused && focused.value.length == 0)
|
||||||
// // doc.commandDispatcher.focusedElement.blur();
|
focused.blur();
|
||||||
// // alert(doc.commandDispatcher.focusedElement);
|
}, 100);
|
||||||
// // }, 1000);
|
}
|
||||||
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var inputBufferLength = 0; // counts the keys in v.input.buffer
|
// return true when load successful, or false otherwise
|
||||||
var skipMap = false; // while feeding the keys (stored in v.input.buffer | no map found) - ignore mappings
|
function waitForPageLoaded()
|
||||||
|
{
|
||||||
|
dump("start waiting in loaded state: " + vimperator.buffer.loaded + "\n");
|
||||||
|
var mainThread = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager).mainThread;
|
||||||
|
while (mainThread.hasPendingEvents()) // clear queue
|
||||||
|
mainThread.processNextEvent(true);
|
||||||
|
|
||||||
|
// if (vimperator.buffer.loaded == 1)
|
||||||
|
// return true;
|
||||||
|
|
||||||
|
var ms = 10000; // maximum time to wait - TODO: add option
|
||||||
|
var then = new Date().getTime();
|
||||||
|
for (var now = then; now - then < ms; now = new Date().getTime())
|
||||||
|
{
|
||||||
|
mainThread.processNextEvent(true);
|
||||||
|
dump("waited: " + (now - then) + " ms\n");
|
||||||
|
|
||||||
|
if (vimperator.buffer.loaded > 0)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
vimperator.echo("Waiting for page to load...");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: allow macros to be continued when page does not fully load with an option
|
||||||
|
var ret = (vimperator.buffer.loaded == 1);
|
||||||
|
if (!ret)
|
||||||
|
vimperator.echoerr("Page did not load completely in " + ms + " milliseconds. Macro stopped.");
|
||||||
|
dump("done waiting: " + ret + "\n");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load all macros inside ~/.vimperator/macros/
|
||||||
|
// setTimeout needed since vimperator.io. is loaded after vimperator.events.
|
||||||
|
setTimeout (function() {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var files = vimperator.io.readDirectory(vimperator.io.getSpecialDirectory("macros"));
|
||||||
|
for (var i = 0; i < files.length; i++)
|
||||||
|
{
|
||||||
|
var file = files[i];
|
||||||
|
if (!file.exists() || file.isDirectory() || !file.isReadable())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var name = file.leafName.replace(/\.vimp$/i, "");
|
||||||
|
macros[name] = vimperator.io.readFile(file).split(/\n/)[0];
|
||||||
|
vimperator.log("Macro " + name + " added: " + macros[name], 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
vimperator.log("macro directory not found or error reading macro file");
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
|
||||||
var macros = {};
|
|
||||||
var isRecording = false;
|
|
||||||
var currentMacro;
|
|
||||||
var lastMacro = "";
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////}}}
|
/////////////////////////////////////////////////////////////////////////////}}}
|
||||||
////////////////////// PUBLIC SECTION //////////////////////////////////////////
|
////////////////////// PUBLIC SECTION //////////////////////////////////////////
|
||||||
@@ -261,57 +321,6 @@ vimperator.Events = function () //{{{
|
|||||||
|
|
||||||
wantsModeReset: true, // used in onFocusChange since Firefox is so buggy here
|
wantsModeReset: true, // used in onFocusChange since Firefox is so buggy here
|
||||||
|
|
||||||
startRecording: function (macro)
|
|
||||||
{
|
|
||||||
if (!/[a-zA-Z0-9]/.test(macro))
|
|
||||||
{
|
|
||||||
vimperator.echoerr("Register must be [a-zA-z0-9]");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
vimperator.modes.add(vimperator.modes.RECORDING); //TODO: does not work/show yet
|
|
||||||
|
|
||||||
if (/[A-Z]/.test(macro)) // uppercase (append)
|
|
||||||
{
|
|
||||||
currentMacro = macro.toLowerCase();
|
|
||||||
if (!macros[currentMacro])
|
|
||||||
macros[currentMacro] = ""; // initialise if it does not yet exist
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
currentMacro = macro;
|
|
||||||
macros[currentMacro] = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
vimperator.echo("recording into register " + currentMacro + "...");
|
|
||||||
isRecording = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
playMacro: function (macro)
|
|
||||||
{
|
|
||||||
if (!/[a-zA-Z0-9@]/.test(macro))
|
|
||||||
{
|
|
||||||
vimperator.echoerr("Register must be [a-z0-9]");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (macro == "@") // use lastMacro if it's set
|
|
||||||
{
|
|
||||||
if (!lastMacro)
|
|
||||||
{
|
|
||||||
vimperator.echoerr("E748: No previously used Register");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lastMacro = macro.toLowerCase(); // XXX: sets last playerd macro, even if it does not yet exist
|
|
||||||
}
|
|
||||||
|
|
||||||
if (macros[lastMacro])
|
|
||||||
vimperator.events.feedkeys(macros[lastMacro], true); // true -> noremap
|
|
||||||
else
|
|
||||||
vimperator.echoerr("Register '" + lastMacro + " not set");
|
|
||||||
},
|
|
||||||
|
|
||||||
destroy: function ()
|
destroy: function ()
|
||||||
{
|
{
|
||||||
// removeEventListeners() to avoid mem leaks
|
// removeEventListeners() to avoid mem leaks
|
||||||
@@ -328,6 +337,61 @@ vimperator.Events = function () //{{{
|
|||||||
window.removeEventListener("keydown", this.onKeyDown, true);
|
window.removeEventListener("keydown", this.onKeyDown, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
startRecording: function (macro)
|
||||||
|
{
|
||||||
|
if (!/[a-zA-Z0-9]/.test(macro))
|
||||||
|
{
|
||||||
|
vimperator.echoerr("Register must be [a-zA-z0-9]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vimperator.modes.isRecording = true;
|
||||||
|
|
||||||
|
if (/[A-Z]/.test(macro)) // uppercase (append)
|
||||||
|
{
|
||||||
|
currentMacro = macro.toLowerCase();
|
||||||
|
if (!macros[currentMacro])
|
||||||
|
macros[currentMacro] = ""; // initialize if it does not yet exist
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentMacro = macro;
|
||||||
|
macros[currentMacro] = "";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
playMacro: function (macro)
|
||||||
|
{
|
||||||
|
if (!/[a-zA-Z0-9@]/.test(macro))
|
||||||
|
{
|
||||||
|
vimperator.echoerr("Register must be [a-z0-9]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (macro == "@") // use lastMacro if it's set
|
||||||
|
{
|
||||||
|
if (!lastMacro)
|
||||||
|
{
|
||||||
|
vimperator.echoerr("E748: No previously used register");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastMacro = macro.toLowerCase(); // XXX: sets last playerd macro, even if it does not yet exist
|
||||||
|
}
|
||||||
|
|
||||||
|
if (macros[lastMacro])
|
||||||
|
{
|
||||||
|
vimperator.modes.isReplaying = true;
|
||||||
|
BrowserStop(); // make sure the page is stopped before starting to play the macro
|
||||||
|
vimperator.buffer.loaded = 1; // even if not a full page load, assume it did load correctly before starting the macro
|
||||||
|
vimperator.events.feedkeys(macros[lastMacro], true); // true -> noremap
|
||||||
|
vimperator.modes.isReplaying = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vimperator.echoerr("Register " + lastMacro + " not set");
|
||||||
|
},
|
||||||
|
|
||||||
// This method pushes keys into the event queue from vimperator
|
// This method pushes keys into the event queue from vimperator
|
||||||
// it is similar to vim's feedkeys() method, but cannot cope with
|
// it is similar to vim's feedkeys() method, but cannot cope with
|
||||||
// 2 partially feeded strings, you have to feed one parsable string
|
// 2 partially feeded strings, you have to feed one parsable string
|
||||||
@@ -390,7 +454,12 @@ vimperator.Events = function () //{{{
|
|||||||
var evt = doc.createEvent("KeyEvents");
|
var evt = doc.createEvent("KeyEvents");
|
||||||
evt.initKeyEvent("keypress", true, true, view, ctrl, alt, shift, meta, keyCode, charCode);
|
evt.initKeyEvent("keypress", true, true, view, ctrl, alt, shift, meta, keyCode, charCode);
|
||||||
evt.noremap = noremap;
|
evt.noremap = noremap;
|
||||||
elem.dispatchEvent(evt);
|
if (elem.dispatchEvent(evt)) // return true in onEvent to stop feeding keys
|
||||||
|
{
|
||||||
|
dump("help in mode: " + vimperator.mode + " - " + vimperator.events.toString(evt) + "\n");
|
||||||
|
vimperator.beep();
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -527,12 +596,17 @@ vimperator.Events = function () //{{{
|
|||||||
vimperator.mode == vimperator.modes.TEXTAREA ||
|
vimperator.mode == vimperator.modes.TEXTAREA ||
|
||||||
vimperator.mode == vimperator.modes.VISUAL)
|
vimperator.mode == vimperator.modes.VISUAL)
|
||||||
{
|
{
|
||||||
this.wantsModeReset = true;
|
// FIXME: currently this hack is disabled to make macros work
|
||||||
setTimeout(function ()
|
// this.wantsModeReset = true;
|
||||||
{
|
// setTimeout(function ()
|
||||||
if (vimperator.events.wantsModeReset)
|
// {
|
||||||
vimperator.modes.reset();
|
// dump("cur: " + vimperator.mode + "\n");
|
||||||
}, 10);
|
// if (vimperator.events.wantsModeReset)
|
||||||
|
// {
|
||||||
|
// vimperator.events.wantsModeReset = false;
|
||||||
|
vimperator.modes.reset();
|
||||||
|
// }
|
||||||
|
// }, 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -628,19 +702,20 @@ vimperator.Events = function () //{{{
|
|||||||
var key = vimperator.events.toString(event);
|
var key = vimperator.events.toString(event);
|
||||||
if (!key)
|
if (!key)
|
||||||
return true;
|
return true;
|
||||||
|
dump(key + " in mode: " + vimperator.mode + "\n");
|
||||||
|
|
||||||
if (isRecording)
|
if (vimperator.modes.isRecording)
|
||||||
{
|
{
|
||||||
if (key == "q") // TODO: should not be hardcoded
|
if (key == "q") // TODO: should not be hardcoded
|
||||||
{
|
{
|
||||||
isRecording = false;
|
vimperator.modes.isRecording = false;
|
||||||
vimperator.modes.remove(vimperator.modes.RECORDING);
|
vimperator.log("Recorded " + currentMacro + ": " + macros[currentMacro], 8);
|
||||||
vimperator.echo("recorded " + currentMacro + " : " + macros[currentMacro]); // DEBUG:
|
event.preventDefault(); // XXX: or howto stop that key being processed?
|
||||||
event.preventDefault(); // XXX: or howto stop that key beeing processed?
|
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (!vimperator.mappings.hasMap(vimperator.mode, vimperator.input.buffer + key))
|
else if (!(vimperator.modes.extended & vimperator.modes.INACTIVE_HINT) &&
|
||||||
|
!vimperator.mappings.hasMap(vimperator.mode, vimperator.input.buffer + key))
|
||||||
{
|
{
|
||||||
macros[currentMacro] += key;
|
macros[currentMacro] += key;
|
||||||
}
|
}
|
||||||
@@ -648,19 +723,19 @@ vimperator.Events = function () //{{{
|
|||||||
|
|
||||||
var stop = true; // set to false if we should NOT consume this event but let also firefox handle it
|
var stop = true; // set to false if we should NOT consume this event but let also firefox handle it
|
||||||
|
|
||||||
var win = document.commandDispatcher.focusedWindow;
|
var win = document.commandDispatcher.focusedWindow;
|
||||||
if (win && win.document.designMode == "on")
|
if (win && win.document.designMode == "on")
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
// menus have their own command handlers
|
// menus have their own command handlers
|
||||||
if (vimperator.modes.extended & vimperator.modes.MENU)
|
if (vimperator.modes.extended & vimperator.modes.MENU)
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
// handle Escape-one-key mode (Ctrl-v)
|
// handle Escape-one-key mode (Ctrl-v)
|
||||||
if (vimperator.modes.passNextKey && !vimperator.modes.passAllKeys)
|
if (vimperator.modes.passNextKey && !vimperator.modes.passAllKeys)
|
||||||
{
|
{
|
||||||
vimperator.modes.passNextKey = false;
|
vimperator.modes.passNextKey = false;
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
// handle Escape-all-keys mode (Ctrl-q)
|
// handle Escape-all-keys mode (Ctrl-q)
|
||||||
if (vimperator.modes.passAllKeys)
|
if (vimperator.modes.passAllKeys)
|
||||||
@@ -670,7 +745,7 @@ vimperator.Events = function () //{{{
|
|||||||
else if (key == "<Esc>" || key == "<C-[>" || key == "<C-v>")
|
else if (key == "<Esc>" || key == "<C-[>" || key == "<C-v>")
|
||||||
; // let flow continue to handle these keys to cancel escape-all-keys mode
|
; // let flow continue to handle these keys to cancel escape-all-keys mode
|
||||||
else
|
else
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: proper way is to have a better onFocus handler which also handles events for the XUL
|
// FIXME: proper way is to have a better onFocus handler which also handles events for the XUL
|
||||||
@@ -678,20 +753,38 @@ vimperator.Events = function () //{{{
|
|||||||
!vimperator.mode == vimperator.modes.INSERT &&
|
!vimperator.mode == vimperator.modes.INSERT &&
|
||||||
!vimperator.mode == vimperator.modes.COMMAND_LINE &&
|
!vimperator.mode == vimperator.modes.COMMAND_LINE &&
|
||||||
isFormElemFocused()) // non insert mode, but e.g. the location bar has focus
|
isFormElemFocused()) // non insert mode, but e.g. the location bar has focus
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
|
// just forward event, without checking any mappings
|
||||||
if (vimperator.mode == vimperator.modes.COMMAND_LINE &&
|
if (vimperator.mode == vimperator.modes.COMMAND_LINE &&
|
||||||
(vimperator.modes.extended & vimperator.modes.OUTPUT_MULTILINE))
|
vimperator.modes.extended & vimperator.modes.OUTPUT_MULTILINE)
|
||||||
{
|
{
|
||||||
vimperator.commandline.onMultilineOutputEvent(event);
|
vimperator.commandline.onMultilineOutputEvent(event);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: ugly hack for now pass certain keys to firefox as they are without beeping
|
// XXX: ugly hack for now pass certain keys to firefox as they are without beeping
|
||||||
// also fixes key navigation in combo boxes, etc.
|
// also fixes key navigation in combo boxes, submitting forms, etc.
|
||||||
if (vimperator.mode == vimperator.modes.NORMAL)
|
// FIXME: breaks iabbr for now --mst
|
||||||
|
if (vimperator.mode == vimperator.modes.NORMAL || vimperator.mode == vimperator.modes.INSERT)
|
||||||
{
|
{
|
||||||
if (key == "<Tab>" || key == "<S-Tab>" || key == "<Return>" || key == "<Space>" || key == "<Up>" || key == "<Down>")
|
if (key == "<Return>")
|
||||||
|
{
|
||||||
|
if (vimperator.modes.isReplaying)
|
||||||
|
{
|
||||||
|
// TODO: how to really submit the correct form?
|
||||||
|
vimperator.modes.reset();
|
||||||
|
content.document.forms[0].submit();
|
||||||
|
waitForPageLoaded();
|
||||||
|
dump("before return\n");
|
||||||
|
event.stopPropagation();
|
||||||
|
event.preventDefault();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (key == "<Space>" || key == "<Up>" || key == "<Down>")
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,7 +818,7 @@ vimperator.Events = function () //{{{
|
|||||||
vimperator.hints.onEvent(event);
|
vimperator.hints.onEvent(event);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,7 +849,12 @@ vimperator.Events = function () //{{{
|
|||||||
var tmp = vimperator.input.pendingArgMap; // must be set to null before .execute; if not
|
var tmp = vimperator.input.pendingArgMap; // must be set to null before .execute; if not
|
||||||
vimperator.input.pendingArgMap = null; // v.inputpendingArgMap is still 'true' also for new feeded keys
|
vimperator.input.pendingArgMap = null; // v.inputpendingArgMap is still 'true' also for new feeded keys
|
||||||
if (key != "<Esc>" && key != "<C-[>")
|
if (key != "<Esc>" && key != "<C-[>")
|
||||||
|
{
|
||||||
|
if (vimperator.modes.isReplaying && !waitForPageLoaded())
|
||||||
|
return true;
|
||||||
|
|
||||||
tmp.execute(null, vimperator.input.count, key);
|
tmp.execute(null, vimperator.input.count, key);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (map && !skipMap)
|
else if (map && !skipMap)
|
||||||
@@ -791,7 +889,11 @@ vimperator.Events = function () //{{{
|
|||||||
{
|
{
|
||||||
vimperator.input.buffer = "";
|
vimperator.input.buffer = "";
|
||||||
inputBufferLength = 0;
|
inputBufferLength = 0;
|
||||||
var ret = map.execute(null, vimperator.input.count);
|
|
||||||
|
if (vimperator.modes.isReplaying && !waitForPageLoaded())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var ret = map.execute(null, vimperator.input.count);
|
||||||
if (map.flags & vimperator.Mappings.flags.ALLOW_EVENT_ROUTING && ret)
|
if (map.flags & vimperator.Mappings.flags.ALLOW_EVENT_ROUTING && ret)
|
||||||
stop = false;
|
stop = false;
|
||||||
}
|
}
|
||||||
@@ -801,7 +903,7 @@ vimperator.Events = function () //{{{
|
|||||||
vimperator.input.buffer += key;
|
vimperator.input.buffer += key;
|
||||||
inputBufferLength++;
|
inputBufferLength++;
|
||||||
}
|
}
|
||||||
else
|
else // if the key is neither a mapping nor the start of one
|
||||||
{
|
{
|
||||||
if (vimperator.input.buffer != "" && !skipMap) // no map found -> refeed stuff in v.input.buffer
|
if (vimperator.input.buffer != "" && !skipMap) // no map found -> refeed stuff in v.input.buffer
|
||||||
{
|
{
|
||||||
@@ -810,7 +912,7 @@ vimperator.Events = function () //{{{
|
|||||||
}
|
}
|
||||||
if (skipMap)
|
if (skipMap)
|
||||||
{
|
{
|
||||||
if (--inputBufferLength == 0) // inputBufferLenght == 0. v.input.buffer refeeded...
|
if (--inputBufferLength == 0) // inputBufferLength == 0. v.input.buffer refeeded...
|
||||||
skipMap = false; // done...
|
skipMap = false; // done...
|
||||||
}
|
}
|
||||||
vimperator.input.buffer = "";
|
vimperator.input.buffer = "";
|
||||||
@@ -822,10 +924,10 @@ vimperator.Events = function () //{{{
|
|||||||
// allow key to be passed to firefox if we can't handle it
|
// allow key to be passed to firefox if we can't handle it
|
||||||
stop = false;
|
stop = false;
|
||||||
|
|
||||||
// TODO: see if this check is needed or are all motion commands already mapped in these modes?
|
if (vimperator.mode == vimperator.modes.COMMAND_LINE)
|
||||||
if (vimperator.mode != vimperator.modes.INSERT &&
|
vimperator.commandline.onEvent(event); // reroute event in command line mode
|
||||||
vimperator.mode != vimperator.modes.COMMAND_LINE)
|
else if (vimperator.mode != vimperator.modes.INSERT)
|
||||||
vimperator.beep();
|
vimperator.beep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -873,6 +975,7 @@ vimperator.Events = function () //{{{
|
|||||||
// only thrown for the current tab, not when another tab changes
|
// only thrown for the current tab, not when another tab changes
|
||||||
if (flags & Components.interfaces.nsIWebProgressListener.STATE_START)
|
if (flags & Components.interfaces.nsIWebProgressListener.STATE_START)
|
||||||
{
|
{
|
||||||
|
dump("start\n");
|
||||||
vimperator.buffer.loaded = 0;
|
vimperator.buffer.loaded = 0;
|
||||||
vimperator.statusline.updateProgress(0);
|
vimperator.statusline.updateProgress(0);
|
||||||
setTimeout (function () { vimperator.modes.reset(false); },
|
setTimeout (function () { vimperator.modes.reset(false); },
|
||||||
@@ -880,6 +983,7 @@ vimperator.Events = function () //{{{
|
|||||||
}
|
}
|
||||||
else if (flags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
|
else if (flags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
|
||||||
{
|
{
|
||||||
|
dump("stop\n");
|
||||||
vimperator.buffer.loaded = (status == 0 ? 1 : 2);
|
vimperator.buffer.loaded = (status == 0 ? 1 : 2);
|
||||||
vimperator.statusline.updateUrl();
|
vimperator.statusline.updateUrl();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -462,10 +462,21 @@ vimperator.Hints = function () //{{{
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
setTimeout(function () {
|
if (timeout == 0 || vimperator.modes.isReplaying)
|
||||||
|
{
|
||||||
|
// force a possible mode change, based on wheter an input field has focus
|
||||||
|
vimperator.events.onFocusChange();
|
||||||
if (vimperator.mode == vimperator.modes.HINTS)
|
if (vimperator.mode == vimperator.modes.HINTS)
|
||||||
vimperator.modes.reset(false);
|
vimperator.modes.reset(false);
|
||||||
}, timeout);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vimperator.modes.add(vimperator.modes.INACTIVE_HINT);
|
||||||
|
setTimeout(function () {
|
||||||
|
if (vimperator.mode == vimperator.modes.HINTS)
|
||||||
|
vimperator.modes.reset(false);
|
||||||
|
}, timeout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -145,14 +145,14 @@ vimperator.IO = function () //{{{
|
|||||||
return this.getCurrentDirectory();
|
return this.getCurrentDirectory();
|
||||||
},
|
},
|
||||||
|
|
||||||
getPluginDir: function ()
|
getSpecialDirectory: function (directory)
|
||||||
{
|
{
|
||||||
var pluginDir;
|
var pluginDir;
|
||||||
|
|
||||||
if (WINDOWS)
|
if (WINDOWS)
|
||||||
pluginDir = "~/vimperator/plugin";
|
pluginDir = "~/vimperator/" + directory;
|
||||||
else
|
else
|
||||||
pluginDir = "~/.vimperator/plugin";
|
pluginDir = "~/.vimperator/" + directory;
|
||||||
|
|
||||||
pluginDir = this.getFile(this.expandPath(pluginDir));
|
pluginDir = this.getFile(this.expandPath(pluginDir));
|
||||||
|
|
||||||
|
|||||||
@@ -398,6 +398,17 @@ vimperator.Mappings = function () //{{{
|
|||||||
help: "In command line mode, you can perform extended commands, which may require arguments."
|
help: "In command line mode, you can perform extended commands, which may require arguments."
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
|
addDefaultMap(new vimperator.Map([vimperator.modes.NORMAL, vimperator.modes.VISUAL, vimperator.modes.CARET], ["<Tab>"],
|
||||||
|
function () { document.commandDispatcher.advanceFocus(); },
|
||||||
|
{ shortHelp: "Advance keyboard focus" }
|
||||||
|
));
|
||||||
|
addDefaultMap(new vimperator.Map([vimperator.modes.NORMAL, vimperator.modes.VISUAL, vimperator.modes.CARET, vimperator.modes.INSERT, vimperator.modes.TEXTAREA],
|
||||||
|
["<S-Tab>"],
|
||||||
|
function () { document.commandDispatcher.rewindFocus(); },
|
||||||
|
{ shortHelp: "Rewind keyboard focus" }
|
||||||
|
));
|
||||||
|
|
||||||
addDefaultMap(new vimperator.Map([vimperator.modes.NORMAL], ["i", "<Insert>"],
|
addDefaultMap(new vimperator.Map([vimperator.modes.NORMAL], ["i", "<Insert>"],
|
||||||
function ()
|
function ()
|
||||||
{
|
{
|
||||||
@@ -1923,10 +1934,14 @@ vimperator.Mappings = function () //{{{
|
|||||||
function () { vimperator.editor.editWithExternalEditor(); },
|
function () { vimperator.editor.editWithExternalEditor(); },
|
||||||
{ }
|
{ }
|
||||||
));
|
));
|
||||||
addDefaultMap(new vimperator.Map([vimperator.modes.INSERT, vimperator.modes.TEXTAREA], ["<Space>", "<Tab>", "<Return>"],
|
addDefaultMap(new vimperator.Map([vimperator.modes.INSERT, vimperator.modes.TEXTAREA], ["<Space>", "<Return>"],
|
||||||
function () { return vimperator.editor.expandAbbreviation("i"); },
|
function () { return vimperator.editor.expandAbbreviation("i"); },
|
||||||
{ flags: vimperator.Mappings.flags.ALLOW_EVENT_ROUTING }
|
{ flags: vimperator.Mappings.flags.ALLOW_EVENT_ROUTING }
|
||||||
));
|
));
|
||||||
|
addDefaultMap(new vimperator.Map([vimperator.modes.INSERT, vimperator.modes.TEXTAREA], ["<Tab>"],
|
||||||
|
function () { vimperator.editor.expandAbbreviation("i"); document.commandDispatcher.advanceFocus(); },
|
||||||
|
{ }
|
||||||
|
));
|
||||||
addDefaultMap(new vimperator.Map([vimperator.modes.INSERT, vimperator.modes.TEXTAREA],
|
addDefaultMap(new vimperator.Map([vimperator.modes.INSERT, vimperator.modes.TEXTAREA],
|
||||||
["<C-]>", "<C-5>"], function () { vimperator.editor.expandAbbreviation("i"); }, { }
|
["<C-]>", "<C-5>"], function () { vimperator.editor.expandAbbreviation("i"); }, { }
|
||||||
));
|
));
|
||||||
@@ -1939,8 +1954,8 @@ vimperator.Mappings = function () //{{{
|
|||||||
function () { return vimperator.editor.expandAbbreviation("c"); },
|
function () { return vimperator.editor.expandAbbreviation("c"); },
|
||||||
{ flags: vimperator.Mappings.flags.ALLOW_EVENT_ROUTING }
|
{ flags: vimperator.Mappings.flags.ALLOW_EVENT_ROUTING }
|
||||||
));
|
));
|
||||||
addDefaultMap(new vimperator.Map([vimperator.modes.COMMAND_LINE],
|
addDefaultMap(new vimperator.Map([vimperator.modes.COMMAND_LINE], ["<C-]>", "<C-5>"],
|
||||||
["<C-]>", "<C-5>"], function () { vimperator.editor.expandAbbreviation("c"); }, { }
|
function () { vimperator.editor.expandAbbreviation("c"); }, { }
|
||||||
));
|
));
|
||||||
|
|
||||||
//}}} }}}
|
//}}} }}}
|
||||||
|
|||||||
@@ -37,43 +37,51 @@ vimperator.modes = (function () //{{{
|
|||||||
|
|
||||||
var passNextKey = false;
|
var passNextKey = false;
|
||||||
var passAllKeys = false;
|
var passAllKeys = false;
|
||||||
|
var isRecording = false;
|
||||||
|
var isReplaying = false; // playing a macro
|
||||||
|
|
||||||
function getModeMessage()
|
function getModeMessage()
|
||||||
{
|
{
|
||||||
if (passNextKey && !passAllKeys)
|
if (passNextKey && !passAllKeys)
|
||||||
return "PASS THROUGH (next)";
|
return "-- PASS THROUGH (next) --";
|
||||||
else if (passAllKeys && !passNextKey)
|
else if (passAllKeys && !passNextKey)
|
||||||
return "PASS THROUGH";
|
return "-- PASS THROUGH --";
|
||||||
|
|
||||||
var ext = "";
|
var ext = "";
|
||||||
switch (extended)
|
if (extended & vimperator.modes.QUICK_HINT)
|
||||||
{
|
ext += " (quick)";
|
||||||
case vimperator.modes.QUICK_HINT:
|
if (extended & vimperator.modes.EXTENDED_HINT)
|
||||||
ext = " (quick)"; break;
|
ext += " (extended)";
|
||||||
case vimperator.modes.EXTENDED_HINT:
|
if (extended & vimperator.modes.ALWAYS_HINT)
|
||||||
ext = " (extended)"; break;
|
ext += " (always)";
|
||||||
case vimperator.modes.ALWAYS_HINT:
|
if (extended & vimperator.modes.INACTIVE_HINT)
|
||||||
ext = " (always)"; break;
|
ext += " (inactive)";
|
||||||
case vimperator.modes.MENU: // TODO: desirable?
|
if (extended & vimperator.modes.MENU) // TODO: desirable?
|
||||||
ext = " (menu)"; break;
|
ext += " (menu)";
|
||||||
case vimperator.modes.RECORDING:
|
|
||||||
ext = " (recording)"; break;
|
ext += " --";
|
||||||
}
|
|
||||||
|
// when recording a macro
|
||||||
|
if (vimperator.modes.isRecording)
|
||||||
|
ext += "recording";
|
||||||
|
|
||||||
switch (main)
|
switch (main)
|
||||||
{
|
{
|
||||||
case vimperator.modes.INSERT:
|
case vimperator.modes.INSERT:
|
||||||
return "INSERT" + ext;
|
return "-- INSERT" + ext;
|
||||||
case vimperator.modes.VISUAL:
|
case vimperator.modes.VISUAL:
|
||||||
return (extended & vimperator.modes.LINE) ? "VISUAL LINE" + ext : "VISUAL" + ext;
|
return (extended & vimperator.modes.LINE) ? "-- VISUAL LINE" + ext : "-- VISUAL" + ext;
|
||||||
case vimperator.modes.HINTS:
|
case vimperator.modes.HINTS:
|
||||||
return "HINTS" + ext;
|
return "-- HINTS" + ext;
|
||||||
case vimperator.modes.CARET:
|
case vimperator.modes.CARET:
|
||||||
return "CARET" + ext;
|
return "-- CARET" + ext;
|
||||||
case vimperator.modes.TEXTAREA:
|
case vimperator.modes.TEXTAREA:
|
||||||
return "TEXTAREA" + ext;
|
return "-- TEXTAREA" + ext;
|
||||||
default:
|
default: // NORMAL mode
|
||||||
return null;
|
if (vimperator.modes.isRecording)
|
||||||
|
return "recording";
|
||||||
|
else
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +93,7 @@ vimperator.modes = (function () //{{{
|
|||||||
{
|
{
|
||||||
// TODO: fix v.log() to work with verbosity level
|
// TODO: fix v.log() to work with verbosity level
|
||||||
// vimperator.log("switching from mode " + oldMode + " to mode " + newMode, 7);
|
// vimperator.log("switching from mode " + oldMode + " to mode " + newMode, 7);
|
||||||
|
dump("switching from mode " + oldMode + " to mode " + newMode + "\n");
|
||||||
|
|
||||||
switch (oldMode)
|
switch (oldMode)
|
||||||
{
|
{
|
||||||
@@ -153,9 +162,10 @@ vimperator.modes = (function () //{{{
|
|||||||
QUICK_HINT: 1 << 15,
|
QUICK_HINT: 1 << 15,
|
||||||
EXTENDED_HINT: 1 << 16,
|
EXTENDED_HINT: 1 << 16,
|
||||||
ALWAYS_HINT: 1 << 17,
|
ALWAYS_HINT: 1 << 17,
|
||||||
MENU: 1 << 18, // a popupmenu is active
|
INACTIVE_HINT: 1 << 18, // a short time after following a hint, we do not accept any input
|
||||||
LINE: 1 << 19, // linewise visual mode
|
MENU: 1 << 19, // a popupmenu is active
|
||||||
RECORDING: 1 << 20,
|
LINE: 1 << 20, // linewise visual mode
|
||||||
|
RECORDING: 1 << 21,
|
||||||
|
|
||||||
__iterator__: function ()
|
__iterator__: function ()
|
||||||
{
|
{
|
||||||
@@ -168,6 +178,7 @@ vimperator.modes = (function () //{{{
|
|||||||
throw StopIteration;
|
throw StopIteration;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// keeps recording state
|
||||||
reset: function (silent)
|
reset: function (silent)
|
||||||
{
|
{
|
||||||
this.set(vimperator.modes.NORMAL, vimperator.modes.NONE, silent);
|
this.set(vimperator.modes.NORMAL, vimperator.modes.NONE, silent);
|
||||||
@@ -182,11 +193,7 @@ vimperator.modes = (function () //{{{
|
|||||||
if (main == vimperator.modes.COMMAND_LINE)
|
if (main == vimperator.modes.COMMAND_LINE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var msg = getModeMessage();
|
vimperator.commandline.echo(getModeMessage(), vimperator.commandline.HL_MODEMSG, vimperator.commandline.DISALLOW_MULTILINE);
|
||||||
if (msg)
|
|
||||||
vimperator.commandline.echo("-- " + getModeMessage() + " --", vimperator.commandline.HL_MODEMSG, vimperator.commandline.DISALLOW_MULTILINE);
|
|
||||||
else
|
|
||||||
vimperator.commandline.echo("", null, vimperator.commandline.DISALLOW_MULTILINE);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// helper function to set both modes in one go
|
// helper function to set both modes in one go
|
||||||
@@ -229,6 +236,12 @@ vimperator.modes = (function () //{{{
|
|||||||
get passAllKeys() { return passAllKeys; },
|
get passAllKeys() { return passAllKeys; },
|
||||||
set passAllKeys(value) { passAllKeys = value; this.show(); },
|
set passAllKeys(value) { passAllKeys = value; this.show(); },
|
||||||
|
|
||||||
|
get isRecording() { return isRecording; },
|
||||||
|
set isRecording(value) { isRecording = value; this.show(); },
|
||||||
|
|
||||||
|
get isReplaying() { return isReplaying; },
|
||||||
|
set isReplaying(value) { isReplaying = value; },
|
||||||
|
|
||||||
get main() { return main; },
|
get main() { return main; },
|
||||||
set main(value) {
|
set main(value) {
|
||||||
if (value != main)
|
if (value != main)
|
||||||
|
|||||||
@@ -396,6 +396,7 @@ vimperator.CommandLine = function () //{{{
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var key = vimperator.events.toString(event);
|
var key = vimperator.events.toString(event);
|
||||||
|
// dump("command line handling key: " + key + "\n");
|
||||||
|
|
||||||
// user pressed ENTER to carry out a command
|
// user pressed ENTER to carry out a command
|
||||||
// user pressing ESCAPE is handled in the global onEscape
|
// user pressing ESCAPE is handled in the global onEscape
|
||||||
@@ -410,7 +411,6 @@ vimperator.CommandLine = function () //{{{
|
|||||||
return vimperator.triggerCallback("submit", mode, command);
|
return vimperator.triggerCallback("submit", mode, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// user pressed UP or DOWN arrow to cycle history completion
|
// user pressed UP or DOWN arrow to cycle history completion
|
||||||
else if (key == "<Up>" || key == "<Down>")
|
else if (key == "<Up>" || key == "<Down>")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -660,7 +660,7 @@ const vimperator = (function () //{{{
|
|||||||
// also source plugins in ~/.vimperator/plugin/
|
// also source plugins in ~/.vimperator/plugin/
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var pluginDir = vimperator.io.getPluginDir();
|
var pluginDir = vimperator.io.getSpecialDirectory("plugin");
|
||||||
if (pluginDir)
|
if (pluginDir)
|
||||||
{
|
{
|
||||||
var files = vimperator.io.readDirectory(pluginDir.path);
|
var files = vimperator.io.readDirectory(pluginDir.path);
|
||||||
|
|||||||
@@ -123,7 +123,6 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
|||||||
<hbox id="vimperator-commandline" hidden="false" class="hl-Normal">
|
<hbox id="vimperator-commandline" hidden="false" class="hl-Normal">
|
||||||
<label class="plain" id="vimperator-commandline-prompt" flex="0" crop="end" value="" collapsed="true"/>
|
<label class="plain" id="vimperator-commandline-prompt" flex="0" crop="end" value="" collapsed="true"/>
|
||||||
<textbox class="plain" id="vimperator-commandline-command" flex="1" type="timed" timeout="100"
|
<textbox class="plain" id="vimperator-commandline-command" flex="1" type="timed" timeout="100"
|
||||||
onkeypress="vimperator.commandline.onEvent(event);"
|
|
||||||
oninput="vimperator.commandline.onEvent(event);"
|
oninput="vimperator.commandline.onEvent(event);"
|
||||||
onfocus="vimperator.commandline.onEvent(event);"
|
onfocus="vimperator.commandline.onEvent(event);"
|
||||||
onblur="vimperator.commandline.onEvent(event);"/>
|
onblur="vimperator.commandline.onEvent(event);"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user