From 945bc44550b47489de3eebe619fc260a2c55b239 Mon Sep 17 00:00:00 2001 From: rr- Date: Mon, 9 Apr 2018 17:20:23 +0200 Subject: [PATCH 1/7] Support rapid hinting mode in yanking --- qutebrowser/browser/hints.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py index f7bcd713c..537215275 100644 --- a/qutebrowser/browser/hints.py +++ b/qutebrowser/browser/hints.py @@ -154,6 +154,8 @@ class HintContext: to_follow: The link to follow when enter is pressed. args: Custom arguments for userscript/spawn rapid: Whether to do rapid hinting. + num: While in rapid hinting, count how many times the action + has been executed so far. add_history: Whether to add yanked or spawned link to the history. filterstr: Used to save the filter string for restoring in rapid mode. tab: The WebTab object we started hinting in. @@ -166,6 +168,7 @@ class HintContext: baseurl = attr.ib(None) to_follow = attr.ib(None) rapid = attr.ib(False) + num = attr.ib(0) add_history = attr.ib(False) filterstr = attr.ib(None) args = attr.ib(attr.Factory(list)) @@ -240,7 +243,18 @@ class HintActions: if url.scheme() == 'mailto': flags |= QUrl.RemoveScheme urlstr = url.toString(flags) - utils.set_clipboard(urlstr, selection=sel) + + new_content = urlstr + + # only second and consecutive yanks are to append to the clipboard + if context.rapid and context.num > 1: + try: + old_content = utils.get_clipboard(selection=sel) + except utils.ClipboardEmptyError: + pass + else: + new_content = old_content + '\n' + new_content + utils.set_clipboard(new_content, selection=sel) msg = "Yanked URL to {}: {}".format( "primary selection" if sel else "clipboard", @@ -694,7 +708,8 @@ class HintManager(QObject): if rapid: if target in [Target.tab_bg, Target.window, Target.run, Target.hover, Target.userscript, Target.spawn, - Target.download, Target.normal, Target.current]: + Target.download, Target.normal, Target.current, + Target.yank, Target.yank_primary]: pass elif target == Target.tab and config.val.tabs.background: pass @@ -898,6 +913,7 @@ class HintManager(QObject): else: # Reset filtering self.filter_hints(None) + self._context.num += 1 # Undo keystring highlighting for string, label in self._context.labels.items(): label.update_text('', string) From 46e4aeb3e9ecae65cd157c57678e25740e6836fe Mon Sep 17 00:00:00 2001 From: rr- Date: Tue, 10 Apr 2018 08:45:23 +0200 Subject: [PATCH 2/7] Don't hardcode newline --- qutebrowser/browser/hints.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py index 537215275..01333eff5 100644 --- a/qutebrowser/browser/hints.py +++ b/qutebrowser/browser/hints.py @@ -22,6 +22,7 @@ import collections import functools import math +import os import re import html import enum @@ -253,7 +254,7 @@ class HintActions: except utils.ClipboardEmptyError: pass else: - new_content = old_content + '\n' + new_content + new_content = os.linesep.join([old_content, new_content]) utils.set_clipboard(new_content, selection=sel) msg = "Yanked URL to {}: {}".format( From d705e600e212d4301d071dc7b2deeb60ef02e616 Mon Sep 17 00:00:00 2001 From: rr- Date: Fri, 13 Apr 2018 10:57:17 +0200 Subject: [PATCH 3/7] Simplify `num` in hinting to `first_run` --- qutebrowser/browser/hints.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py index 01333eff5..5e6e4064f 100644 --- a/qutebrowser/browser/hints.py +++ b/qutebrowser/browser/hints.py @@ -155,8 +155,7 @@ class HintContext: to_follow: The link to follow when enter is pressed. args: Custom arguments for userscript/spawn rapid: Whether to do rapid hinting. - num: While in rapid hinting, count how many times the action - has been executed so far. + first_run: Whether the action is run for the 1st time in rapid hinting. add_history: Whether to add yanked or spawned link to the history. filterstr: Used to save the filter string for restoring in rapid mode. tab: The WebTab object we started hinting in. @@ -169,7 +168,7 @@ class HintContext: baseurl = attr.ib(None) to_follow = attr.ib(None) rapid = attr.ib(False) - num = attr.ib(0) + first_run = attr.ib(True) add_history = attr.ib(False) filterstr = attr.ib(None) args = attr.ib(attr.Factory(list)) @@ -248,7 +247,7 @@ class HintActions: new_content = urlstr # only second and consecutive yanks are to append to the clipboard - if context.rapid and context.num > 1: + if context.rapid and not context.first_run: try: old_content = utils.get_clipboard(selection=sel) except utils.ClipboardEmptyError: @@ -914,7 +913,6 @@ class HintManager(QObject): else: # Reset filtering self.filter_hints(None) - self._context.num += 1 # Undo keystring highlighting for string, label in self._context.labels.items(): label.update_text('', string) @@ -924,6 +922,8 @@ class HintManager(QObject): except HintingError as e: message.error(str(e)) + self._context.first_run = False + @cmdutils.register(instance='hintmanager', scope='tab', modes=[usertypes.KeyMode.hint]) def follow_hint(self, select=False, keystring=None): From 563d9bd0970b6fe764f2c322d820c189838bfa3a Mon Sep 17 00:00:00 2001 From: rr- Date: Mon, 16 Apr 2018 08:52:06 +0200 Subject: [PATCH 4/7] Fix crash in non-rapid link yanking --- qutebrowser/browser/hints.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py index 5e6e4064f..98f14e4a3 100644 --- a/qutebrowser/browser/hints.py +++ b/qutebrowser/browser/hints.py @@ -922,7 +922,8 @@ class HintManager(QObject): except HintingError as e: message.error(str(e)) - self._context.first_run = False + if self._context is not None: + self._context.first_run = False @cmdutils.register(instance='hintmanager', scope='tab', modes=[usertypes.KeyMode.hint]) From 30d3612a177813eb23558ebe02f26c546069f238 Mon Sep 17 00:00:00 2001 From: rr- Date: Mon, 16 Apr 2018 09:31:36 +0200 Subject: [PATCH 5/7] Add test for rapid yanking --- tests/end2end/features/hints.feature | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/end2end/features/hints.feature b/tests/end2end/features/hints.feature index a1c4d0bde..2399fb372 100644 --- a/tests/end2end/features/hints.feature +++ b/tests/end2end/features/hints.feature @@ -120,6 +120,15 @@ Feature: Using hints And I hint with args "links yank" and follow a Then the clipboard should contain "javascript:window.location.href='/data/hello.txt'" + Scenario: Rapid yanking + When I run :debug-set-fake-clipboard + And I open data/hints/rapid.html + And I hint with args "links yank --rapid" + And I run :follow-hint a + And I run :follow-hint s + And I run :leave-mode + Then the clipboard should contain "http://localhost:(port)/data/hello.txt\nhttp://localhost:(port)/data/hello2.txt" + Scenario: Rapid hinting When I open data/hints/rapid.html in a new tab And I run :tab-only From 537aa22d64838606be2f2b3072f0345aa49a9c3c Mon Sep 17 00:00:00 2001 From: rr- Date: Wed, 18 Apr 2018 11:00:05 +0200 Subject: [PATCH 6/7] Change clipboard mocking --- qutebrowser/utils/utils.py | 2 ++ tests/end2end/features/conftest.py | 2 +- tests/unit/utils/test_utils.py | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/qutebrowser/utils/utils.py b/qutebrowser/utils/utils.py index da1ddf085..4554aef2e 100644 --- a/qutebrowser/utils/utils.py +++ b/qutebrowser/utils/utils.py @@ -510,11 +510,13 @@ def sanitize_filename(name, replacement='_'): def set_clipboard(data, selection=False): """Set the clipboard to some given data.""" + global fake_clipboard if selection and not supports_selection(): raise SelectionUnsupportedError if log_clipboard: what = 'primary selection' if selection else 'clipboard' log.misc.debug("Setting fake {}: {}".format(what, json.dumps(data))) + fake_clipboard = data else: mode = QClipboard.Selection if selection else QClipboard.Clipboard QApplication.clipboard().setText(data, mode=mode) diff --git a/tests/end2end/features/conftest.py b/tests/end2end/features/conftest.py index 4752e2393..d81c40b2a 100644 --- a/tests/end2end/features/conftest.py +++ b/tests/end2end/features/conftest.py @@ -599,7 +599,7 @@ def check_open_tabs(quteproc, request, tabs): r'contain "(?P.*)"')) def clipboard_contains(quteproc, server, what, content): expected = content.replace('(port)', str(server.port)) - expected = expected.replace('\\n', '\n') + expected = expected.replace('\\n', os.linesep) quteproc.wait_for(message='Setting fake {}: {}'.format( what, json.dumps(expected))) diff --git a/tests/unit/utils/test_utils.py b/tests/unit/utils/test_utils.py index df0eb9ecb..ef2b6c8d4 100644 --- a/tests/unit/utils/test_utils.py +++ b/tests/unit/utils/test_utils.py @@ -651,6 +651,7 @@ class TestGetSetClipboard: autospec=True) clipboard = m() clipboard.text.return_value = 'mocked clipboard text' + mocker.patch('qutebrowser.utils.utils.fake_clipboard', None) return clipboard def test_set(self, clipboard_mock, caplog): From 50fa7743baa9565b30d4c02e53151cb623d0bd6a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 10 Jun 2018 17:21:31 +0200 Subject: [PATCH 7/7] Only use OS-specific line separator for hints --- tests/end2end/features/conftest.py | 3 ++- tests/end2end/features/hints.feature | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/end2end/features/conftest.py b/tests/end2end/features/conftest.py index d81c40b2a..8040d84cc 100644 --- a/tests/end2end/features/conftest.py +++ b/tests/end2end/features/conftest.py @@ -599,7 +599,8 @@ def check_open_tabs(quteproc, request, tabs): r'contain "(?P.*)"')) def clipboard_contains(quteproc, server, what, content): expected = content.replace('(port)', str(server.port)) - expected = expected.replace('\\n', os.linesep) + expected = expected.replace('\\n', '\n') + expected = expected.replace('(linesep)', os.linesep) quteproc.wait_for(message='Setting fake {}: {}'.format( what, json.dumps(expected))) diff --git a/tests/end2end/features/hints.feature b/tests/end2end/features/hints.feature index 2399fb372..f31094bc2 100644 --- a/tests/end2end/features/hints.feature +++ b/tests/end2end/features/hints.feature @@ -127,7 +127,7 @@ Feature: Using hints And I run :follow-hint a And I run :follow-hint s And I run :leave-mode - Then the clipboard should contain "http://localhost:(port)/data/hello.txt\nhttp://localhost:(port)/data/hello2.txt" + Then the clipboard should contain "http://localhost:(port)/data/hello.txt(linesep)http://localhost:(port)/data/hello2.txt" Scenario: Rapid hinting When I open data/hints/rapid.html in a new tab