From b610563e7fed16f6403925fb5d17eb2f9f9a70a7 Mon Sep 17 00:00:00 2001 From: Ryan Roden-Corrent Date: Sun, 3 Dec 2017 07:32:55 -0500 Subject: [PATCH] Don't show current window for :tab-give/:tab-take. Resolves #3144. --- qutebrowser/browser/commands.py | 2 +- qutebrowser/completion/completer.py | 8 +++-- qutebrowser/completion/models/miscmodels.py | 30 +++++++++++++++--- qutebrowser/mainwindow/mainwindow.py | 2 +- tests/unit/completion/test_completer.py | 2 +- tests/unit/completion/test_models.py | 35 ++++++++++++++++++--- 6 files changed, 65 insertions(+), 14 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 0de903004..bced4daf4 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -518,7 +518,7 @@ class CommandDispatcher: return newtab @cmdutils.register(instance='command-dispatcher', scope='window') - @cmdutils.argument('index', completion=miscmodels.buffer) + @cmdutils.argument('index', completion=miscmodels.other_buffer) def tab_take(self, index): """Take a tab from another window. diff --git a/qutebrowser/completion/completer.py b/qutebrowser/completion/completer.py index bc0e4991f..15c5d7f14 100644 --- a/qutebrowser/completion/completer.py +++ b/qutebrowser/completion/completer.py @@ -35,6 +35,7 @@ class CompletionInfo: config = attr.ib() keyconf = attr.ib() + win_id = attr.ib() class Completer(QObject): @@ -43,6 +44,7 @@ class Completer(QObject): Attributes: _cmd: The statusbar Command object this completer belongs to. + _win_id: The id of the window that owns this object. _timer: The timer used to trigger the completion update. _last_cursor_pos: The old cursor position so we avoid double completion updates. @@ -50,9 +52,10 @@ class Completer(QObject): _last_completion_func: The completion function used for the last text. """ - def __init__(self, cmd, parent=None): + def __init__(self, cmd, win_id, parent=None): super().__init__(parent) self._cmd = cmd + self._win_id = win_id self._timer = QTimer() self._timer.setSingleShot(True) self._timer.setInterval(0) @@ -250,7 +253,8 @@ class Completer(QObject): with debug.log_time(log.completion, 'Starting {} completion'.format(func.__name__)): info = CompletionInfo(config=config.instance, - keyconf=config.key_instance) + keyconf=config.key_instance, + win_id=self._win_id) model = func(*args, info=info) with debug.log_time(log.completion, 'Set completion model'): completion.set_model(model) diff --git a/qutebrowser/completion/models/miscmodels.py b/qutebrowser/completion/models/miscmodels.py index 28ff0ddac..6175dcfb4 100644 --- a/qutebrowser/completion/models/miscmodels.py +++ b/qutebrowser/completion/models/miscmodels.py @@ -94,10 +94,10 @@ def session(*, info=None): # pylint: disable=unused-argument return model -def buffer(*, info=None): # pylint: disable=unused-argument - """A model to complete on open tabs across all windows. - - Used for switching the buffer command. +def _buffer(skip_win_id=None): + """Helper to get the completion model for buffer/other_buffer. + Args: + skip_win_id: The id of the window to skip, or None to include all. """ def delete_buffer(data): """Close the selected tab.""" @@ -109,6 +109,8 @@ def buffer(*, info=None): # pylint: disable=unused-argument model = completionmodel.CompletionModel(column_widths=(6, 40, 54)) for win_id in objreg.window_registry: + if skip_win_id and win_id == skip_win_id: + continue tabbed_browser = objreg.get('tabbed-browser', scope='window', window=win_id) if tabbed_browser.shutting_down: @@ -126,13 +128,31 @@ def buffer(*, info=None): # pylint: disable=unused-argument return model -def window(*, info=None): # pylint: disable=unused-argument +def buffer(*, info=None): # pylint: disable=unused-argument + """A model to complete on open tabs across all windows. + + Used for switching the buffer command. + """ + return _buffer() + + +def other_buffer(*, info): + """A model to complete on open tabs across all windows except the current. + + Used for the tab-take command. + """ + return _buffer(skip_win_id=info.win_id) + + +def window(*, info): """A model to complete on all open windows.""" model = completionmodel.CompletionModel(column_widths=(6, 30, 64)) windows = [] for win_id in objreg.window_registry: + if win_id == info.win_id: + continue tabbed_browser = objreg.get('tabbed-browser', scope='window', window=win_id) tab_titles = (tab.title() for tab in tabbed_browser.widgets()) diff --git a/qutebrowser/mainwindow/mainwindow.py b/qutebrowser/mainwindow/mainwindow.py index bf95d3e6a..5acec2384 100644 --- a/qutebrowser/mainwindow/mainwindow.py +++ b/qutebrowser/mainwindow/mainwindow.py @@ -320,7 +320,7 @@ class MainWindow(QWidget): def _init_completion(self): self._completion = completionwidget.CompletionView(self.win_id, self) cmd = objreg.get('status-command', scope='window', window=self.win_id) - completer_obj = completer.Completer(cmd, self._completion) + completer_obj = completer.Completer(cmd, self.win_id, self._completion) self._completion.selection_changed.connect( completer_obj.on_selection_changed) objreg.register('completion', self._completion, scope='window', diff --git a/tests/unit/completion/test_completer.py b/tests/unit/completion/test_completer.py index a32241621..0e8aabb93 100644 --- a/tests/unit/completion/test_completer.py +++ b/tests/unit/completion/test_completer.py @@ -65,7 +65,7 @@ def completer_obj(qtbot, status_command_stub, config_stub, monkeypatch, stubs, """Create the completer used for testing.""" monkeypatch.setattr(completer, 'QTimer', stubs.InstaTimer) config_stub.val.completion.show = 'auto' - return completer.Completer(status_command_stub, completion_widget_stub) + return completer.Completer(status_command_stub, 0, completion_widget_stub) @pytest.fixture(autouse=True) diff --git a/tests/unit/completion/test_models.py b/tests/unit/completion/test_models.py index 9c767c102..8879f3201 100644 --- a/tests/unit/completion/test_models.py +++ b/tests/unit/completion/test_models.py @@ -191,7 +191,8 @@ def web_history_populated(web_history): @pytest.fixture def info(config_stub, key_config_stub): return completer.CompletionInfo(config=config_stub, - keyconf=key_config_stub) + keyconf=key_config_stub, + win_id=0) def test_command_completion(qtmodeltester, cmdutils_stub, configdata_stub, @@ -581,7 +582,33 @@ def test_tab_completion_delete(qtmodeltester, fake_web_tab, app_stub, QUrl('https://duckduckgo.com')] -def test_window_completion(qtmodeltester, fake_web_tab, tabbed_browser_stubs): +def test_other_buffer_completion(qtmodeltester, fake_web_tab, app_stub, + win_registry, tabbed_browser_stubs, info): + tabbed_browser_stubs[0].tabs = [ + fake_web_tab(QUrl('https://github.com'), 'GitHub', 0), + fake_web_tab(QUrl('https://wikipedia.org'), 'Wikipedia', 1), + fake_web_tab(QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2), + ] + tabbed_browser_stubs[1].tabs = [ + fake_web_tab(QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0), + ] + info.win_id = 1 + model = miscmodels.other_buffer(info=info) + model.set_pattern('') + qtmodeltester.data_display_may_return_none = True + qtmodeltester.check(model) + + _check_completions(model, { + '0': [ + ('0/1', 'https://github.com', 'GitHub'), + ('0/2', 'https://wikipedia.org', 'Wikipedia'), + ('0/3', 'https://duckduckgo.com', 'DuckDuckGo') + ], + }) + + +def test_window_completion(qtmodeltester, fake_web_tab, tabbed_browser_stubs, + info): tabbed_browser_stubs[0].tabs = [ fake_web_tab(QUrl('https://github.com'), 'GitHub', 0), fake_web_tab(QUrl('https://wikipedia.org'), 'Wikipedia', 1), @@ -591,7 +618,8 @@ def test_window_completion(qtmodeltester, fake_web_tab, tabbed_browser_stubs): fake_web_tab(QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0) ] - model = miscmodels.window() + info.win_id = 1 + model = miscmodels.window(info=info) model.set_pattern('') qtmodeltester.data_display_may_return_none = True qtmodeltester.check(model) @@ -600,7 +628,6 @@ def test_window_completion(qtmodeltester, fake_web_tab, tabbed_browser_stubs): 'Windows': [ ('0', 'window title - qutebrowser', 'GitHub, Wikipedia, DuckDuckGo'), - ('1', 'window title - qutebrowser', 'ArchWiki') ] })