diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 8050206a5..165823b99 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -28,6 +28,7 @@ Changed ~~~~~~~ - Pasting multiple lines via `:paste` now opens each line in a new tab. +- `:navigate increment/decrement` now preserves leading zeroes in URLs. Fixed ~~~~~ diff --git a/README.asciidoc b/README.asciidoc index 056ae4cbb..d8cd6fb81 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -171,6 +171,7 @@ Contributors, sorted by the number of commits in descending order: * Halfwit * Felix Van der Jeugt * rikn00 +* Michael Ilsaas * Martin Zimmermann * Brian Jackson * sbinix diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py index 2db14a18b..2406ed43a 100644 --- a/qutebrowser/utils/urlutils.py +++ b/qutebrowser/utils/urlutils.py @@ -468,6 +468,28 @@ class IncDecError(Exception): return '{}: {}'.format(self.msg, self.url.toString()) +def _get_incdec_value(match, incdec, url): + """Get a incremented/decremented URL based on a URL match.""" + pre, zeroes, number, post = match.groups() + # This should always succeed because we match \d+ + val = int(number) + if incdec == 'decrement': + if val <= 0: + raise IncDecError("Can't decrement {}!".format(val), url) + val -= 1 + elif incdec == 'increment': + val += 1 + else: + raise ValueError("Invalid value {} for indec!".format(incdec)) + if zeroes: + if len(number) < len(str(val)): + zeroes = zeroes[1:] + elif len(number) > len(str(val)): + zeroes += '0' + + return ''.join([pre, zeroes, str(val), post]) + + def incdec_number(url, incdec, segments=None): """Find a number in the url and increment or decrement it. @@ -509,23 +531,11 @@ def incdec_number(url, incdec, segments=None): continue # Get the last number in a string - match = re.match(r'(.*\D|^)(\d+)(.*)', getter()) + match = re.match(r'(.*\D|^)(0*)(\d+)(.*)', getter()) if not match: continue - pre, number, post = match.groups() - # This should always succeed because we match \d+ - val = int(number) - if incdec == 'decrement': - if val <= 0: - raise IncDecError("Can't decrement {}!".format(val), url) - val -= 1 - elif incdec == 'increment': - val += 1 - else: - raise ValueError("Invalid value {} for indec!".format(incdec)) - new_value = ''.join([pre, str(val), post]) - setter(new_value) + setter(_get_incdec_value(match, incdec, url)) return url raise IncDecError("No number found in URL!", url) diff --git a/tests/unit/utils/test_urlutils.py b/tests/unit/utils/test_urlutils.py index b2ab548b3..707edd704 100644 --- a/tests/unit/utils/test_urlutils.py +++ b/tests/unit/utils/test_urlutils.py @@ -587,6 +587,22 @@ class TestIncDecNumber: base_url, incdec, segments={'host', 'path', 'query', 'anchor'}) assert new_url == expected_url + @pytest.mark.parametrize('number, expected, incdec', [ + ('01', '02', 'increment'), + ('09', '10', 'increment'), + ('009', '010', 'increment'), + ('02', '01', 'decrement'), + ('10', '9', 'decrement'), + ('010', '009', 'decrement') + ]) + def test_incdec_leading_zeroes(self, number, expected, incdec): + """Test incdec_number with leading zeroes.""" + url = 'http://example.com/{}' + base_url = QUrl(url.format(number)) + expected_url = QUrl(url.format(expected)) + new_url = urlutils.incdec_number(base_url, incdec, segments={'path'}) + assert new_url == expected_url + @pytest.mark.parametrize('url, segments, expected', [ ('http://ex4mple.com/test_4?page=3#anchor2', {'host'}, 'http://ex5mple.com/test_4?page=3#anchor2'),