Add a --rapid option to :hint, remove rapid target

This makes it possible to use rapid hinting for the run/hover/userscript/spawn
targets as well, and makes more sense anyways.
This commit is contained in:
Florian Bruhin 2015-03-10 19:40:30 +01:00
parent 4b6d49e926
commit 2f0522ebb0
2 changed files with 82 additions and 39 deletions

View File

@ -176,7 +176,7 @@ Show help about a command or setting.
[[hint]]
=== hint
Syntax: +:hint ['group'] ['target'] ['args' ['args' ...]]+
Syntax: +:hint [*--rapid*] ['group'] ['target'] ['args' ['args' ...]]+
Start hinting.
@ -201,9 +201,6 @@ Start hinting.
- `run`: Run the argument as command.
- `fill`: Fill the commandline with the command given as
argument.
- `rapid`: Open the link in a new tab and stay in hinting mode.
- `rapid-win`: Open the link in a new window and stay in
hinting mode.
- `download`: Download the link.
- `userscript`: Call an userscript with `$QUTE_URL` set to the
link.
@ -223,6 +220,11 @@ Start hinting.
- With `run`: Same as `fill`.
==== optional arguments
* +*-r*+, +*--rapid*+: Whether to do rapid hinting. This is only possible with targets `tab-bg`, `window`, `run`, `hover`, `userscript` and
`spawn`.
[[home]]
=== home
Open main startpage in current tab.

View File

