mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-22 23:58:00 +01:00
new alwayshints mode on ;a and F for quickhints in new tab
This commit is contained in:
2
NEWS
2
NEWS
@@ -4,6 +4,8 @@
|
|||||||
* THIS VERSION ONLY WORKS WITH FIREFOX 3.0
|
* THIS VERSION ONLY WORKS WITH FIREFOX 3.0
|
||||||
* IMPORTANT! options are no longer automatically stored - use the
|
* IMPORTANT! options are no longer automatically stored - use the
|
||||||
~/.vimperatorrc file instead for persistent options
|
~/.vimperatorrc file instead for persistent options
|
||||||
|
* IMPORTANT! Major hints rewrite
|
||||||
|
read up the new help for the f, F and ; commands for details
|
||||||
* added new :mkvimperatorrc command
|
* added new :mkvimperatorrc command
|
||||||
* you can edit textfields with Ctrl-i now using an external editor (thanks to Joseph Xu)
|
* you can edit textfields with Ctrl-i now using an external editor (thanks to Joseph Xu)
|
||||||
* :open, :bmarks, etc. filter on space separated tokens now, so you can
|
* :open, :bmarks, etc. filter on space separated tokens now, so you can
|
||||||
|
|||||||
8
TODO
8
TODO
@@ -3,21 +3,15 @@ Priority list:
|
|||||||
1-9 as in vim (9=required for next release, 5=would be nice, 1=probably not)
|
1-9 as in vim (9=required for next release, 5=would be nice, 1=probably not)
|
||||||
|
|
||||||
BUGS:
|
BUGS:
|
||||||
- http://en.wikipedia.org/wiki/Portal:Current_events - 'f' shows more hints than 'F' (on left side of nav bar)
|
|
||||||
- dpb| 09:09:56 dpb :: when I save a page with vimperator, it adds <hints
|
|
||||||
id="hah_hints"></hints> near the end of it.. kinda annoying
|
|
||||||
dpb| 09:11:50 dpb :: and this happens only when saving the complete
|
|
||||||
webpage, saving only the html works just fine..
|
|
||||||
- add window resize support to hints
|
- add window resize support to hints
|
||||||
- can't reverse tab through the vimperator toolbar
|
- can't reverse tab through the vimperator toolbar
|
||||||
- gu and gU don't work on local files properly
|
- gu and gU don't work on local files properly - still valid?
|
||||||
- :noremap does not work fully
|
- :noremap does not work fully
|
||||||
- pvh option not working
|
- pvh option not working
|
||||||
- searching backwards incrementally does not work i.e. with 'incsearch' set
|
- searching backwards incrementally does not work i.e. with 'incsearch' set
|
||||||
|
|
||||||
FEATURES:
|
FEATURES:
|
||||||
9 :command for new commands
|
9 :command for new commands
|
||||||
9 make hints smarter, not only with characters from from hintchars, but use "NE" or "NP" for 'new posts' e.g. (might be too slow)
|
|
||||||
8 add an interface for navigating document relationships
|
8 add an interface for navigating document relationships
|
||||||
8 middleclick in content == p, and if command line is open, paste there the clipboard buffer
|
8 middleclick in content == p, and if command line is open, paste there the clipboard buffer
|
||||||
7 use ctrl-n/p in insert mode for word completion
|
7 use ctrl-n/p in insert mode for word completion
|
||||||
|
|||||||
@@ -52,11 +52,15 @@ vimperator.Events = function() //{{{
|
|||||||
vimperator.buffer.updateBufferList();
|
vimperator.buffer.updateBufferList();
|
||||||
}, false);
|
}, false);
|
||||||
tabcontainer.addEventListener("TabSelect", function(event) {
|
tabcontainer.addEventListener("TabSelect", function(event) {
|
||||||
|
if (vimperator.mode == vimperator.modes.HINTS)
|
||||||
|
vimperator.modes.reset();
|
||||||
|
|
||||||
vimperator.commandline.clear();
|
vimperator.commandline.clear();
|
||||||
vimperator.modes.show();
|
vimperator.modes.show();
|
||||||
vimperator.statusline.updateTabCount();
|
vimperator.statusline.updateTabCount();
|
||||||
vimperator.buffer.updateBufferList();
|
vimperator.buffer.updateBufferList();
|
||||||
vimperator.tabs.updateSelectionHistory();
|
vimperator.tabs.updateSelectionHistory();
|
||||||
|
|
||||||
setTimeout(function() { vimperator.focusContent(true); }, 10); // just make sure, that no widget has focus
|
setTimeout(function() { vimperator.focusContent(true); }, 10); // just make sure, that no widget has focus
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
@@ -620,7 +624,8 @@ vimperator.Events = function() //{{{
|
|||||||
vimperator.hints.onEvent(event);
|
vimperator.hints.onEvent(event);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
151
content/hints.js
151
content/hints.js
@@ -35,10 +35,10 @@ vimperator.Hints = function() //{{{
|
|||||||
var hints = [];
|
var hints = [];
|
||||||
var valid_hints = []; // store the indices of the "hints" array with valid elements
|
var valid_hints = []; // store the indices of the "hints" array with valid elements
|
||||||
|
|
||||||
var canUpdate = true;
|
var canUpdate = false;
|
||||||
|
var hintsGenerated = false;
|
||||||
var timeout = 200; // only update every 200ms when typing fast, not used yet
|
var timeout = 200; // only update every 200ms when typing fast, not used yet
|
||||||
|
var docs = []; // keep track of the documents which we display the hints for
|
||||||
var wins = []; // keep track of the windows which we display the hints for
|
|
||||||
|
|
||||||
// this function 'click' an element, which also works
|
// this function 'click' an element, which also works
|
||||||
// for javascript links
|
// for javascript links
|
||||||
@@ -148,7 +148,7 @@ vimperator.Hints = function() //{{{
|
|||||||
win = window.content;
|
win = window.content;
|
||||||
|
|
||||||
var doc = win.document;
|
var doc = win.document;
|
||||||
wins.push(doc);
|
docs.push(doc);
|
||||||
|
|
||||||
var baseNodeAbsolute = doc.createElementNS("http://www.w3.org/1999/xhtml", "span");
|
var baseNodeAbsolute = doc.createElementNS("http://www.w3.org/1999/xhtml", "span");
|
||||||
baseNodeAbsolute.style.backgroundColor = "red";
|
baseNodeAbsolute.style.backgroundColor = "red";
|
||||||
@@ -201,9 +201,21 @@ vimperator.Hints = function() //{{{
|
|||||||
hints.push([elem, text, span, elem.style.backgroundColor, elem.style.color]);
|
hints.push([elem, text, span, elem.style.backgroundColor, elem.style.color]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hintsGenerated = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset all important variables
|
||||||
|
function reset()
|
||||||
|
{
|
||||||
|
vimperator.statusline.updateInputBuffer("");
|
||||||
|
linkNumString = "";
|
||||||
|
hints = [];
|
||||||
|
valid_hints = [];
|
||||||
|
canUpdate = false;
|
||||||
|
hintsGenerated = false;
|
||||||
|
}
|
||||||
|
|
||||||
function showHints(win, str, start_idx)
|
function showHints(win, str, start_idx)
|
||||||
{
|
{
|
||||||
if (!win)
|
if (!win)
|
||||||
@@ -275,6 +287,7 @@ outer:
|
|||||||
|
|
||||||
function removeHints(doc, timeout)
|
function removeHints(doc, timeout)
|
||||||
{
|
{
|
||||||
|
vimperator.log(timeout);
|
||||||
if (!doc)
|
if (!doc)
|
||||||
{
|
{
|
||||||
vimperator.log("Argument doc is required for internal removeHints() method", 9);
|
vimperator.log("Argument doc is required for internal removeHints() method", 9);
|
||||||
@@ -336,8 +349,11 @@ outer:
|
|||||||
firstElem.style.color = firstElemColor;
|
firstElem.style.color = firstElemColor;
|
||||||
}, timeout);
|
}, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (e) { vimperator.log("Error hiding hints, probably wrong window"); }
|
catch (e) { vimperator.log("Error hiding hints, probably wrong window"); }
|
||||||
|
|
||||||
|
reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
function processHints(followFirst)
|
function processHints(followFirst)
|
||||||
@@ -347,47 +363,57 @@ outer:
|
|||||||
vimperator.beep();
|
vimperator.beep();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (!followFirst)
|
||||||
{
|
{
|
||||||
if (!followFirst)
|
var first_href = valid_hints[0].getAttribute("href") || null;
|
||||||
|
if (first_href)
|
||||||
{
|
{
|
||||||
var first_href = valid_hints[0].getAttribute("href") || null;
|
if (valid_hints.some( function(e) { return e.getAttribute("href") != first_href; } ))
|
||||||
if (first_href)
|
|
||||||
{
|
|
||||||
if (valid_hints.some( function(e) { return e.getAttribute("href") != first_href; } ))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (valid_hints.length > 1)
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (valid_hints.length > 1)
|
||||||
if (vimperator.modes.extended & vimperator.modes.QUICK_HINT)
|
return false;
|
||||||
openHint(false, false);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var loc = valid_hints.length > 0 ? valid_hints[0].href : "";
|
|
||||||
switch (submode)
|
|
||||||
{
|
|
||||||
case "f": focusHint(); break;
|
|
||||||
case "o": openHint(false, false); break;
|
|
||||||
case "O": vimperator.commandline.open(":", "open " + loc, vimperator.modes.EX); break;
|
|
||||||
case "t": openHint(true, false); break;
|
|
||||||
case "T": openHint(true, false); break;
|
|
||||||
case "T": vimperator.commandline.open(":", "tabopen " + loc, vimperator.modes.EX); break;
|
|
||||||
case "w": openHint(false, true); break;
|
|
||||||
case "W": vimperator.commandline.open(":", "winopen " + loc, vimperator.modes.EX); break;
|
|
||||||
case "a": saveHint(false); break;
|
|
||||||
case "s": saveHint(true); break;
|
|
||||||
case "y": yankHint(false); break;
|
|
||||||
case "Y": yankHint(true); break;
|
|
||||||
default:
|
|
||||||
vimperator.echoerr("INTERNAL ERROR: unknown submode: " + submode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// I KNOW, ugly but this. is not available in this context :(
|
|
||||||
vimperator.hints.hide(null, !followFirst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var loc = valid_hints.length > 0 ? valid_hints[0].href : "";
|
||||||
|
switch (submode)
|
||||||
|
{
|
||||||
|
case "f": focusHint(); break;
|
||||||
|
case "o": openHint(false, false); break;
|
||||||
|
case "O": vimperator.commandline.open(":", "open " + loc, vimperator.modes.EX); break;
|
||||||
|
case "t": openHint(true, false); break;
|
||||||
|
case "T": openHint(true, false); break;
|
||||||
|
case "T": vimperator.commandline.open(":", "tabopen " + loc, vimperator.modes.EX); break;
|
||||||
|
case "w": openHint(false, true); break;
|
||||||
|
case "W": vimperator.commandline.open(":", "winopen " + loc, vimperator.modes.EX); break;
|
||||||
|
case "a": saveHint(false); break;
|
||||||
|
case "s": saveHint(true); break;
|
||||||
|
case "y": yankHint(false); break;
|
||||||
|
case "Y": yankHint(true); break;
|
||||||
|
default:
|
||||||
|
vimperator.echoerr("INTERNAL ERROR: unknown submode: " + submode);
|
||||||
|
}
|
||||||
|
|
||||||
|
var timeout = followFirst ? 0 : 500;
|
||||||
|
removeHints(docs.pop(), timeout);
|
||||||
|
|
||||||
|
if (vimperator.modes.extended & vimperator.modes.ALWAYS_HINT)
|
||||||
|
{
|
||||||
|
setTimeout(function() {
|
||||||
|
canUpdate = true;
|
||||||
|
linkNumString = "";
|
||||||
|
vimperator.statusline.updateInputBuffer("");
|
||||||
|
}, timeout);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setTimeout( function() {
|
||||||
|
if (vimperator.mode == vimperator.modes.HINTS)
|
||||||
|
vimperator.modes.reset(false);
|
||||||
|
}, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -405,7 +431,7 @@ outer:
|
|||||||
}
|
}
|
||||||
|
|
||||||
vimperator.modes.set(vimperator.modes.HINTS, mode);
|
vimperator.modes.set(vimperator.modes.HINTS, mode);
|
||||||
submode = minor;
|
submode = minor || "o"; // open is the default mode
|
||||||
linkNumString = filter || "";
|
linkNumString = filter || "";
|
||||||
canUpdate = false;
|
canUpdate = false;
|
||||||
|
|
||||||
@@ -432,26 +458,14 @@ outer:
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.hide = function(win, delayModeChange)
|
this.hide = function()
|
||||||
{
|
{
|
||||||
var timeout = delayModeChange ? 500 : 0;
|
if (!hintsGenerated)
|
||||||
doc = wins.pop();
|
return;
|
||||||
|
|
||||||
|
doc = docs.pop();
|
||||||
if(doc);
|
if(doc);
|
||||||
removeHints(doc, timeout);
|
removeHints(doc, 0);
|
||||||
|
|
||||||
vimperator.echo(" ");
|
|
||||||
vimperator.statusline.updateInputBuffer("");
|
|
||||||
|
|
||||||
linkNumString = "";
|
|
||||||
hints = [];
|
|
||||||
valid_hints = [];
|
|
||||||
canUpdate = false;
|
|
||||||
|
|
||||||
// only close this mode half a second later, so we don't trigger accidental actions so easily
|
|
||||||
setTimeout( function() {
|
|
||||||
if (vimperator.mode == vimperator.modes.HINTS)
|
|
||||||
vimperator.modes.reset(true);
|
|
||||||
}, timeout);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onEvent = function(event)
|
this.onEvent = function(event)
|
||||||
@@ -484,15 +498,34 @@ outer:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
// pass any special or ctrl- etc. prefixed key back to the main vimperator loop
|
||||||
|
if (/^<./.test(key) || key == ":")
|
||||||
|
{
|
||||||
|
var map = null;
|
||||||
|
if ((map = vimperator.mappings.get(vimperator.modes.NORMAL, key)) ||
|
||||||
|
(map = vimperator.mappings.get(vimperator.modes.HINTS, key)))
|
||||||
|
{
|
||||||
|
map.execute(null, -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vimperator.beep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
linkNumString += key;
|
linkNumString += key;
|
||||||
}
|
}
|
||||||
|
|
||||||
vimperator.statusline.updateInputBuffer(linkNumString);
|
vimperator.statusline.updateInputBuffer(linkNumString);
|
||||||
if (canUpdate)
|
if (canUpdate)
|
||||||
{
|
{
|
||||||
|
if (!hintsGenerated && linkNumString.length > 0)
|
||||||
|
generate();
|
||||||
|
|
||||||
showHints(null, linkNumString);
|
showHints(null, linkNumString);
|
||||||
processHints(followFirst);
|
processHints(followFirst);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1027,25 +1027,40 @@ vimperator.Mappings = function() //{{{
|
|||||||
usage: ["f{hint}"],
|
usage: ["f{hint}"],
|
||||||
help: "In QuickHint mode, every hintable item (according to the <code class=\"option\">'hinttags'</code> XPath query) is assigned a unique number (FIXME: numbers shown, but not usable yet).<br/>" +
|
help: "In QuickHint mode, every hintable item (according to the <code class=\"option\">'hinttags'</code> XPath query) is assigned a unique number (FIXME: numbers shown, but not usable yet).<br/>" +
|
||||||
"You can now either type this number or type any part of the URL which you want to follow, and it is followed as soon as it can be uniquely identified. " +
|
"You can now either type this number or type any part of the URL which you want to follow, and it is followed as soon as it can be uniquely identified. " +
|
||||||
//"If you write the hint in ALLCAPS, the hint is followed in a background tab.<br/>" +
|
|
||||||
"Often it is can be useful to combine these techniques to narrow down results with some letters, and then typing a single digit to make the match unique.<br/>" +
|
"Often it is can be useful to combine these techniques to narrow down results with some letters, and then typing a single digit to make the match unique.<br/>" +
|
||||||
"<code class=\"mapping\"><Esc></code> stops this mode at any time."
|
"<code class=\"mapping\"><Esc></code> stops this mode at any time."
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
addDefaultMap(new vimperator.Map([vimperator.modes.NORMAL], ["F"],
|
addDefaultMap(new vimperator.Map([vimperator.modes.NORMAL], ["F"],
|
||||||
function() { vimperator.echo("Always HINT mode not available anymore"); },
|
function() { vimperator.hints.show(vimperator.modes.QUICK_HINT, "t"); },
|
||||||
{
|
{
|
||||||
short_help: "Start AlwaysHint mode (CURRENTLY DISABLED)",
|
short_help: "Start QuickHint mode, but open link in a new tab",
|
||||||
help: "In AlwaysHint mode, every hintable item (according to the <code class=\"option\">'hinttags'</code> XPath query) is assigned a label.<br/>" +
|
usage: ["F{hint}"],
|
||||||
"If you then press the keys for a label, it is followed as soon as it can be uniquely identified. Labels stay active after following a hint in this mode, press <code class=\"mapping\"><Esc></code> to stop this mode.<br/>" +
|
help: "Like normal QuickMode (activated with <code class='mapping'>f</code>) but open the link in a new tab."
|
||||||
"This hint mode is especially useful for browsing large sites like Forums as hints are automatically regenerated when switching to a new document.<br/>" +
|
|
||||||
"Also, most <code class=\"mapping\">Ctrl</code>-prefixed shortcut keys are available in this mode for navigation."
|
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
// addDefaultMap(new vimperator.Map([vimperator.modes.NORMAL], ["F"],
|
||||||
|
// function() { vimperator.echo("Always HINT mode not available anymore"); },
|
||||||
|
// {
|
||||||
|
// short_help: "Start AlwaysHint mode (CURRENTLY DISABLED)",
|
||||||
|
// help: "In AlwaysHint mode, every hintable item (according to the <code class=\"option\">'hinttags'</code> XPath query) is assigned a label.<br/>" +
|
||||||
|
// "If you then press the keys for a label, it is followed as soon as it can be uniquely identified. Labels stay active after following a hint in this mode, press <code class=\"mapping\"><Esc></code> to stop this mode.<br/>" +
|
||||||
|
// "This hint mode is especially useful for browsing large sites like Forums as hints are automatically regenerated when switching to a new document.<br/>" +
|
||||||
|
// "Also, most <code class=\"mapping\">Ctrl</code>-prefixed shortcut keys are available in this mode for navigation."
|
||||||
|
// }
|
||||||
|
// ));
|
||||||
addDefaultMap(new vimperator.Map([vimperator.modes.NORMAL], [";"],
|
addDefaultMap(new vimperator.Map([vimperator.modes.NORMAL], [";"],
|
||||||
function(arg) { vimperator.hints.show(vimperator.modes.EXTENDED_HINT, arg); },
|
function(arg)
|
||||||
{
|
{
|
||||||
short_help: "Start ExtendedHint mode",
|
if (arg == "a")
|
||||||
|
vimperator.hints.show(vimperator.modes.ALWAYS_HINT, "o");
|
||||||
|
else if (arg == "A")
|
||||||
|
vimperator.hints.show(vimperator.modes.ALWAYS_HINT, "t");
|
||||||
|
else
|
||||||
|
vimperator.hints.show(vimperator.modes.EXTENDED_HINT, arg);
|
||||||
|
},
|
||||||
|
{
|
||||||
|
short_help: "Start an extended Hint mode",
|
||||||
usage: [";{mode}{hint}"],
|
usage: [";{mode}{hint}"],
|
||||||
help: "ExtendedHint mode is useful, since in this mode you can yank link locations, open them in a new window or save images.<br/>" +
|
help: "ExtendedHint mode is useful, since in this mode you can yank link locations, open them in a new window or save images.<br/>" +
|
||||||
"If you want to yank the location of hint <code>24</code>, press <code class=\"mapping\">;y</code> to start this hint mode.<br/>" +
|
"If you want to yank the location of hint <code>24</code>, press <code class=\"mapping\">;y</code> to start this hint mode.<br/>" +
|
||||||
|
|||||||
Reference in New Issue
Block a user