1
0
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:
Martin Stubenschrott
2007-12-18 15:05:03 +00:00
parent 39fbf33d8b
commit 5122e6c448
10 changed files with 289 additions and 147 deletions

View File

@@ -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)
{ {

View File

@@ -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 () {

View File

@@ -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();
} }

View File

@@ -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;

View File

@@ -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));

View File

@@ -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"); }, { }
)); ));
//}}} }}} //}}} }}}

View File

@@ -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)

View File

@@ -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>")
{ {

View File

@@ -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);

View File

@@ -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);"/>