From f654013372d9165a979a52e6e2eb9a0ec7f866e3 Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Mon, 27 Jun 2016 17:38:11 +0200 Subject: [PATCH 01/16] Add repeat-command (.) command --- qutebrowser/browser/commands.py | 14 ++++++++++++++ qutebrowser/commands/runners.py | 11 ++++++++++- qutebrowser/config/configdata.py | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index eb2f31575..8acfea948 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1972,3 +1972,17 @@ class CommandDispatcher: key: mark identifier; capital indicates a global mark """ self._tabbed_browser.jump_mark(key) + + @cmdutils.register(instance='command-dispatcher', scope='window') + @cmdutils.argument('count', count=True) + def repeat_command(self, count=None): + """Repeat the last executed command, like '.' in vi. + + Args: + count: Which numeric argument to give the command. + """ + if runners._last_command == None: + raise cmdexc.CommandError("You didn't do anything yet.") + runners.CommandRunner(self._win_id).run( + runners._last_command[0], + count if count != None else runners._last_command[1]) diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index 2d9668467..375a0e035 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -26,12 +26,13 @@ from PyQt5.QtCore import pyqtSlot, QUrl, QObject from qutebrowser.config import config, configexc from qutebrowser.commands import cmdexc, cmdutils -from qutebrowser.utils import message, log, objreg, qtutils +from qutebrowser.utils import message, log, objreg, qtutils, usertypes from qutebrowser.misc import split ParseResult = collections.namedtuple('ParseResult', ['cmd', 'args', 'cmdline', 'count']) +_last_command = None def _current_url(tabbed_browser): @@ -285,6 +286,14 @@ class CommandRunner(QObject): else: result.cmd.run(self._win_id, args) + if (result.cmdline[0] != 'repeat-command' and + (result.cmd._modes == None or + usertypes.KeyMode.normal in result.cmd._modes) and + (result.cmd._not_modes == None or + usertypes.KeyMode.normal not in result.cmd._not_modes)): + global _last_command + _last_command = (text, count) + @pyqtSlot(str, int) @pyqtSlot(str) def run_safely(self, text, count=None): diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 5feec1e92..ecd3fdc9c 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -1550,6 +1550,7 @@ KEY_DATA = collections.OrderedDict([ ('open qute:settings', ['Ss']), ('follow-selected', RETURN_KEYS), ('follow-selected -t', ['', '']), + ('repeat-command', ['.']), ])), ('insert', collections.OrderedDict([ From 81f25251a54f929650ac3b47381c2ab4160838da Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Mon, 27 Jun 2016 18:21:35 +0200 Subject: [PATCH 02/16] Fix singleton-comparison --- qutebrowser/browser/commands.py | 4 ++-- qutebrowser/commands/runners.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 8acfea948..95f69e663 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1981,8 +1981,8 @@ class CommandDispatcher: Args: count: Which numeric argument to give the command. """ - if runners._last_command == None: + if runners._last_command is None: raise cmdexc.CommandError("You didn't do anything yet.") runners.CommandRunner(self._win_id).run( runners._last_command[0], - count if count != None else runners._last_command[1]) + count if count is not None else runners._last_command[1]) diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index 375a0e035..7581ae719 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -287,9 +287,9 @@ class CommandRunner(QObject): result.cmd.run(self._win_id, args) if (result.cmdline[0] != 'repeat-command' and - (result.cmd._modes == None or + (result.cmd._modes is None or usertypes.KeyMode.normal in result.cmd._modes) and - (result.cmd._not_modes == None or + (result.cmd._not_modes is None or usertypes.KeyMode.normal not in result.cmd._not_modes)): global _last_command _last_command = (text, count) From 7a6d26ef869b3c49268dc6698bec0d22a2bd89c8 Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Mon, 27 Jun 2016 18:40:47 +0200 Subject: [PATCH 03/16] Fix protected-access for last_command (not sure what to do for _modes and _not_modes) --- qutebrowser/browser/commands.py | 6 +++--- qutebrowser/commands/runners.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 95f69e663..f3d1f2a85 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1981,8 +1981,8 @@ class CommandDispatcher: Args: count: Which numeric argument to give the command. """ - if runners._last_command is None: + if runners.last_command is None: raise cmdexc.CommandError("You didn't do anything yet.") runners.CommandRunner(self._win_id).run( - runners._last_command[0], - count if count is not None else runners._last_command[1]) + runners.last_command[0], + count if count is not None else runners.last_command[1]) diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index 7581ae719..414a0d8a3 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -32,7 +32,7 @@ from qutebrowser.misc import split ParseResult = collections.namedtuple('ParseResult', ['cmd', 'args', 'cmdline', 'count']) -_last_command = None +last_command = None def _current_url(tabbed_browser): @@ -291,8 +291,8 @@ class CommandRunner(QObject): usertypes.KeyMode.normal in result.cmd._modes) and (result.cmd._not_modes is None or usertypes.KeyMode.normal not in result.cmd._not_modes)): - global _last_command - _last_command = (text, count) + global last_command + last_command = (text, count) @pyqtSlot(str, int) @pyqtSlot(str) From cc1899ebca95f6928c7ce91a5e56cadb3fa7d57d Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Wed, 29 Jun 2016 20:29:56 +0200 Subject: [PATCH 04/16] Add tests for repeat-command, make compatible with different count methods --- qutebrowser/commands/runners.py | 3 +- tests/end2end/features/repeatcommand.feature | 34 +++++++++++++++++++ .../features/test_repeatcommand_bbd.py | 21 ++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 tests/end2end/features/repeatcommand.feature create mode 100644 tests/end2end/features/test_repeatcommand_bbd.py diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index 414a0d8a3..22a715d15 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -292,7 +292,8 @@ class CommandRunner(QObject): (result.cmd._not_modes is None or usertypes.KeyMode.normal not in result.cmd._not_modes)): global last_command - last_command = (text, count) + last_command = (self._parse_count(text)[1], + count if count is not None else result.count) @pyqtSlot(str, int) @pyqtSlot(str) diff --git a/tests/end2end/features/repeatcommand.feature b/tests/end2end/features/repeatcommand.feature new file mode 100644 index 000000000..1e8cc83ff --- /dev/null +++ b/tests/end2end/features/repeatcommand.feature @@ -0,0 +1,34 @@ +Feature: Repeating + Test the repeat-command command. + + Background: + Given I run :tab-only + + Scenario: :repeat-command + When I open data/numbers/1.txt + And I open data/numbers/2.txt in a new tab + And I open data/numbers/3.txt in a new tab + And I run :tab-close with count 1 + And I run :repeat-command + Then the following tabs should be open: + - data/numbers/3.txt (active) + + Scenario: :repeat-command with count + When I open data/numbers/1.txt + And I open data/numbers/2.txt in a new tab + And I open data/numbers/3.txt in a new tab + And I run :tab-close with count 1 + And I run :repeat-command with count 2 + Then the following tabs should be open: + - data/numbers/2.txt (active) + + Scenario: :repeat-command with not-normal command inbetween + When I open data/numbers/1.txt + And I open data/numbers/2.txt in a new tab + And I open data/numbers/3.txt in a new tab + And I run :tab-close with count 1 + And I run :prompt-accept + And I run :repeat-command + Then the following tabs should be open: + - data/numbers/3.txt (active) + And the error "prompt-accept: This command is only allowed in prompt/yesno mode." should be shown diff --git a/tests/end2end/features/test_repeatcommand_bbd.py b/tests/end2end/features/test_repeatcommand_bbd.py new file mode 100644 index 000000000..d6c063ade --- /dev/null +++ b/tests/end2end/features/test_repeatcommand_bbd.py @@ -0,0 +1,21 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2016 Jan Verbeek (blyxxyz) +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +import pytest_bdd as bdd +bdd.scenarios('repeatcommand.feature') From f9afa190b1eff5f5f17faa0ada0dd520eb072fb4 Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Wed, 29 Jun 2016 20:58:29 +0200 Subject: [PATCH 05/16] Handle check for allowed mode better --- qutebrowser/commands/command.py | 9 +++++++++ qutebrowser/commands/runners.py | 5 +---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/qutebrowser/commands/command.py b/qutebrowser/commands/command.py index 41d97481c..034039479 100644 --- a/qutebrowser/commands/command.py +++ b/qutebrowser/commands/command.py @@ -502,3 +502,12 @@ class Command: log.commands.debug('Calling {}'.format( debug_utils.format_call(self.handler, posargs, kwargs))) self.handler(*posargs, **kwargs) + + def mode_allowed(self, mode): + """Check if the command can be run in the given mode. + + Args: + mode: The mode to check. + """ + return ((self._modes is None or mode in self._modes) and + (self._not_modes is None or mode not in self._not_modes)) diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index 22a715d15..78f691191 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -287,10 +287,7 @@ class CommandRunner(QObject): result.cmd.run(self._win_id, args) if (result.cmdline[0] != 'repeat-command' and - (result.cmd._modes is None or - usertypes.KeyMode.normal in result.cmd._modes) and - (result.cmd._not_modes is None or - usertypes.KeyMode.normal not in result.cmd._not_modes)): + result.cmd.mode_allowed(usertypes.KeyMode.normal)): global last_command last_command = (self._parse_count(text)[1], count if count is not None else result.count) From 64731c2053c546a15093b39a81eb0a26ad7ea100 Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Wed, 29 Jun 2016 21:23:42 +0200 Subject: [PATCH 06/16] Fix confusing indent --- qutebrowser/commands/runners.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index 78f691191..4fc80f630 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -287,7 +287,7 @@ class CommandRunner(QObject): result.cmd.run(self._win_id, args) if (result.cmdline[0] != 'repeat-command' and - result.cmd.mode_allowed(usertypes.KeyMode.normal)): + result.cmd.mode_allowed(usertypes.KeyMode.normal)): global last_command last_command = (self._parse_count(text)[1], count if count is not None else result.count) From 320b9cac3fd97ab0a99549003993713ce5176e5e Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Thu, 30 Jun 2016 02:22:02 +0200 Subject: [PATCH 07/16] Move repeat-command, make it work with multiple modes, improve tests --- qutebrowser/browser/commands.py | 14 -------- qutebrowser/commands/runners.py | 11 +++--- qutebrowser/misc/utilcmds.py | 16 +++++++++ tests/end2end/features/misc.feature | 23 +++++++++++++ tests/end2end/features/repeatcommand.feature | 34 ------------------- tests/end2end/features/test_misc_bdd.py | 1 + .../features/test_repeatcommand_bbd.py | 21 ------------ 7 files changed, 47 insertions(+), 73 deletions(-) delete mode 100644 tests/end2end/features/repeatcommand.feature delete mode 100644 tests/end2end/features/test_repeatcommand_bbd.py diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index f3d1f2a85..eb2f31575 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1972,17 +1972,3 @@ class CommandDispatcher: key: mark identifier; capital indicates a global mark """ self._tabbed_browser.jump_mark(key) - - @cmdutils.register(instance='command-dispatcher', scope='window') - @cmdutils.argument('count', count=True) - def repeat_command(self, count=None): - """Repeat the last executed command, like '.' in vi. - - Args: - count: Which numeric argument to give the command. - """ - if runners.last_command is None: - raise cmdexc.CommandError("You didn't do anything yet.") - runners.CommandRunner(self._win_id).run( - runners.last_command[0], - count if count is not None else runners.last_command[1]) diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index 4fc80f630..b9ab0b6c4 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -32,7 +32,7 @@ from qutebrowser.misc import split ParseResult = collections.namedtuple('ParseResult', ['cmd', 'args', 'cmdline', 'count']) -last_command = None +last_command = {} def _current_url(tabbed_browser): @@ -286,11 +286,14 @@ class CommandRunner(QObject): else: result.cmd.run(self._win_id, args) + mode_manager = objreg.get('mode-manager', scope='window', + window=self._win_id) if (result.cmdline[0] != 'repeat-command' and - result.cmd.mode_allowed(usertypes.KeyMode.normal)): + result.cmd.mode_allowed(mode_manager.mode)): global last_command - last_command = (self._parse_count(text)[1], - count if count is not None else result.count) + last_command[mode_manager.mode] = ( + self._parse_count(text)[1], + count if count is not None else result.count) @pyqtSlot(str, int) @pyqtSlot(str) diff --git a/qutebrowser/misc/utilcmds.py b/qutebrowser/misc/utilcmds.py index 1de004c90..9996913e5 100644 --- a/qutebrowser/misc/utilcmds.py +++ b/qutebrowser/misc/utilcmds.py @@ -217,3 +217,19 @@ def debug_set_fake_clipboard(s=None): utils.log_clipboard = True else: utils.fake_clipboard = s + +@cmdutils.register() +@cmdutils.argument('win_id', win_id=True) +@cmdutils.argument('count', count=True) +def repeat_command(win_id, count=None): + """Repeat the last executed command, like '.' in vi. + Args: + count: Which numeric argument to give the command. + """ + mode_manager = objreg.get('mode-manager', scope='window', + window=win_id) + if mode_manager.mode not in runners.last_command: + raise cmdexc.CommandError("You didn't do anything yet.") + cmd = runners.last_command[mode_manager.mode] + commandrunner = runners.CommandRunner(win_id) + commandrunner.run(cmd[0], count if count is not None else cmd[1]) diff --git a/tests/end2end/features/misc.feature b/tests/end2end/features/misc.feature index bd54960bd..e11d87121 100644 --- a/tests/end2end/features/misc.feature +++ b/tests/end2end/features/misc.feature @@ -464,3 +464,26 @@ Feature: Various utility commands. And I wait until cookies is loaded And I open cookies in a new tab Then the cookie qute-test should be set to 42 + + Scenario: :repeat-command + Given I open data/scroll.html + When I run :scroll down + And I run :repeat-command + And I run :scroll up + Then the page should be scrolled vertically + + Scenario: :repeat-command with count + Given I open data/scroll.html + When I run :scroll down with count 3 + And I run :scroll up + And I run :repeat-command with count 2 + Then the page should not be scrolled + + Scenario: :repeat-command with not-normal command inbetween + Given I open data/scroll.html + When I run :scroll down with count 3 + And I run :scroll up + And I run :prompt-accept + And I run :repeat-command with count 2 + Then the page should not be scrolled + And the error "prompt-accept: This command is only allowed in prompt/yesno mode." should be shown diff --git a/tests/end2end/features/repeatcommand.feature b/tests/end2end/features/repeatcommand.feature deleted file mode 100644 index 1e8cc83ff..000000000 --- a/tests/end2end/features/repeatcommand.feature +++ /dev/null @@ -1,34 +0,0 @@ -Feature: Repeating - Test the repeat-command command. - - Background: - Given I run :tab-only - - Scenario: :repeat-command - When I open data/numbers/1.txt - And I open data/numbers/2.txt in a new tab - And I open data/numbers/3.txt in a new tab - And I run :tab-close with count 1 - And I run :repeat-command - Then the following tabs should be open: - - data/numbers/3.txt (active) - - Scenario: :repeat-command with count - When I open data/numbers/1.txt - And I open data/numbers/2.txt in a new tab - And I open data/numbers/3.txt in a new tab - And I run :tab-close with count 1 - And I run :repeat-command with count 2 - Then the following tabs should be open: - - data/numbers/2.txt (active) - - Scenario: :repeat-command with not-normal command inbetween - When I open data/numbers/1.txt - And I open data/numbers/2.txt in a new tab - And I open data/numbers/3.txt in a new tab - And I run :tab-close with count 1 - And I run :prompt-accept - And I run :repeat-command - Then the following tabs should be open: - - data/numbers/3.txt (active) - And the error "prompt-accept: This command is only allowed in prompt/yesno mode." should be shown diff --git a/tests/end2end/features/test_misc_bdd.py b/tests/end2end/features/test_misc_bdd.py index 443583166..03c1f0ff1 100644 --- a/tests/end2end/features/test_misc_bdd.py +++ b/tests/end2end/features/test_misc_bdd.py @@ -29,6 +29,7 @@ import qutebrowser from qutebrowser.utils import docutils from qutebrowser.browser import pdfjs +from end2end.features.test_scroll_bdd import check_scrolled, check_not_scrolled bdd.scenarios('misc.feature') diff --git a/tests/end2end/features/test_repeatcommand_bbd.py b/tests/end2end/features/test_repeatcommand_bbd.py deleted file mode 100644 index d6c063ade..000000000 --- a/tests/end2end/features/test_repeatcommand_bbd.py +++ /dev/null @@ -1,21 +0,0 @@ -# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: - -# Copyright 2016 Jan Verbeek (blyxxyz) -# -# This file is part of qutebrowser. -# -# qutebrowser is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# qutebrowser is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with qutebrowser. If not, see . - -import pytest_bdd as bdd -bdd.scenarios('repeatcommand.feature') From 2ab1d35a7c2a6496c1f45b7356c4cfd28b6781cc Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Thu, 30 Jun 2016 03:13:40 +0200 Subject: [PATCH 08/16] Remove useless import and global declaration, add missing whitespace --- qutebrowser/commands/runners.py | 3 +-- qutebrowser/misc/utilcmds.py | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index b9ab0b6c4..5d2453560 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -26,7 +26,7 @@ from PyQt5.QtCore import pyqtSlot, QUrl, QObject from qutebrowser.config import config, configexc from qutebrowser.commands import cmdexc, cmdutils -from qutebrowser.utils import message, log, objreg, qtutils, usertypes +from qutebrowser.utils import message, log, objreg, qtutils from qutebrowser.misc import split @@ -290,7 +290,6 @@ class CommandRunner(QObject): window=self._win_id) if (result.cmdline[0] != 'repeat-command' and result.cmd.mode_allowed(mode_manager.mode)): - global last_command last_command[mode_manager.mode] = ( self._parse_count(text)[1], count if count is not None else result.count) diff --git a/qutebrowser/misc/utilcmds.py b/qutebrowser/misc/utilcmds.py index 9996913e5..2e4ad21bf 100644 --- a/qutebrowser/misc/utilcmds.py +++ b/qutebrowser/misc/utilcmds.py @@ -218,11 +218,13 @@ def debug_set_fake_clipboard(s=None): else: utils.fake_clipboard = s + @cmdutils.register() @cmdutils.argument('win_id', win_id=True) @cmdutils.argument('count', count=True) def repeat_command(win_id, count=None): """Repeat the last executed command, like '.' in vi. + Args: count: Which numeric argument to give the command. """ From 9678fd1e09334fac726e02a0bc5dbad767356144 Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Fri, 1 Jul 2016 19:17:50 +0200 Subject: [PATCH 09/16] Make argument description more clear + style fix --- qutebrowser/misc/utilcmds.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qutebrowser/misc/utilcmds.py b/qutebrowser/misc/utilcmds.py index 2e4ad21bf..948f1ca0e 100644 --- a/qutebrowser/misc/utilcmds.py +++ b/qutebrowser/misc/utilcmds.py @@ -226,10 +226,9 @@ def repeat_command(win_id, count=None): """Repeat the last executed command, like '.' in vi. Args: - count: Which numeric argument to give the command. + count: Which count to pass the command. """ - mode_manager = objreg.get('mode-manager', scope='window', - window=win_id) + mode_manager = objreg.get('mode-manager', scope='window', window=win_id) if mode_manager.mode not in runners.last_command: raise cmdexc.CommandError("You didn't do anything yet.") cmd = runners.last_command[mode_manager.mode] From 4172e3904577ebc63bc6aece5939e6f712580174 Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Sat, 2 Jul 2016 01:42:47 +0200 Subject: [PATCH 10/16] Move :repeat-command tests to scroll.feature --- tests/end2end/features/misc.feature | 23 ----------------------- tests/end2end/features/scroll.feature | 20 ++++++++++++++++++++ tests/end2end/features/test_misc_bdd.py | 2 -- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/tests/end2end/features/misc.feature b/tests/end2end/features/misc.feature index e11d87121..bd54960bd 100644 --- a/tests/end2end/features/misc.feature +++ b/tests/end2end/features/misc.feature @@ -464,26 +464,3 @@ Feature: Various utility commands. And I wait until cookies is loaded And I open cookies in a new tab Then the cookie qute-test should be set to 42 - - Scenario: :repeat-command - Given I open data/scroll.html - When I run :scroll down - And I run :repeat-command - And I run :scroll up - Then the page should be scrolled vertically - - Scenario: :repeat-command with count - Given I open data/scroll.html - When I run :scroll down with count 3 - And I run :scroll up - And I run :repeat-command with count 2 - Then the page should not be scrolled - - Scenario: :repeat-command with not-normal command inbetween - Given I open data/scroll.html - When I run :scroll down with count 3 - And I run :scroll up - And I run :prompt-accept - And I run :repeat-command with count 2 - Then the page should not be scrolled - And the error "prompt-accept: This command is only allowed in prompt/yesno mode." should be shown diff --git a/tests/end2end/features/scroll.feature b/tests/end2end/features/scroll.feature index 676cd0890..508a2c2e5 100644 --- a/tests/end2end/features/scroll.feature +++ b/tests/end2end/features/scroll.feature @@ -241,3 +241,23 @@ Feature: Scrolling When I open data/hello.txt And I run :scroll-page 1 1 Then no crash should happen + + Scenario: :repeat-command + When I run :scroll down + And I run :repeat-command + And I run :scroll up + Then the page should be scrolled vertically + + Scenario: :repeat-command with count + When I run :scroll down with count 3 + And I run :scroll up + And I run :repeat-command with count 2 + Then the page should not be scrolled + + Scenario: :repeat-command with not-normal command inbetween + When I run :scroll down with count 3 + And I run :scroll up + And I run :prompt-accept + And I run :repeat-command with count 2 + Then the page should not be scrolled + And the error "prompt-accept: This command is only allowed in prompt/yesno mode." should be shown diff --git a/tests/end2end/features/test_misc_bdd.py b/tests/end2end/features/test_misc_bdd.py index 03c1f0ff1..35bf6753e 100644 --- a/tests/end2end/features/test_misc_bdd.py +++ b/tests/end2end/features/test_misc_bdd.py @@ -29,8 +29,6 @@ import qutebrowser from qutebrowser.utils import docutils from qutebrowser.browser import pdfjs -from end2end.features.test_scroll_bdd import check_scrolled, check_not_scrolled - bdd.scenarios('misc.feature') From 8039e7ab74cc1486a55e1e3c6507046b06b40994 Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Sun, 3 Jul 2016 22:32:07 +0200 Subject: [PATCH 11/16] Move :repeat-command tests --- tests/end2end/features/conftest.py | 25 ++++++++++++++++++++++ tests/end2end/features/misc.feature | 26 +++++++++++++++++++++++ tests/end2end/features/scroll.feature | 20 ----------------- tests/end2end/features/test_scroll_bdd.py | 25 ---------------------- 4 files changed, 51 insertions(+), 45 deletions(-) diff --git a/tests/end2end/features/conftest.py b/tests/end2end/features/conftest.py index 9d1d5c074..c97318ca9 100644 --- a/tests/end2end/features/conftest.py +++ b/tests/end2end/features/conftest.py @@ -492,3 +492,28 @@ def clipboard_contains_multiline(quteproc, httpbin, content): @bdd.then("qutebrowser should quit") def should_quit(qtbot, quteproc): quteproc.wait_for_quit() + + +def _get_scroll_values(quteproc): + data = quteproc.get_session() + pos = data['windows'][0]['tabs'][0]['history'][0]['scroll-pos'] + return (pos['x'], pos['y']) + + +@bdd.then(bdd.parsers.re(r"the page should be scrolled " + r"(?Phorizontally|vertically)")) +def check_scrolled(quteproc, direction): + x, y = _get_scroll_values(quteproc) + if direction == 'horizontally': + assert x != 0 + assert y == 0 + else: + assert x == 0 + assert y != 0 + + +@bdd.then("the page should not be scrolled") +def check_not_scrolled(quteproc): + x, y = _get_scroll_values(quteproc) + assert x == 0 + assert y == 0 diff --git a/tests/end2end/features/misc.feature b/tests/end2end/features/misc.feature index bd54960bd..8f458f1a3 100644 --- a/tests/end2end/features/misc.feature +++ b/tests/end2end/features/misc.feature @@ -464,3 +464,29 @@ Feature: Various utility commands. And I wait until cookies is loaded And I open cookies in a new tab Then the cookie qute-test should be set to 42 + + Scenario: :repeat-command + Given I open data/scroll.html + And I run :tab-only + When I run :scroll down + And I run :repeat-command + And I run :scroll up + Then the page should be scrolled vertically + + Scenario: :repeat-command with count + Given I open data/scroll.html + And I run :tab-only + When I run :scroll down with count 3 + And I run :scroll up + And I run :repeat-command with count 2 + Then the page should not be scrolled + + Scenario: :repeat-command with not-normal command inbetween + Given I open data/scroll.html + And I run :tab-only + When I run :scroll down with count 3 + And I run :scroll up + And I run :prompt-accept + And I run :repeat-command with count 2 + Then the page should not be scrolled + And the error "prompt-accept: This command is only allowed in prompt/yesno mode." should be shown diff --git a/tests/end2end/features/scroll.feature b/tests/end2end/features/scroll.feature index 508a2c2e5..676cd0890 100644 --- a/tests/end2end/features/scroll.feature +++ b/tests/end2end/features/scroll.feature @@ -241,23 +241,3 @@ Feature: Scrolling When I open data/hello.txt And I run :scroll-page 1 1 Then no crash should happen - - Scenario: :repeat-command - When I run :scroll down - And I run :repeat-command - And I run :scroll up - Then the page should be scrolled vertically - - Scenario: :repeat-command with count - When I run :scroll down with count 3 - And I run :scroll up - And I run :repeat-command with count 2 - Then the page should not be scrolled - - Scenario: :repeat-command with not-normal command inbetween - When I run :scroll down with count 3 - And I run :scroll up - And I run :prompt-accept - And I run :repeat-command with count 2 - Then the page should not be scrolled - And the error "prompt-accept: This command is only allowed in prompt/yesno mode." should be shown diff --git a/tests/end2end/features/test_scroll_bdd.py b/tests/end2end/features/test_scroll_bdd.py index 7ea63936e..de1ed3e0a 100644 --- a/tests/end2end/features/test_scroll_bdd.py +++ b/tests/end2end/features/test_scroll_bdd.py @@ -19,28 +19,3 @@ import pytest_bdd as bdd bdd.scenarios('scroll.feature') - - -def _get_scroll_values(quteproc): - data = quteproc.get_session() - pos = data['windows'][0]['tabs'][0]['history'][0]['scroll-pos'] - return (pos['x'], pos['y']) - - -@bdd.then(bdd.parsers.re(r"the page should be scrolled " - r"(?Phorizontally|vertically)")) -def check_scrolled(quteproc, direction): - x, y = _get_scroll_values(quteproc) - if direction == 'horizontally': - assert x != 0 - assert y == 0 - else: - assert x == 0 - assert y != 0 - - -@bdd.then("the page should not be scrolled") -def check_not_scrolled(quteproc): - x, y = _get_scroll_values(quteproc) - assert x == 0 - assert y == 0 From 955478799bf8cc0349ff085118c7ff59431b34f2 Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Mon, 4 Jul 2016 13:39:00 +0200 Subject: [PATCH 12/16] Shorten repeat-command description, remove .i, .o If .i and .o exist there's a delay before . gets accepted. --- qutebrowser/config/configdata.py | 2 -- qutebrowser/misc/utilcmds.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index ecd3fdc9c..225828429 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -1463,10 +1463,8 @@ KEY_DATA = collections.OrderedDict([ ('hint all hover', [';h']), ('hint images', [';i']), ('hint images tab', [';I']), - ('hint images tab-bg', ['.i']), ('hint links fill ":open {hint-url}"', [';o']), ('hint links fill ":open -t {hint-url}"', [';O']), - ('hint links fill ":open -b {hint-url}"', ['.o']), ('hint links yank', [';y']), ('hint links yank-primary', [';Y']), ('hint --rapid links tab-bg', [';r']), diff --git a/qutebrowser/misc/utilcmds.py b/qutebrowser/misc/utilcmds.py index 948f1ca0e..e420f2f76 100644 --- a/qutebrowser/misc/utilcmds.py +++ b/qutebrowser/misc/utilcmds.py @@ -223,7 +223,7 @@ def debug_set_fake_clipboard(s=None): @cmdutils.argument('win_id', win_id=True) @cmdutils.argument('count', count=True) def repeat_command(win_id, count=None): - """Repeat the last executed command, like '.' in vi. + """Repeat the last executed command. Args: count: Which count to pass the command. From 508c0f21fa5ac1cbc41bb76609af72cbd8d85cf9 Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Tue, 12 Jul 2016 00:23:34 +0200 Subject: [PATCH 13/16] Blacklist prompt-accept, remove mode_allowed --- qutebrowser/commands/command.py | 9 --------- qutebrowser/commands/runners.py | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/qutebrowser/commands/command.py b/qutebrowser/commands/command.py index 034039479..41d97481c 100644 --- a/qutebrowser/commands/command.py +++ b/qutebrowser/commands/command.py @@ -502,12 +502,3 @@ class Command: log.commands.debug('Calling {}'.format( debug_utils.format_call(self.handler, posargs, kwargs))) self.handler(*posargs, **kwargs) - - def mode_allowed(self, mode): - """Check if the command can be run in the given mode. - - Args: - mode: The mode to check. - """ - return ((self._modes is None or mode in self._modes) and - (self._not_modes is None or mode not in self._not_modes)) diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index 5d2453560..f3dba8665 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -289,7 +289,7 @@ class CommandRunner(QObject): mode_manager = objreg.get('mode-manager', scope='window', window=self._win_id) if (result.cmdline[0] != 'repeat-command' and - result.cmd.mode_allowed(mode_manager.mode)): + result.cmdline[0] != 'prompt-accept'): last_command[mode_manager.mode] = ( self._parse_count(text)[1], count if count is not None else result.count) From ee4b24a5dca89b7e91f22fd250206ea52b471f22 Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Tue, 12 Jul 2016 11:03:36 +0200 Subject: [PATCH 14/16] Blacklist leave-mode, use "not in" --- qutebrowser/commands/runners.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index f3dba8665..10dd9d8c4 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -288,8 +288,8 @@ class CommandRunner(QObject): mode_manager = objreg.get('mode-manager', scope='window', window=self._win_id) - if (result.cmdline[0] != 'repeat-command' and - result.cmdline[0] != 'prompt-accept'): + if result.cmdline[0] not in ['leave-mode', 'prompt-accept', + 'repeat-command']: last_command[mode_manager.mode] = ( self._parse_count(text)[1], count if count is not None else result.count) From cafe7181c781770d10009d076265996e1b042173 Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Tue, 12 Jul 2016 16:48:33 +0200 Subject: [PATCH 15/16] Blacklist command-accept, hide repeat-command prompt-accept was blacklisted instead of command-accept. --- qutebrowser/commands/runners.py | 2 +- qutebrowser/misc/utilcmds.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index 10dd9d8c4..80782d504 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -288,7 +288,7 @@ class CommandRunner(QObject): mode_manager = objreg.get('mode-manager', scope='window', window=self._win_id) - if result.cmdline[0] not in ['leave-mode', 'prompt-accept', + if result.cmdline[0] not in ['leave-mode', 'command-accept', 'repeat-command']: last_command[mode_manager.mode] = ( self._parse_count(text)[1], diff --git a/qutebrowser/misc/utilcmds.py b/qutebrowser/misc/utilcmds.py index e420f2f76..e1d7c6a61 100644 --- a/qutebrowser/misc/utilcmds.py +++ b/qutebrowser/misc/utilcmds.py @@ -219,7 +219,7 @@ def debug_set_fake_clipboard(s=None): utils.fake_clipboard = s -@cmdutils.register() +@cmdutils.register(hide=True) @cmdutils.argument('win_id', win_id=True) @cmdutils.argument('count', count=True) def repeat_command(win_id, count=None): From 13cbdbb8bd8353a93563616ccb3a02abbf6f9217 Mon Sep 17 00:00:00 2001 From: Jan Verbeek Date: Wed, 13 Jul 2016 15:24:45 +0200 Subject: [PATCH 16/16] Record mode for :repeat-command before executing --- qutebrowser/commands/runners.py | 11 ++++++----- tests/end2end/features/misc.feature | 12 ++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py index 80782d504..edb3720f9 100644 --- a/qutebrowser/commands/runners.py +++ b/qutebrowser/commands/runners.py @@ -275,6 +275,10 @@ class CommandRunner(QObject): count: The count to pass to the command. """ for result in self.parse_all(text): + mode_manager = objreg.get('mode-manager', scope='window', + window=self._win_id) + cur_mode = mode_manager.mode + args = replace_variables(self._win_id, result.args) if count is not None: if result.count is not None: @@ -286,11 +290,8 @@ class CommandRunner(QObject): else: result.cmd.run(self._win_id, args) - mode_manager = objreg.get('mode-manager', scope='window', - window=self._win_id) - if result.cmdline[0] not in ['leave-mode', 'command-accept', - 'repeat-command']: - last_command[mode_manager.mode] = ( + if result.cmdline[0] != 'repeat-command': + last_command[cur_mode] = ( self._parse_count(text)[1], count if count is not None else result.count) diff --git a/tests/end2end/features/misc.feature b/tests/end2end/features/misc.feature index 8f458f1a3..50c36715a 100644 --- a/tests/end2end/features/misc.feature +++ b/tests/end2end/features/misc.feature @@ -490,3 +490,15 @@ Feature: Various utility commands. And I run :repeat-command with count 2 Then the page should not be scrolled And the error "prompt-accept: This command is only allowed in prompt/yesno mode." should be shown + + Scenario: :repeat-command with mode-switching command + Given I open data/hints/link_blank.html + And I run :tab-only + When I run :hint + And I run :leave-mode + And I run :repeat-command + And I run :follow-hint a + And I wait until data/hello.txt is loaded + Then the following tabs should be open: + - data/hints/link_blank.html + - data/hello.txt (active)