@ -75,6 +75,9 @@ class HintContext:
spawn: Spawn a simple command.
to_follow: The link to follow when enter is pressed.
args: Custom arguments for userscript/spawn
rapid: Whether to do rapid hinting.
mainframe: The main QWebFrame where we started hinting in.
group: The group of webelements to hint.
"""
def __init__(self):
@ -82,9 +85,12 @@ class HintContext:
self.target = None
self.baseurl = None
self.to_follow = None
self.rapid = False
self.frames = []
self.destroyed_frames = []
self.args = []
self.mainframe = None
self.group = None
def get_args(self, urlstr):
"""Get the arguments, with {hint-url} replaced by the given URL."""
@ -116,20 +122,18 @@ class HintManager(QObject):
"""
HINT_TEXTS = {
Target.normal: "Follow hint...",
Target.tab: "Follow hint in new tab...",
Target.tab_bg: "Follow hint in background tab...",
Target.window: "Follow hint in new window...",
Target.yank: "Yank hint to clipboard...",
Target.yank_primary: "Yank hint to primary selection...",
Target.run: "Run a command on a hint...",
Target.fill: "Set hint in commandline...",
Target.hover: "Hover over a hint...",
Target.rapid: "Follow hint (rapid mode)...",
Target.rapid_win: "Follow hint in new window (rapid mode)...",
Target.download: "Download hint...",
Target.userscript: "Call userscript via hint...",
Target.spawn: "Spawn command via hint...",
Target.normal: "Follow hint",
Target.tab: "Follow hint in new tab",
Target.tab_bg: "Follow hint in background tab",
Target.window: "Follow hint in new window",
Target.yank: "Yank hint to clipboard",
Target.yank_primary: "Yank hint to primary selection",
Target.run: "Run a command on a hint",
Target.fill: "Set hint in commandline",
Target.hover: "Hover over a hint",
Target.download: "Download hint",
Target.userscript: "Call userscript via hint",
Target.spawn: "Spawn command via hint",
}
mouse_event = pyqtSignal('QMouseEvent')
@ -146,6 +150,14 @@ class HintManager(QObject):
window=win_id)
mode_manager.left.connect(self.on_mode_left)
def _get_text(self):
"""Get a hint text based on the current context."""
text = self.HINT_TEXTS[self._context.target]
if self._context.rapid:
text += ' (rapid mode)'
text += '...'
return text
def _cleanup(self):
"""Clean up after hinting."""
for elem in self._context.elems.values():
@ -169,7 +181,7 @@ class HintManager(QObject):
# See # https://github.com/The-Compiler/qutebrowser/issues/263
pass
log.hints.debug("Disconnected.")
text = self.HINT_TEXTS[self._context.target]
text = self._get_text()
message_bridge = objreg.get('message-bridge', scope='window',
window=self._win_id)
message_bridge.maybe_reset_text(text)
@ -593,21 +605,17 @@ class HintManager(QObject):
raise cmdexc.CommandError(
"'args' is only allowed with target userscript/spawn.")
def _init_elements(self, mainframe, group):
"""Initialize the elements and labels based on the context set.
Args:
mainframe: The main QWebFrame.
group: A Group enum member (which elements to find).
"""
def _init_elements(self):
"""Initialize the elements and labels based on the context set."""
elems = []
for f in self._context.frames:
elems += f.findAllElements(webelem.SELECTORS[group])
elems = [e for e in elems if webelem.is_visible(e, mainframe)]
elems += f.findAllElements(webelem.SELECTORS[self._context.group])
elems = [e for e in elems
if webelem.is_visible(e, self._context.mainframe)]
# We wrap the elements late for performance reasons, as wrapping 1000s
# of elements (with ~50 methods each) just takes too much time...
elems = [webelem.WebElementWrapper(e) for e in elems]
filterfunc = webelem.FILTERS.get(group, lambda e: True)
filterfunc = webelem.FILTERS.get(self._context.group, lambda e: True)
elems = [e for e in elems if filterfunc(e)]
if not elems:
raise cmdexc.CommandError("No elements found.")
@ -658,11 +666,14 @@ class HintManager(QObject):
webview.openurl(url)
@cmdutils.register(instance='hintmanager', scope='tab', name='hint')
def start(self, group=webelem.Group.all, target=Target.normal,
*args: {'nargs': '*'}):
def start(self, rapid=False, group=webelem.Group.all, target=Target.normal,
*args: {'nargs': '*'}, win_id: {'special': 'win_id'}):
"""Start hinting.
Args:
rapid: Whether to do rapid hinting. This is only possible with
targets `tab-bg`, `window`, `run`, `hover`, `userscript` and
`spawn`.
group: The hinting mode to use.
- `all`: All clickable elements.
@ -681,9 +692,6 @@ class HintManager(QObject):
- `run`: Run the argument as command.
- `fill`: Fill the commandline with the command given as
argument.
- `rapid`: Open the link in a new tab and stay in hinting mode.
- `rapid-win`: Open the link in a new window and stay in
hinting mode.
- `download`: Download the link.
- `userscript`: Call an userscript with `$QUTE_URL` set to the
link.
@ -712,9 +720,18 @@ class HintManager(QObject):
window=self._win_id)
if mode_manager.mode == usertypes.KeyMode.hint:
raise cmdexc.CommandError("Already hinting!")
if rapid and target not in (Target.tab_bg, Target.window, Target.run,
Target.hover, Target.userscript,
Target.spawn):
name = target.name.replace('_', '-')
raise cmdexc.CommandError("Rapid hinting makes no sense with "
"target {}!".format(name))
self._check_args(target, *args)
self._context = HintContext()
self._context.target = target
self._context.rapid = rapid
self._context.baseurl = tabbed_browser.current_url()
self._context.frames = webelem.get_child_frames(mainframe)
for frame in self._context.frames:
@ -723,14 +740,40 @@ class HintManager(QObject):
frame.destroyed.connect(functools.partial(
self._context.destroyed_frames.append, id(frame)))
self._context.args = args
self._init_elements(mainframe, group)
self._context.mainframe = mainframe
self._context.group = group
self._handle_old_rapid_targets(win_id)
self._init_elements()
message_bridge = objreg.get('message-bridge', scope='window',
window=self._win_id)
message_bridge.set_text(self.HINT_TEXTS[target])
message_bridge.set_text(self._get_text())
self._connect_frame_signals()
modeman.enter(self._win_id, usertypes.KeyMode.hint,
'HintManager.start')
def _handle_old_rapid_targets(self, win_id):
"""Switch to the new way for rapid hinting with a rapid target.
Args:
win_id: The window ID to display the warning in.
DEPRECATED.
"""
old_rapid_targets = {
Target.rapid: Target.tab_bg,
Target.rapid_win: Target.window,
}
target = self._context.target
if target in old_rapid_targets:
self._context.target = old_rapid_targets[target]
self._context.rapid = True
name = target.name.replace('_', '-')
group_name = self._context.group.name.replace('_', '-')
new_name = self._context.target.name.replace('_', '-')
message.warning(
win_id, ':hint with target {} is deprecated, use :hint '
'--rapid {} {} instead!'.format(name, group_name, new_name))
def handle_partial_key(self, keystr):
"""Handle a new partial keypress."""
log.hints.debug("Handling new keystring: '{}'".format(keystr))
@ -801,8 +844,6 @@ class HintManager(QObject):
Target.tab: self._click,
Target.tab_bg: self._click,
Target.window: self._click,
Target.rapid: self._click,
Target.rapid_win: self._click,
Target.hover: self._click,
# _download needs a QWebElement to get the frame.
Target.download: self._download,
@ -829,7 +870,7 @@ class HintManager(QObject):
url_handlers[self._context.target], url, self._context)
else:
raise ValueError("No suitable handler found!")
if self._context.target not in (Target.rapid, Target.rapid_win):
if not self._context.rapid:
modeman.maybe_leave(self._win_id, usertypes.KeyMode.hint,
'followed')
else: