1
0
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:
Martin Stubenschrott
2007-10-25 23:30:10 +00:00
parent faefb78c24
commit 11815eaa73
5 changed files with 125 additions and 76 deletions

2
NEWS
View File

@@ -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
View File

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

View File

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

View File

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

View File

@@ -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\">&lt;Esc&gt;</code> stops this mode at any time." "<code class=\"mapping\">&lt;Esc&gt;</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\">&lt;Esc&gt;</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\">&lt;Esc&gt;</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/>" +