From d3e4d62d14bf6aa8aafed7d709afaf8ca3ced162 Mon Sep 17 00:00:00 2001 From: Peter Rice Date: Mon, 15 Aug 2016 21:09:15 -0400 Subject: [PATCH 1/6] make navigate take counts for inc, dec, and up --- qutebrowser/browser/commands.py | 5 +++-- qutebrowser/browser/navigate.py | 11 ++++++----- qutebrowser/utils/urlutils.py | 10 +++++----- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 2964b6113..5438b29a0 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -482,7 +482,8 @@ class CommandDispatcher: @cmdutils.register(instance='command-dispatcher', scope='window') @cmdutils.argument('where', choices=['prev', 'next', 'up', 'increment', 'decrement']) - def navigate(self, where: str, tab=False, bg=False, window=False): + @cmdutils.argument('count', count=True) + def navigate(self, where: str, tab=False, bg=False, window=False, count=1): """Open typical prev/next links or navigate using the URL path. This tries to automatically click on typical _Previous Page_ or @@ -526,7 +527,7 @@ class CommandDispatcher: handler(browsertab=widget, win_id=self._win_id, baseurl=url, tab=tab, background=bg, window=window) elif where in ['up', 'increment', 'decrement']: - new_url = handlers[where](url) + new_url = handlers[where](url, count) self._open(new_url, tab, bg, window) else: # pragma: no cover raise ValueError("Got called with invalid value {} for " diff --git a/qutebrowser/browser/navigate.py b/qutebrowser/browser/navigate.py index 86e7eeb77..2d5b0aab3 100644 --- a/qutebrowser/browser/navigate.py +++ b/qutebrowser/browser/navigate.py @@ -31,7 +31,7 @@ class Error(Exception): """Raised when the navigation can't be done.""" -def incdec(url, inc_or_dec): +def incdec(url, count, inc_or_dec): """Helper method for :navigate when `where' is increment/decrement. Args: @@ -43,13 +43,13 @@ def incdec(url, inc_or_dec): """ segments = set(config.get('general', 'url-incdec-segments')) try: - new_url = urlutils.incdec_number(url, inc_or_dec, segments=segments) + new_url = urlutils.incdec_number(url, inc_or_dec, count, segments=segments) except urlutils.IncDecError as error: raise Error(error.msg) return new_url -def path_up(url): +def path_up(url, count): """Helper method for :navigate when `where' is up. Args: @@ -58,8 +58,9 @@ def path_up(url): path = url.path() if not path or path == '/': raise Error("Can't go up!") - new_path = posixpath.join(path, posixpath.pardir) - url.setPath(new_path) + for i in range(0, min(count, path.count('/'))): + path = posixpath.join(path, posixpath.pardir) + url.setPath(path) return url diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py index 2fe465aa4..d37a2772e 100644 --- a/qutebrowser/utils/urlutils.py +++ b/qutebrowser/utils/urlutils.py @@ -499,7 +499,7 @@ class IncDecError(Exception): return '{}: {}'.format(self.msg, self.url.toString()) -def _get_incdec_value(match, incdec, url): +def _get_incdec_value(match, incdec, url, count): """Get an incremented/decremented URL based on a URL match.""" pre, zeroes, number, post = match.groups() # This should always succeed because we match \d+ @@ -507,9 +507,9 @@ def _get_incdec_value(match, incdec, url): if incdec == 'decrement': if val <= 0: raise IncDecError("Can't decrement {}!".format(val), url) - val -= 1 + val -= count elif incdec == 'increment': - val += 1 + val += count else: raise ValueError("Invalid value {} for indec!".format(incdec)) if zeroes: @@ -521,7 +521,7 @@ def _get_incdec_value(match, incdec, url): return ''.join([pre, zeroes, str(val), post]) -def incdec_number(url, incdec, segments=None): +def incdec_number(url, incdec, count=1, segments=None): """Find a number in the url and increment or decrement it. Args: @@ -566,7 +566,7 @@ def incdec_number(url, incdec, segments=None): if not match: continue - setter(_get_incdec_value(match, incdec, url)) + setter(_get_incdec_value(match, incdec, url, count)) return url raise IncDecError("No number found in URL!", url) From 060305279cf90c95d2f5e348f547b5f4be561dda Mon Sep 17 00:00:00 2001 From: Peter Rice Date: Mon, 15 Aug 2016 21:22:22 -0400 Subject: [PATCH 2/6] update navigate-related help and function docs --- doc/help/commands.asciidoc | 3 +++ qutebrowser/browser/commands.py | 2 ++ qutebrowser/browser/navigate.py | 2 ++ qutebrowser/utils/urlutils.py | 1 + 4 files changed, 8 insertions(+) diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index 4a90783f8..4f9451ded 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -480,6 +480,9 @@ This tries to automatically click on typical _Previous Page_ or _Next Page_ link * +*-b*+, +*--bg*+: Open in a background tab. * +*-w*+, +*--window*+: Open in a new window. +==== count +For `increment` and `decrement`, the number to change the URL by. For `up`, the number of levels to go up in the URL. + [[open]] === open Syntax: +:open [*--implicit*] [*--bg*] [*--tab*] [*--window*] ['url']+ diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 5438b29a0..04a15fabb 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -503,6 +503,8 @@ class CommandDispatcher: tab: Open in a new tab. bg: Open in a background tab. window: Open in a new window. + count: How much to increment or decrement the URL by, or number of + levels to go up in the current URL. """ # save the pre-jump position in the special ' mark self.set_mark("'") diff --git a/qutebrowser/browser/navigate.py b/qutebrowser/browser/navigate.py index 2d5b0aab3..0a7328047 100644 --- a/qutebrowser/browser/navigate.py +++ b/qutebrowser/browser/navigate.py @@ -36,6 +36,7 @@ def incdec(url, count, inc_or_dec): Args: url: The current url. + count: How much to increment or decrement by. inc_or_dec: Either 'increment' or 'decrement'. tab: Whether to open the link in a new tab. background: Open the link in a new background tab. @@ -54,6 +55,7 @@ def path_up(url, count): Args: url: The current url. + count: The number of levels to go up in the url. """ path = url.path() if not path or path == '/': diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py index d37a2772e..7e1b8ea9e 100644 --- a/qutebrowser/utils/urlutils.py +++ b/qutebrowser/utils/urlutils.py @@ -527,6 +527,7 @@ def incdec_number(url, incdec, count=1, segments=None): Args: url: The current url incdec: Either 'increment' or 'decrement' + count: The number to increment or decrement by segments: A set of URL segments to search. Valid segments are: 'host', 'path', 'query', 'anchor'. Default: {'path', 'query'} From d4c16aa3c7d88ace4c3278be109f69058befe006 Mon Sep 17 00:00:00 2001 From: Peter Rice Date: Mon, 15 Aug 2016 22:29:26 -0400 Subject: [PATCH 3/6] add a test for incdec with a count --- tests/unit/utils/test_urlutils.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/unit/utils/test_urlutils.py b/tests/unit/utils/test_urlutils.py index af0e62ed3..f5d8c9bdc 100644 --- a/tests/unit/utils/test_urlutils.py +++ b/tests/unit/utils/test_urlutils.py @@ -620,6 +620,32 @@ class TestIncDecNumber: base_url, incdec, segments={'host', 'path', 'query', 'anchor'}) assert new_url == expected_url + @pytest.mark.parametrize('incdec', ['increment', 'decrement']) + @pytest.mark.parametrize('value', [ + '{}foo', 'foo{}', 'foo{}bar', '42foo{}' + ]) + @pytest.mark.parametrize('url', [ + 'http://example.com:80/v1/path/{}/test', + 'http://example.com:80/v1/query_test?value={}', + 'http://example.com:80/v1/anchor_test#{}', + 'http://host_{}_test.com:80', + 'http://m4ny.c0m:80/number5/3very?where=yes#{}' + ]) + @pytest.mark.parametrize('count', [1, 5, 100]) + def test_incdec_number_count(self, incdec, value, url, count): + """Test incdec_number with valid URLs and a count.""" + base_value = value.format(20) + if incdec == 'increment': + expected_value = value.format(20 + count) + else: + expected_value = value.format(20 - count) + + base_url = QUrl(url.format(base_value)) + expected_url = QUrl(url.format(expected_value)) + new_url = urlutils.incdec_number( + base_url, incdec, count, segments={'host', 'path', 'query', 'anchor'}) + assert new_url == expected_url + @pytest.mark.parametrize('number, expected, incdec', [ ('01', '02', 'increment'), ('09', '10', 'increment'), From 67609af21ba04969e2783ecfa661392bc6daf5f7 Mon Sep 17 00:00:00 2001 From: Peter Rice Date: Mon, 15 Aug 2016 22:43:49 -0400 Subject: [PATCH 4/6] resolve linter warnings --- qutebrowser/browser/navigate.py | 5 +++-- tests/unit/utils/test_urlutils.py | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/qutebrowser/browser/navigate.py b/qutebrowser/browser/navigate.py index 0a7328047..12492e673 100644 --- a/qutebrowser/browser/navigate.py +++ b/qutebrowser/browser/navigate.py @@ -44,7 +44,8 @@ def incdec(url, count, inc_or_dec): """ segments = set(config.get('general', 'url-incdec-segments')) try: - new_url = urlutils.incdec_number(url, inc_or_dec, count, segments=segments) + new_url = urlutils.incdec_number(url, inc_or_dec, count, + segments=segments) except urlutils.IncDecError as error: raise Error(error.msg) return new_url @@ -60,7 +61,7 @@ def path_up(url, count): path = url.path() if not path or path == '/': raise Error("Can't go up!") - for i in range(0, min(count, path.count('/'))): + for _i in range(0, min(count, path.count('/'))): path = posixpath.join(path, posixpath.pardir) url.setPath(path) return url diff --git a/tests/unit/utils/test_urlutils.py b/tests/unit/utils/test_urlutils.py index f5d8c9bdc..e036c4b9e 100644 --- a/tests/unit/utils/test_urlutils.py +++ b/tests/unit/utils/test_urlutils.py @@ -643,7 +643,8 @@ class TestIncDecNumber: base_url = QUrl(url.format(base_value)) expected_url = QUrl(url.format(expected_value)) new_url = urlutils.incdec_number( - base_url, incdec, count, segments={'host', 'path', 'query', 'anchor'}) + base_url, incdec, count, + segments={'host', 'path', 'query', 'anchor'}) assert new_url == expected_url @pytest.mark.parametrize('number, expected, incdec', [ From ad9dfc198139492bc7430c6a3e4cd90ff7c04b97 Mon Sep 17 00:00:00 2001 From: Peter Rice Date: Tue, 16 Aug 2016 04:28:31 -0400 Subject: [PATCH 5/6] add end-to-end tests for navigating with a count --- tests/end2end/features/navigate.feature | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/end2end/features/navigate.feature b/tests/end2end/features/navigate.feature index c43ff1c18..1041fcdee 100644 --- a/tests/end2end/features/navigate.feature +++ b/tests/end2end/features/navigate.feature @@ -11,6 +11,11 @@ Feature: Using :navigate And I run :navigate up Then data/navigate should be loaded + Scenario: Navigating up by count + When I open data/navigate/sub/index.html + And I run :navigate up with count 2 + Then data/navigate should be loaded + # prev/next Scenario: Navigating to previous page @@ -60,6 +65,16 @@ Feature: Using :navigate And I run :navigate increment Then the error "No number found in URL!" should be shown + Scenario: Incrementing number in URL by count + When I open data/numbers/3.txt + And I run :navigate increment with count 3 + Then data/numbers/6.txt should be loaded + + Scenario: Decrementing number in URL by count + When I open data/numbers/8.txt + And I run :navigate decrement with count 5 + Then data/numbers/3.txt should be loaded + Scenario: Setting url-incdec-segments When I set general -> url-incdec-segments to anchor And I open data/numbers/1.txt From d1138fa34272c4fbc847c0fd83b51ffdebc350f7 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 16 Aug 2016 11:22:29 +0200 Subject: [PATCH 6/6] Update docs --- CHANGELOG.asciidoc | 1 + README.asciidoc | 1 + doc/help/commands.asciidoc | 1 + qutebrowser/browser/commands.py | 4 ++-- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 007b86fd9..a17ac2031 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -67,6 +67,7 @@ Changed - Completions for `:help` and `:bind` now also show hidden commands - The `:buffer` completion now also filters using the first column (id). - `:undo` has been improved to reopen tabs at the position they were closed. +- `:navigate` now takes a count for `up`/`increment`/`decrement`. Deprecated ~~~~~~~~~~ diff --git a/README.asciidoc b/README.asciidoc index 9d4b8d986..420c5cc21 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -183,6 +183,7 @@ Contributors, sorted by the number of commits in descending order: * skinnay * Zach-Button * Tomasz Kramkowski +* Peter Rice * Ismail S * Halfwit * David Vogt diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc index b6b8ac8d9..1b93a2d65 100644 --- a/doc/help/commands.asciidoc +++ b/doc/help/commands.asciidoc @@ -484,6 +484,7 @@ This tries to automatically click on typical _Previous Page_ or _Next Page_ link ==== count For `increment` and `decrement`, the number to change the URL by. For `up`, the number of levels to go up in the URL. + [[open]] === open Syntax: +:open [*--implicit*] [*--bg*] [*--tab*] [*--window*] ['url']+ diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 03bf0a3d0..e13651b23 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -505,8 +505,8 @@ class CommandDispatcher: tab: Open in a new tab. bg: Open in a background tab. window: Open in a new window. - count: How much to increment or decrement the URL by, or number of - levels to go up in the current URL. + count: For `increment` and `decrement`, the number to change the URL + by. For `up`, the number of levels to go up in the URL. """ # save the pre-jump position in the special ' mark self.set_mark("'")