diff options
author | toofar <toofar@spalge.com> | 2024-09-17 18:56:10 +1200 |
---|---|---|
committer | toofar <toofar@spalge.com> | 2024-09-17 18:56:10 +1200 |
commit | 04ac7800e6f366d250b57579b1f440205ff9e002 (patch) | |
tree | 9e2947791ab547bd180bd1da396ce1659123e5a9 | |
parent | 358b6928942f3e8f0d5c90811c875df60c707be8 (diff) | |
download | qutebrowser-feat/8077_remove_tree_code_from_commands.py.tar.gz qutebrowser-feat/8077_remove_tree_code_from_commands.py.zip |
Add common "ensure tree tab" method in commands.pyfeat/8077_remove_tree_code_from_commands.py
There was a few checks of `is_treetabbedbrowser` and repeated errors messages.
I wanted to move them to a common method, but might have overestimated how
many places could use it. There are several tree tab specific arguments that
aren't treated as fatal, for example `tab-give --recursive` and `tab-prev
--sibling`. I'm not sure if they should be fatal or not. There is some value
in defaulting to the non-tree tab behavior if someone wants to use the same
bindings across tree tab and non-tree tab basedirs. There is also value in
being clear that what you've asked for can't be delivered.
If indeed there is only one or two places where we need to complain about an
argument, and not a whole command, then we can moved the magic command name
finding bit into the Command object and just hardcode the command name in the
two places where we want to warn about a specific argument.
There is also the `tree-tab-create-group` command which doesn't bother
checking that yo have a tree tab enabled windows because it doesn't actually
depend on any tree tab features, it's just an alternate to about:blank.
-rw-r--r-- | qutebrowser/browser/commands.py | 61 |
1 files changed, 43 insertions, 18 deletions
diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index e61923e86..29d2fda4d 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -8,6 +8,7 @@ import os.path import shlex import functools import urllib.parse +import inspect from typing import cast, Callable, Dict, Union, Optional from qutebrowser.qt.widgets import QApplication, QTabBar @@ -126,15 +127,11 @@ class CommandDispatcher: tabbed_browser.tabopen(url) tabbed_browser.window().show() elif tab or background: - if tabbed_browser.is_treetabbedbrowser: - tabbed_browser.tabopen(url, background=background, - related=related, sibling=sibling) - elif sibling: - raise cmdutils.CommandError("--sibling flag only works with \ - tree-tab enabled") - else: - tabbed_browser.tabopen(url, background=background, - related=related) + if sibling: + self._ensure_tree_tabs("--sibling") + + tabbed_browser.tabopen(url, background=background, + related=related, sibling=sibling) else: widget = self._current_widget() widget.load_url(url) @@ -1109,7 +1106,8 @@ class CommandDispatcher: assert isinstance(index, str) self._tab_focus_stack(index) return - elif index == 'parent' and self._tabbed_browser.is_treetabbedbrowser: + elif index == 'parent': + self._ensure_tree_tabs("parent") node = self._current_widget().node path = node.path if count: @@ -2053,6 +2051,36 @@ class CommandDispatcher: log.misc.debug('state before fullscreen: {}'.format( debug.qflags_key(Qt, window.state_before_fullscreen))) + def _ensure_tree_tabs(self, arg_name: Optional[str] = None): + """Check if we are on a tree tabs enabled browser.""" + tabbed_browser = self._tabbed_browser + if not self._tabbed_browser.is_treetabbedbrowser: + # Potentially fragile code to get the name of the command the user + # called. Get the calling functions via inspect, lookup the + # command object by looking for a command with the related unbound + # functions as its handler. + # Alternate options: + # 1. stash the cmd object on the function + # 2. duplicate the slugification of the function name (it's just _->-) + # 3. move this check into the Command object somehow (easy for + # disallowed commands, hard for disallowed args) + # 4. save the currently executing command somewhere + bound_func = getattr(self, inspect.stack()[1].function) + cmds = [ + name + for name, cmd + in objects.commands.items() + if cmd.handler == bound_func.__func__ + ] + assert len(cmds) == 1 + cmd_name = cmds[0] + + arg_part = "" + if arg_name: + arg_part = f"argument `{arg_name}` " + msg = f"{cmd_name}: {arg_part}requires a window with tree tabs" + raise cmdutils.CommandError(msg) + @cmdutils.register(instance='command-dispatcher', scope='window', tree_tab=True) @cmdutils.argument('count', value=cmdutils.Value.count) @@ -2065,8 +2093,7 @@ class CommandDispatcher: Args: count: How many levels the tabs should be promoted to """ - if not self._tabbed_browser.is_treetabbedbrowser: - raise cmdutils.CommandError('Tree-tabs are disabled') + self._ensure_tree_tabs() config_position = config.val.tabs.new_position.tree.promote try: self._current_widget().node.promote(count, config_position) @@ -2083,8 +2110,7 @@ class CommandDispatcher: Observes tabs.new_position.tree.demote in positioning the tab among new siblings. """ - if not self._tabbed_browser.is_treetabbedbrowser: - raise cmdutils.CommandError('Tree-tabs are disabled') + self._ensure_tree_tabs() cur_node = self._current_widget().node config_position = config.val.tabs.new_position.tree.demote @@ -2106,8 +2132,7 @@ class CommandDispatcher: Args: count: Which tab to collapse """ - if not self._tabbed_browser.is_treetabbedbrowser: - raise cmdutils.CommandError('Tree-tabs are disabled') + self._ensure_tree_tabs() tab = self._cntwidget(count) if not tab.node.children: return @@ -2124,8 +2149,7 @@ class CommandDispatcher: Args: count: How many levels to hide. """ - if not self._tabbed_browser.is_treetabbedbrowser: - raise cmdutils.CommandError('Tree-tabs are disabled') + self._ensure_tree_tabs() while count > 0: tab = self._current_widget() self._tabbed_browser.cycle_hide_tab(tab.node) @@ -2163,6 +2187,7 @@ class CommandDispatcher: Args: count: Target tab. """ + self._ensure_tree_tabs() tab = self._cntwidget(count) for descendent in tab.node.traverse(): cur_tab = descendent.value |