From 3474604dea49381980c27a8d5caabfe3655b165a Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 14:30:02 +0200 Subject: Added simple text widgets to status bar with currently hard-coded content. --- qutebrowser/config/configdata.yml | 1 + qutebrowser/mainwindow/statusbar/bar.py | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index 1c0f03d37..dc8ddd1dc 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -1927,6 +1927,7 @@ statusbar.widgets: - tabs: "Current active tab, e.g. `2`." - keypress: "Display pressed keys when composing a vi command." - progress: "Progress bar for the current page loading." + - text: "A text widget. Currently hard coded content." none_ok: true default: ['keypress', 'url', 'scroll', 'history', 'tabs', 'progress'] desc: List of widgets displayed in the statusbar. diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py index 0f6cd9fbc..54f62f1ad 100644 --- a/qutebrowser/mainwindow/statusbar/bar.py +++ b/qutebrowser/mainwindow/statusbar/bar.py @@ -200,6 +200,7 @@ class StatusBar(QWidget): self.tabindex = tabindex.TabIndex() self.keystring = keystring.KeyString() self.prog = progress.Progress(self) + self.text_widgets = [] self._draw_widgets() config.instance.changed.connect(self._on_config_changed) @@ -222,12 +223,13 @@ class StatusBar(QWidget): # Start with widgets hidden and show them when needed for widget in [self.url, self.percentage, self.backforward, self.tabindex, - self.keystring, self.prog]: + self.keystring, self.prog, *self.text_widgets]: assert isinstance(widget, QWidget) widget.hide() self._hbox.removeWidget(widget) tab = self._current_tab() + text_widget_nr = 0 # Read the list and set widgets accordingly for segment in config.val.statusbar.widgets: @@ -257,6 +259,18 @@ class StatusBar(QWidget): self.prog.enabled = True if tab: self.prog.on_tab_changed(tab) + elif segment == 'text': + try: + cur_widget = self.text_widgets[text_widget_nr] + except IndexError: + cur_widget = textbase.TextBase() + self.text_widgets.append(cur_widget) + cur_widget.setText('Lorem %s' % text_widget_nr) + self._hbox.addWidget(cur_widget) + cur_widget.show() + text_widget_nr += 1 + + del self.text_widgets[text_widget_nr:] @pyqtSlot() def maybe_hide(self): -- cgit v1.2.3-54-g00ecf From 5fa0228a7efc3b8ea64b7002a198d0a22d0c8cd1 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 15:23:53 +0200 Subject: Added configtype StatusbarWidget that can either be one of the valid_values or text:*. --- qutebrowser/config/configdata.yml | 2 +- qutebrowser/config/configtypes.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index dc8ddd1dc..9ceb84173 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -1917,7 +1917,7 @@ statusbar.widgets: type: name: List valtype: - name: String + name: StatusbarWidget valid_values: - url: "Current page URL." - scroll: "Percentage of the current page position like `10%`." diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 49a1f0356..4439cd4f4 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -1996,3 +1996,15 @@ class UrlPattern(BaseType): return urlmatch.UrlPattern(value) except urlmatch.ParseError as e: raise configexc.ValidationError(value, str(e)) + + +class StatusbarWidget(String): + + """A Widget for the status bar. + + Allows some predefined widgets and custom text-widgets via text:$CONTENT.""" + + def _validate_valid_values(self, value: str) -> None: + if value.startswith("text:"): + return + super()._validate_valid_values(value) -- cgit v1.2.3-54-g00ecf From 02a64630aa83e37e47a28a60366e1c65f0eba3ac Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 16:20:14 +0200 Subject: Added configtype to wrap valid prefixes. --- qutebrowser/config/configtypes.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 4439cd4f4..55676207f 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -142,6 +142,27 @@ class ValidValues: self.descriptions == other.descriptions) +class ValidPrefixes(ValidValues): + + def __init__(self, *values, separator: str = ':', **kwargs): + super().__init__(*values, **kwargs) + self.separator = separator + + def __contains__(self, item) -> bool: + return any(map(lambda x: item.startswith(x + self.separator), self.values)) + + def __iter__(self) -> Iterator[str]: + return map(lambda x: x + self.separator, super().__iter__()) + + def __repr__(self) -> str: + return utils.get_repr(self, values=self.values, separator=self.separator, + descriptions=self.descriptions) + + def __eq__(self, other: object) -> bool: + assert (isinstance(other, ValidPrefixes)) + return super().__eq__(other) and self.separator == other.separator + + class BaseType: """A type used for a setting value. -- cgit v1.2.3-54-g00ecf From 525548a2024e1befada8cc939c66c72f00234d76 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 16:21:44 +0200 Subject: Added tests for ValidPrefixes. --- tests/unit/config/test_configtypes.py | 87 +++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index 28c52a1e0..22674c812 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -186,6 +186,93 @@ class TestValidValues: assert vv.descriptions['bar'] == "bar desc" +class TestValidPrefixes: + + @pytest.fixture + def klass(self): + return configtypes.ValidPrefixes + + @pytest.mark.parametrize('valid_values, separator, contained, not_contained', [ + # Without description + (['foo', 'bar'], ':', ['foo:blub'], ['bar.blah', 'baz:blub', 'foo']), + # With description + ([('foo', "foo desc"), ('bar', "bar desc")], '/', ['foo/blub'], + ['bar:blah', 'baz/blub', 'foo']), + # With mixed description + ([('foo', "foo desc"), 'bar'], '.', ['foo.blub'], + ['bar:blah', 'baz.blub', 'foo']), + ]) + def test_contains(self, klass, valid_values, separator, contained, not_contained): + """Test __contains___ with various values.""" + vv = klass(*valid_values, separator=separator) + for elem in contained: + assert elem in vv + for elem in not_contained: + assert elem not in vv + + @pytest.mark.parametrize('valid_values', [ + # With description + ['foo', 'bar'], + [('foo', "foo desc"), ('bar', "bar desc")], + [('foo', "foo desc"), 'bar'], + ]) + def test_iter_without_desc(self, klass, valid_values): + """Test __iter__ without a description.""" + vv = klass(*valid_values) + assert list(vv) == ['foo:', 'bar:'] + + def test_descriptions(self, klass): + """Test descriptions.""" + vv = klass( + ('one-with', "desc 1"), + ('two-with', "desc 2"), + 'three-without', + ('four-without', None) + ) + assert vv.descriptions['one-with'] == "desc 1" + assert vv.descriptions['two-with'] == "desc 2" + assert 'three-without' not in vv.descriptions + assert 'four-without' not in vv.descriptions + + @pytest.mark.parametrize('args, separator, expected', [ + (['a', 'b'], ':', ""), + ([('val', 'desc')], '/', ""), + ]) + def test_repr(self, klass, args, separator, expected): + assert repr(klass(*args, separator=separator)) == expected + + def test_empty(self, klass): + with pytest.raises(ValueError): + klass() + + @pytest.mark.parametrize('args1, args2, is_equal', [ + ((('foo', 'bar'), {}), (('foo', 'bar'), {}), True), + ((('foo', 'bar'), {}), (('foo', 'baz'), {}), False), + ((('foo', 'bar'), {'separator': '/'}), (('foo', 'bar'), {}), False), + (((('foo', 'foo desc'), ('bar', 'bar desc')), {}), + ((('foo', 'foo desc'), ('bar', 'bar desc')), {}), + True), + (((('foo', 'foo desc'), ('bar', 'bar desc')), {}), + ((('foo', 'foo desc'), ('bar', 'bar desc2')), {}), + False), + ]) + def test_equal(self, klass, args1, args2, is_equal): + obj1 = klass(*args1[0], **args1[1]) + obj2 = klass(*args2[0], **args2[1]) + assert (obj1 == obj2) == is_equal + + def test_from_dict(self, klass): + """Test initializing from a list of dicts.""" + vv = klass({'foo': "foo desc"}, {'bar': "bar desc"}) + assert 'foo:blah' in vv + assert 'bar:blub' in vv + assert vv.descriptions['foo'] == "foo desc" + assert vv.descriptions['bar'] == "bar desc" + + class TestAll: """Various tests which apply to all available config types.""" -- cgit v1.2.3-54-g00ecf From aa1c2b6ac2a0d715ac9b413eb469d4a6a698039e Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 16:27:08 +0200 Subject: Reworked StatusbarWidget to use ValidPrefixes. --- qutebrowser/config/configtypes.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 55676207f..0e69be684 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -2025,7 +2025,11 @@ class StatusbarWidget(String): Allows some predefined widgets and custom text-widgets via text:$CONTENT.""" + def __init__(self, *, valid_prefixes: ValidPrefixes = None, **kwargs): + super().__init__(**kwargs) + self.valid_prefixes = valid_prefixes + def _validate_valid_values(self, value: str) -> None: - if value.startswith("text:"): + if value in self.valid_prefixes: return super()._validate_valid_values(value) -- cgit v1.2.3-54-g00ecf From 895d28e0303a17130003e8604a948e7c93fdbcbe Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 16:29:39 +0200 Subject: Renamed configtypes.StatusbarWidget to PrefixOrString to reflect more general use cases. --- qutebrowser/config/configtypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 0e69be684..983e4685c 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -2019,7 +2019,7 @@ class UrlPattern(BaseType): raise configexc.ValidationError(value, str(e)) -class StatusbarWidget(String): +class PrefixOrString(String): """A Widget for the status bar. -- cgit v1.2.3-54-g00ecf From 8cb5a123d1ea8e6b58de1a50705eb5be16553c30 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 16:29:54 +0200 Subject: Added tests for configtypes.PrefixOrString. --- tests/unit/config/test_configtypes.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index 22674c812..158150886 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -2204,6 +2204,23 @@ class TestUrlPattern: klass().to_py('http://') +class TestPrefixOrString: + + @pytest.fixture + def klass(self): + return configtypes.PrefixOrString + + def test_to_py_valid(self, klass): + widget = klass() + widget.valid_values = configtypes.ValidValues('foo') + widget.valid_prefixes = configtypes.ValidPrefixes('bar') + + patterns = ['foo', 'bar:baz'] + + for i in patterns: + assert i == widget.to_py(i) + + @pytest.mark.parametrize('first, second, equal', [ (re.compile('foo'), RegexEq('foo'), True), (RegexEq('bar'), re.compile('bar'), True), -- cgit v1.2.3-54-g00ecf From c3f435820c97f62edcb46da8b807a0b8867d3e71 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 16:31:57 +0200 Subject: Changed type of statusbar.widgets to PrefixOrString. --- qutebrowser/config/configdata.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index 9ceb84173..73fde8471 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -1917,7 +1917,7 @@ statusbar.widgets: type: name: List valtype: - name: StatusbarWidget + name: PrefixOrString valid_values: - url: "Current page URL." - scroll: "Percentage of the current page position like `10%`." -- cgit v1.2.3-54-g00ecf From 84d2a632300ff767ff2f1f68ea1c5bb21037e9a1 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 16:32:19 +0200 Subject: Read valid_prefixes from configdata.yml. --- qutebrowser/config/configdata.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index ec4efc375..8e1be5509 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -105,6 +105,10 @@ def _parse_yaml_type( valid_values = kwargs.get('valid_values', None) if valid_values is not None: kwargs['valid_values'] = configtypes.ValidValues(*valid_values) + + valid_prefixes = kwargs.get('valid_prefixes', None) + if valid_prefixes is not None: + kwargs['valid_prefixes'] = configtypes.ValidPrefixes(*valid_prefixes) else: _raise_invalid_node(name, 'type', node) -- cgit v1.2.3-54-g00ecf From 433883f6baaf6f5da4f7023508fb36d1861868c0 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 16:45:48 +0200 Subject: Add text-prefix to configdata.yml. --- qutebrowser/config/configdata.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index 73fde8471..3e84f2e61 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -1927,7 +1927,8 @@ statusbar.widgets: - tabs: "Current active tab, e.g. `2`." - keypress: "Display pressed keys when composing a vi command." - progress: "Progress bar for the current page loading." - - text: "A text widget. Currently hard coded content." + valid_prefixes: + - text: "A text widget. Add your own text as content." none_ok: true default: ['keypress', 'url', 'scroll', 'history', 'tabs', 'progress'] desc: List of widgets displayed in the statusbar. -- cgit v1.2.3-54-g00ecf From a9f95c72aee2b3abc7b325e194b96188a6524356 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 16:46:03 +0200 Subject: Make bar use content of text widget. --- qutebrowser/mainwindow/statusbar/bar.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py index 54f62f1ad..8a379aa1e 100644 --- a/qutebrowser/mainwindow/statusbar/bar.py +++ b/qutebrowser/mainwindow/statusbar/bar.py @@ -259,13 +259,13 @@ class StatusBar(QWidget): self.prog.enabled = True if tab: self.prog.on_tab_changed(tab) - elif segment == 'text': + elif segment.startswith('text'): try: cur_widget = self.text_widgets[text_widget_nr] except IndexError: cur_widget = textbase.TextBase() self.text_widgets.append(cur_widget) - cur_widget.setText('Lorem %s' % text_widget_nr) + cur_widget.setText(segment.partition(':')[2]) self._hbox.addWidget(cur_widget) cur_widget.show() text_widget_nr += 1 -- cgit v1.2.3-54-g00ecf From f8a34fb7532f6e2880ee0f6f384f836b5dead1e8 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 16:49:35 +0200 Subject: Add getter for valid_prefixes to config BaseType. Will be used for documentation. --- qutebrowser/config/configtypes.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 983e4685c..f03353526 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -184,6 +184,7 @@ class BaseType: self._completions = completions self.none_ok = none_ok self.valid_values: Optional[ValidValues] = None + self.valid_prefixes: Optional[ValidPrefixes] = None def get_name(self) -> str: """Get a name for the type for documentation.""" @@ -193,6 +194,10 @@ class BaseType: """Get the type's valid values for documentation.""" return self.valid_values + def get_valid_prefixes(self) -> Optional[ValidPrefixes]: + """Get the type's valid prefixes for documentation.""" + return self.valid_prefixes + def _basic_py_validation( self, value: Any, pytype: Union[type, Tuple[type, ...]]) -> None: -- cgit v1.2.3-54-g00ecf From cba3054e9f456556450b4b884a75f2f9947a571a Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 16:52:01 +0200 Subject: Add specialized getters for valid prefixes to List and ListOrValue. --- qutebrowser/config/configtypes.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index f03353526..37cd1b68c 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -535,6 +535,9 @@ class List(BaseType): def get_valid_values(self) -> Optional[ValidValues]: return self.valtype.get_valid_values() + def get_valid_prefixes(self) -> Optional[ValidPrefixes]: + return self.valtype.get_valid_prefixes() + def from_str(self, value: str) -> Optional[ListType]: self._basic_str_validation(value) if not value: @@ -640,6 +643,9 @@ class ListOrValue(BaseType): def get_valid_values(self) -> Optional[ValidValues]: return self.valtype.get_valid_values() + def get_valid_prefixes(self) -> Optional[ValidPrefixes]: + return self.valtype.get_valid_prefixes() + def from_str(self, value: str) -> Any: try: return self.listtype.from_str(value) -- cgit v1.2.3-54-g00ecf From 706bdc23270da08f0cd91ab5a71ba1ddf8ce5683 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 16:56:58 +0200 Subject: Added tests for get_valid_prefixes. --- tests/unit/config/test_configtypes.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index 158150886..fd253e692 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -483,6 +483,11 @@ class TestBaseType: basetype.valid_values = configtypes.ValidValues('foo') assert basetype.get_valid_values() is basetype.valid_values + def test_get_valid_prefixes(self, klass): + basetype = klass() + basetype.valid_prefixes = configtypes.ValidPrefixes('foo') + assert basetype.get_valid_prefixes() is basetype.valid_prefixes + @pytest.mark.parametrize('value, expected', [ ('hello', '+pass:[hello]+'), ('', 'empty'), @@ -628,12 +633,14 @@ class ListSubclass(configtypes.List): """ def __init__(self, none_ok_inner=False, none_ok_outer=False, length=None, - elemtype=None, set_valid_values=False): + elemtype=None, set_valid_values=False, set_valid_prefixes=False): if elemtype is None: elemtype = configtypes.String(none_ok=none_ok_inner) super().__init__(elemtype, none_ok=none_ok_outer, length=length) if set_valid_values: self.valtype.valid_values = configtypes.ValidValues('foo', 'bar', 'baz') + if set_valid_prefixes: + self.valtype.valid_prefixes = configtypes.ValidPrefixes('foo', 'bar', 'baz') class FlagListSubclass(configtypes.FlagList): @@ -646,12 +653,15 @@ class FlagListSubclass(configtypes.FlagList): combinable_values = ['foo', 'bar'] def __init__(self, none_ok_inner=False, none_ok_outer=False, length=None, - set_valid_values=False): + set_valid_values=False, set_valid_prefixes=False): # none_ok_inner is ignored, just here for compatibility with TestList super().__init__(none_ok=none_ok_outer, length=length) if set_valid_values: self.valtype.valid_values = configtypes.ValidValues( 'foo', 'bar', 'baz') + if set_valid_prefixes: + self.valtype.valid_prefixes = configtypes.ValidPrefixes( + 'foo', 'bar', 'baz') class FromObjType(configtypes.BaseType): @@ -735,6 +745,10 @@ class TestList: expected = configtypes.ValidValues('foo', 'bar', 'baz') assert klass(set_valid_values=True).get_valid_values() == expected + def test_get_valid_prefixes(self, klass): + expected = configtypes.ValidPrefixes('foo', 'bar', 'baz') + assert klass(set_valid_prefixes=True).get_valid_prefixes() == expected + def test_to_str(self, klass): assert klass().to_str(["a", True]) == '["a", true]' -- cgit v1.2.3-54-g00ecf From 082f7562babfa97affc8823db896c85a8e3e1c93 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 17:16:51 +0200 Subject: Let ValidPrefixes __iter__ fit the keys in descriptions. --- qutebrowser/config/configtypes.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 37cd1b68c..55fc36e83 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -151,9 +151,6 @@ class ValidPrefixes(ValidValues): def __contains__(self, item) -> bool: return any(map(lambda x: item.startswith(x + self.separator), self.values)) - def __iter__(self) -> Iterator[str]: - return map(lambda x: x + self.separator, super().__iter__()) - def __repr__(self) -> str: return utils.get_repr(self, values=self.values, separator=self.separator, descriptions=self.descriptions) -- cgit v1.2.3-54-g00ecf From 55134a0a7c38f9fb1069826b9c86b16fcce433fb Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 17:17:14 +0200 Subject: Added valid_prefixes to documentation creation. --- scripts/dev/src2asciidoc.py | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/scripts/dev/src2asciidoc.py b/scripts/dev/src2asciidoc.py index 82bbdb167..6342a6180 100755 --- a/scripts/dev/src2asciidoc.py +++ b/scripts/dev/src2asciidoc.py @@ -435,6 +435,18 @@ def _generate_setting_backend_info(f, opt): .format(opt.backends)) +def _format_valid_list(f, head, valid_list): + f.write(head) + f.write("\n") + for val in valid_list: + try: + desc = valid_list.descriptions[val] + f.write(" * +{}+: {}".format(val, desc) + "\n") + except KeyError: + f.write(" * +{}+".format(val) + "\n") + f.write("\n") + + def _generate_setting_option(f, opt): """Generate documentation for a single section.""" f.write("\n") @@ -455,15 +467,12 @@ def _generate_setting_option(f, opt): valid_values = opt.typ.get_valid_values() if valid_values is not None and valid_values.generate_docs: - f.write("Valid values:\n") - f.write("\n") - for val in valid_values: - try: - desc = valid_values.descriptions[val] - f.write(" * +{}+: {}".format(val, desc) + "\n") - except KeyError: - f.write(" * +{}+".format(val) + "\n") - f.write("\n") + _format_valid_list(f, "Valid values:\n", valid_values) + + valid_prefixes = opt.typ.get_valid_prefixes() + if valid_prefixes is not None and valid_prefixes.generate_docs: + _format_valid_list(f, "Valid prefixes (separator is +{}+):\n".format( + valid_prefixes.separator), valid_prefixes) f.write("Default: {}\n".format(opt.typ.to_doc(opt.default))) -- cgit v1.2.3-54-g00ecf From 7cf955640e346f8370b3511a0bc8f1ea2a22ffe4 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 17:17:26 +0200 Subject: Update documentation. --- doc/help/settings.asciidoc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index e747b0d75..1d017790a 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -3971,7 +3971,7 @@ Default: +pass:[always]+ === statusbar.widgets List of widgets displayed in the statusbar. -Type: <> +Type: <> Valid values: @@ -3983,6 +3983,10 @@ Valid values: * +keypress+: Display pressed keys when composing a vi command. * +progress+: Progress bar for the current page loading. +Valid prefixes (separator is +:+): + + * +text+: A text widget. Add your own text as content. + Default: - +pass:[keypress]+ @@ -4591,6 +4595,9 @@ When setting from a string, pass a json-like list, e.g. `["one", "two"]`. |Perc|A percentage. |PercOrInt|Percentage or integer. |Position|The position of the tab bar. +|PrefixOrString|A Widget for the status bar. + +Allows some predefined widgets and custom text-widgets via text:$CONTENT. |Proxy|A proxy URL, or `system`/`none`. |QssColor|A color value supporting gradients. -- cgit v1.2.3-54-g00ecf From 4ff204aecc96d77209a18594a14da96af703c43f Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 17:25:23 +0200 Subject: Added documentation generation for valid prefixes to config file generation. --- qutebrowser/config/configfiles.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py index f8566e2d0..78991b5ec 100644 --- a/qutebrowser/config/configfiles.py +++ b/qutebrowser/config/configfiles.py @@ -788,6 +788,15 @@ class ConfigPyWriter: yield self._line("config.load_autoconfig(False)") yield '' + def _gen_valid_list(self, head: str, valid_list) -> Iterator[str]: + yield self._line(head) + for val in valid_list: + try: + desc = valid_list.descriptions[val] + yield self._line("# - {}: {}".format(val, desc)) + except KeyError: + yield self._line("# - {}".format(val)) + def _gen_options(self) -> Iterator[str]: """Generate the options part of the config.""" for pattern, opt, value in self._options: @@ -801,13 +810,13 @@ class ConfigPyWriter: valid_values = opt.typ.get_valid_values() if valid_values is not None and valid_values.generate_docs: - yield self._line("# Valid values:") - for val in valid_values: - try: - desc = valid_values.descriptions[val] - yield self._line("# - {}: {}".format(val, desc)) - except KeyError: - yield self._line("# - {}".format(val)) + yield from self._gen_valid_list('# Valid Values: \n', valid_values) + + valid_prefixes = opt.typ.get_valid_prefixes() + if valid_prefixes is not None and valid_prefixes.generate_docs: + yield from self._gen_valid_list( + '# Valid Prefixes (separator is {}): \n'.format( + valid_prefixes.separator), valid_prefixes) if pattern is None: yield self._line('c.{} = {!r}'.format(opt.name, value)) -- cgit v1.2.3-54-g00ecf From 353bb19cd5e69548f979421d6078f2ea85ad8451 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 17:27:37 +0200 Subject: Simplified code for drawing text widgets. --- qutebrowser/mainwindow/statusbar/bar.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py index 8a379aa1e..1c0ff9a5e 100644 --- a/qutebrowser/mainwindow/statusbar/bar.py +++ b/qutebrowser/mainwindow/statusbar/bar.py @@ -228,8 +228,9 @@ class StatusBar(QWidget): widget.hide() self._hbox.removeWidget(widget) + self.text_widgets.clear() + tab = self._current_tab() - text_widget_nr = 0 # Read the list and set widgets accordingly for segment in config.val.statusbar.widgets: @@ -260,17 +261,11 @@ class StatusBar(QWidget): if tab: self.prog.on_tab_changed(tab) elif segment.startswith('text'): - try: - cur_widget = self.text_widgets[text_widget_nr] - except IndexError: - cur_widget = textbase.TextBase() - self.text_widgets.append(cur_widget) + cur_widget = textbase.TextBase() + self.text_widgets.append(cur_widget) cur_widget.setText(segment.partition(':')[2]) self._hbox.addWidget(cur_widget) cur_widget.show() - text_widget_nr += 1 - - del self.text_widgets[text_widget_nr:] @pyqtSlot() def maybe_hide(self): -- cgit v1.2.3-54-g00ecf From 4bdbdea0946b78d92c3adbb43d03375d1aad63c9 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 17:49:03 +0200 Subject: Revert all prefix-related commits. This reverts commits 02a64630aa83e37e47a28a60366e1c65f0eba3ac to 4ff204aecc96d77209a18594a14da96af703c43f. --- doc/help/settings.asciidoc | 9 +-- qutebrowser/config/configdata.py | 4 -- qutebrowser/config/configdata.yml | 5 +- qutebrowser/config/configfiles.py | 23 ++----- qutebrowser/config/configtypes.py | 37 +---------- scripts/dev/src2asciidoc.py | 27 +++----- tests/unit/config/test_configtypes.py | 122 +--------------------------------- 7 files changed, 23 insertions(+), 204 deletions(-) diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 1d017790a..e747b0d75 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -3971,7 +3971,7 @@ Default: +pass:[always]+ === statusbar.widgets List of widgets displayed in the statusbar. -Type: <> +Type: <> Valid values: @@ -3983,10 +3983,6 @@ Valid values: * +keypress+: Display pressed keys when composing a vi command. * +progress+: Progress bar for the current page loading. -Valid prefixes (separator is +:+): - - * +text+: A text widget. Add your own text as content. - Default: - +pass:[keypress]+ @@ -4595,9 +4591,6 @@ When setting from a string, pass a json-like list, e.g. `["one", "two"]`. |Perc|A percentage. |PercOrInt|Percentage or integer. |Position|The position of the tab bar. -|PrefixOrString|A Widget for the status bar. - -Allows some predefined widgets and custom text-widgets via text:$CONTENT. |Proxy|A proxy URL, or `system`/`none`. |QssColor|A color value supporting gradients. diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 8e1be5509..ec4efc375 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -105,10 +105,6 @@ def _parse_yaml_type( valid_values = kwargs.get('valid_values', None) if valid_values is not None: kwargs['valid_values'] = configtypes.ValidValues(*valid_values) - - valid_prefixes = kwargs.get('valid_prefixes', None) - if valid_prefixes is not None: - kwargs['valid_prefixes'] = configtypes.ValidPrefixes(*valid_prefixes) else: _raise_invalid_node(name, 'type', node) diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index 3e84f2e61..9ceb84173 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -1917,7 +1917,7 @@ statusbar.widgets: type: name: List valtype: - name: PrefixOrString + name: StatusbarWidget valid_values: - url: "Current page URL." - scroll: "Percentage of the current page position like `10%`." @@ -1927,8 +1927,7 @@ statusbar.widgets: - tabs: "Current active tab, e.g. `2`." - keypress: "Display pressed keys when composing a vi command." - progress: "Progress bar for the current page loading." - valid_prefixes: - - text: "A text widget. Add your own text as content." + - text: "A text widget. Currently hard coded content." none_ok: true default: ['keypress', 'url', 'scroll', 'history', 'tabs', 'progress'] desc: List of widgets displayed in the statusbar. diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py index 78991b5ec..f8566e2d0 100644 --- a/qutebrowser/config/configfiles.py +++ b/qutebrowser/config/configfiles.py @@ -788,15 +788,6 @@ class ConfigPyWriter: yield self._line("config.load_autoconfig(False)") yield '' - def _gen_valid_list(self, head: str, valid_list) -> Iterator[str]: - yield self._line(head) - for val in valid_list: - try: - desc = valid_list.descriptions[val] - yield self._line("# - {}: {}".format(val, desc)) - except KeyError: - yield self._line("# - {}".format(val)) - def _gen_options(self) -> Iterator[str]: """Generate the options part of the config.""" for pattern, opt, value in self._options: @@ -810,13 +801,13 @@ class ConfigPyWriter: valid_values = opt.typ.get_valid_values() if valid_values is not None and valid_values.generate_docs: - yield from self._gen_valid_list('# Valid Values: \n', valid_values) - - valid_prefixes = opt.typ.get_valid_prefixes() - if valid_prefixes is not None and valid_prefixes.generate_docs: - yield from self._gen_valid_list( - '# Valid Prefixes (separator is {}): \n'.format( - valid_prefixes.separator), valid_prefixes) + yield self._line("# Valid values:") + for val in valid_values: + try: + desc = valid_values.descriptions[val] + yield self._line("# - {}: {}".format(val, desc)) + except KeyError: + yield self._line("# - {}".format(val)) if pattern is None: yield self._line('c.{} = {!r}'.format(opt.name, value)) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 55fc36e83..4439cd4f4 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -142,24 +142,6 @@ class ValidValues: self.descriptions == other.descriptions) -class ValidPrefixes(ValidValues): - - def __init__(self, *values, separator: str = ':', **kwargs): - super().__init__(*values, **kwargs) - self.separator = separator - - def __contains__(self, item) -> bool: - return any(map(lambda x: item.startswith(x + self.separator), self.values)) - - def __repr__(self) -> str: - return utils.get_repr(self, values=self.values, separator=self.separator, - descriptions=self.descriptions) - - def __eq__(self, other: object) -> bool: - assert (isinstance(other, ValidPrefixes)) - return super().__eq__(other) and self.separator == other.separator - - class BaseType: """A type used for a setting value. @@ -181,7 +163,6 @@ class BaseType: self._completions = completions self.none_ok = none_ok self.valid_values: Optional[ValidValues] = None - self.valid_prefixes: Optional[ValidPrefixes] = None def get_name(self) -> str: """Get a name for the type for documentation.""" @@ -191,10 +172,6 @@ class BaseType: """Get the type's valid values for documentation.""" return self.valid_values - def get_valid_prefixes(self) -> Optional[ValidPrefixes]: - """Get the type's valid prefixes for documentation.""" - return self.valid_prefixes - def _basic_py_validation( self, value: Any, pytype: Union[type, Tuple[type, ...]]) -> None: @@ -532,9 +509,6 @@ class List(BaseType): def get_valid_values(self) -> Optional[ValidValues]: return self.valtype.get_valid_values() - def get_valid_prefixes(self) -> Optional[ValidPrefixes]: - return self.valtype.get_valid_prefixes() - def from_str(self, value: str) -> Optional[ListType]: self._basic_str_validation(value) if not value: @@ -640,9 +614,6 @@ class ListOrValue(BaseType): def get_valid_values(self) -> Optional[ValidValues]: return self.valtype.get_valid_values() - def get_valid_prefixes(self) -> Optional[ValidPrefixes]: - return self.valtype.get_valid_prefixes() - def from_str(self, value: str) -> Any: try: return self.listtype.from_str(value) @@ -2027,17 +1998,13 @@ class UrlPattern(BaseType): raise configexc.ValidationError(value, str(e)) -class PrefixOrString(String): +class StatusbarWidget(String): """A Widget for the status bar. Allows some predefined widgets and custom text-widgets via text:$CONTENT.""" - def __init__(self, *, valid_prefixes: ValidPrefixes = None, **kwargs): - super().__init__(**kwargs) - self.valid_prefixes = valid_prefixes - def _validate_valid_values(self, value: str) -> None: - if value in self.valid_prefixes: + if value.startswith("text:"): return super()._validate_valid_values(value) diff --git a/scripts/dev/src2asciidoc.py b/scripts/dev/src2asciidoc.py index 6342a6180..82bbdb167 100755 --- a/scripts/dev/src2asciidoc.py +++ b/scripts/dev/src2asciidoc.py @@ -435,18 +435,6 @@ def _generate_setting_backend_info(f, opt): .format(opt.backends)) -def _format_valid_list(f, head, valid_list): - f.write(head) - f.write("\n") - for val in valid_list: - try: - desc = valid_list.descriptions[val] - f.write(" * +{}+: {}".format(val, desc) + "\n") - except KeyError: - f.write(" * +{}+".format(val) + "\n") - f.write("\n") - - def _generate_setting_option(f, opt): """Generate documentation for a single section.""" f.write("\n") @@ -467,12 +455,15 @@ def _generate_setting_option(f, opt): valid_values = opt.typ.get_valid_values() if valid_values is not None and valid_values.generate_docs: - _format_valid_list(f, "Valid values:\n", valid_values) - - valid_prefixes = opt.typ.get_valid_prefixes() - if valid_prefixes is not None and valid_prefixes.generate_docs: - _format_valid_list(f, "Valid prefixes (separator is +{}+):\n".format( - valid_prefixes.separator), valid_prefixes) + f.write("Valid values:\n") + f.write("\n") + for val in valid_values: + try: + desc = valid_values.descriptions[val] + f.write(" * +{}+: {}".format(val, desc) + "\n") + except KeyError: + f.write(" * +{}+".format(val) + "\n") + f.write("\n") f.write("Default: {}\n".format(opt.typ.to_doc(opt.default))) diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index fd253e692..28c52a1e0 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -186,93 +186,6 @@ class TestValidValues: assert vv.descriptions['bar'] == "bar desc" -class TestValidPrefixes: - - @pytest.fixture - def klass(self): - return configtypes.ValidPrefixes - - @pytest.mark.parametrize('valid_values, separator, contained, not_contained', [ - # Without description - (['foo', 'bar'], ':', ['foo:blub'], ['bar.blah', 'baz:blub', 'foo']), - # With description - ([('foo', "foo desc"), ('bar', "bar desc")], '/', ['foo/blub'], - ['bar:blah', 'baz/blub', 'foo']), - # With mixed description - ([('foo', "foo desc"), 'bar'], '.', ['foo.blub'], - ['bar:blah', 'baz.blub', 'foo']), - ]) - def test_contains(self, klass, valid_values, separator, contained, not_contained): - """Test __contains___ with various values.""" - vv = klass(*valid_values, separator=separator) - for elem in contained: - assert elem in vv - for elem in not_contained: - assert elem not in vv - - @pytest.mark.parametrize('valid_values', [ - # With description - ['foo', 'bar'], - [('foo', "foo desc"), ('bar', "bar desc")], - [('foo', "foo desc"), 'bar'], - ]) - def test_iter_without_desc(self, klass, valid_values): - """Test __iter__ without a description.""" - vv = klass(*valid_values) - assert list(vv) == ['foo:', 'bar:'] - - def test_descriptions(self, klass): - """Test descriptions.""" - vv = klass( - ('one-with', "desc 1"), - ('two-with', "desc 2"), - 'three-without', - ('four-without', None) - ) - assert vv.descriptions['one-with'] == "desc 1" - assert vv.descriptions['two-with'] == "desc 2" - assert 'three-without' not in vv.descriptions - assert 'four-without' not in vv.descriptions - - @pytest.mark.parametrize('args, separator, expected', [ - (['a', 'b'], ':', ""), - ([('val', 'desc')], '/', ""), - ]) - def test_repr(self, klass, args, separator, expected): - assert repr(klass(*args, separator=separator)) == expected - - def test_empty(self, klass): - with pytest.raises(ValueError): - klass() - - @pytest.mark.parametrize('args1, args2, is_equal', [ - ((('foo', 'bar'), {}), (('foo', 'bar'), {}), True), - ((('foo', 'bar'), {}), (('foo', 'baz'), {}), False), - ((('foo', 'bar'), {'separator': '/'}), (('foo', 'bar'), {}), False), - (((('foo', 'foo desc'), ('bar', 'bar desc')), {}), - ((('foo', 'foo desc'), ('bar', 'bar desc')), {}), - True), - (((('foo', 'foo desc'), ('bar', 'bar desc')), {}), - ((('foo', 'foo desc'), ('bar', 'bar desc2')), {}), - False), - ]) - def test_equal(self, klass, args1, args2, is_equal): - obj1 = klass(*args1[0], **args1[1]) - obj2 = klass(*args2[0], **args2[1]) - assert (obj1 == obj2) == is_equal - - def test_from_dict(self, klass): - """Test initializing from a list of dicts.""" - vv = klass({'foo': "foo desc"}, {'bar': "bar desc"}) - assert 'foo:blah' in vv - assert 'bar:blub' in vv - assert vv.descriptions['foo'] == "foo desc" - assert vv.descriptions['bar'] == "bar desc" - - class TestAll: """Various tests which apply to all available config types.""" @@ -483,11 +396,6 @@ class TestBaseType: basetype.valid_values = configtypes.ValidValues('foo') assert basetype.get_valid_values() is basetype.valid_values - def test_get_valid_prefixes(self, klass): - basetype = klass() - basetype.valid_prefixes = configtypes.ValidPrefixes('foo') - assert basetype.get_valid_prefixes() is basetype.valid_prefixes - @pytest.mark.parametrize('value, expected', [ ('hello', '+pass:[hello]+'), ('', 'empty'), @@ -633,14 +541,12 @@ class ListSubclass(configtypes.List): """ def __init__(self, none_ok_inner=False, none_ok_outer=False, length=None, - elemtype=None, set_valid_values=False, set_valid_prefixes=False): + elemtype=None, set_valid_values=False): if elemtype is None: elemtype = configtypes.String(none_ok=none_ok_inner) super().__init__(elemtype, none_ok=none_ok_outer, length=length) if set_valid_values: self.valtype.valid_values = configtypes.ValidValues('foo', 'bar', 'baz') - if set_valid_prefixes: - self.valtype.valid_prefixes = configtypes.ValidPrefixes('foo', 'bar', 'baz') class FlagListSubclass(configtypes.FlagList): @@ -653,15 +559,12 @@ class FlagListSubclass(configtypes.FlagList): combinable_values = ['foo', 'bar'] def __init__(self, none_ok_inner=False, none_ok_outer=False, length=None, - set_valid_values=False, set_valid_prefixes=False): + set_valid_values=False): # none_ok_inner is ignored, just here for compatibility with TestList super().__init__(none_ok=none_ok_outer, length=length) if set_valid_values: self.valtype.valid_values = configtypes.ValidValues( 'foo', 'bar', 'baz') - if set_valid_prefixes: - self.valtype.valid_prefixes = configtypes.ValidPrefixes( - 'foo', 'bar', 'baz') class FromObjType(configtypes.BaseType): @@ -745,10 +648,6 @@ class TestList: expected = configtypes.ValidValues('foo', 'bar', 'baz') assert klass(set_valid_values=True).get_valid_values() == expected - def test_get_valid_prefixes(self, klass): - expected = configtypes.ValidPrefixes('foo', 'bar', 'baz') - assert klass(set_valid_prefixes=True).get_valid_prefixes() == expected - def test_to_str(self, klass): assert klass().to_str(["a", True]) == '["a", true]' @@ -2218,23 +2117,6 @@ class TestUrlPattern: klass().to_py('http://') -class TestPrefixOrString: - - @pytest.fixture - def klass(self): - return configtypes.PrefixOrString - - def test_to_py_valid(self, klass): - widget = klass() - widget.valid_values = configtypes.ValidValues('foo') - widget.valid_prefixes = configtypes.ValidPrefixes('bar') - - patterns = ['foo', 'bar:baz'] - - for i in patterns: - assert i == widget.to_py(i) - - @pytest.mark.parametrize('first, second, equal', [ (re.compile('foo'), RegexEq('foo'), True), (RegexEq('bar'), re.compile('bar'), True), -- cgit v1.2.3-54-g00ecf From ad847be3b8e2cb2f8eabf7c818d0e6e9b6250331 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 18:16:04 +0200 Subject: Updated the documentation regarding statusbar.widgets. --- doc/help/settings.asciidoc | 6 +++++- qutebrowser/config/configdata.yml | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index e747b0d75..a6a6cd5ff 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -3970,8 +3970,9 @@ Default: +pass:[always]+ [[statusbar.widgets]] === statusbar.widgets List of widgets displayed in the statusbar. +In addition to the listed values there is also the possibility to add `text:foo` widgets that will display `foo`. -Type: <> +Type: <> Valid values: @@ -4607,6 +4608,9 @@ When setting from `config.py`, both a string or a `re.compile(...)` object are v |ShellCommand|A shell command as a list. See the documentation for `List`. +|StatusbarWidget|A Widget for the status bar. + +Allows some predefined widgets and custom text-widgets via text:$CONTENT. |String|A string value. See the setting's valid values for more information on allowed values. diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index 9ceb84173..596c8e1e7 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -1927,10 +1927,13 @@ statusbar.widgets: - tabs: "Current active tab, e.g. `2`." - keypress: "Display pressed keys when composing a vi command." - progress: "Progress bar for the current page loading." - - text: "A text widget. Currently hard coded content." none_ok: true default: ['keypress', 'url', 'scroll', 'history', 'tabs', 'progress'] - desc: List of widgets displayed in the statusbar. + desc: >- + List of widgets displayed in the statusbar. + + In addition to the listed values there is also the possibility + to add `text:foo` widgets that will display `foo`. ## tabs -- cgit v1.2.3-54-g00ecf From 5e0d6e0d3b5126c6e696d97360d069ea751ef2e8 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Thu, 8 Apr 2021 18:29:53 +0200 Subject: Extracted method clearing the widgets from the StatusBar. --- qutebrowser/mainwindow/statusbar/bar.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py index 1c0ff9a5e..32a899742 100644 --- a/qutebrowser/mainwindow/statusbar/bar.py +++ b/qutebrowser/mainwindow/statusbar/bar.py @@ -220,15 +220,7 @@ class StatusBar(QWidget): def _draw_widgets(self): """Draw statusbar widgets.""" - # Start with widgets hidden and show them when needed - for widget in [self.url, self.percentage, - self.backforward, self.tabindex, - self.keystring, self.prog, *self.text_widgets]: - assert isinstance(widget, QWidget) - widget.hide() - self._hbox.removeWidget(widget) - - self.text_widgets.clear() + self._clear_widgets() tab = self._current_tab() @@ -267,6 +259,17 @@ class StatusBar(QWidget): self._hbox.addWidget(cur_widget) cur_widget.show() + def _clear_widgets(self): + """Clear widgets before redrawing them.""" + # Start with widgets hidden and show them when needed + for widget in [self.url, self.percentage, + self.backforward, self.tabindex, + self.keystring, self.prog, *self.text_widgets]: + assert isinstance(widget, QWidget) + widget.hide() + self._hbox.removeWidget(widget) + self.text_widgets.clear() + @pyqtSlot() def maybe_hide(self): """Hide the statusbar if it's configured to do so.""" -- cgit v1.2.3-54-g00ecf From bfc28ba6d0fedac3fab746aeecbe1f3ec85d8978 Mon Sep 17 00:00:00 2001 From: Nicholas42 Date: Thu, 8 Apr 2021 23:58:55 +0200 Subject: Apply suggestions from code review Co-authored-by: Florian Bruhin --- qutebrowser/config/configtypes.py | 5 +++-- qutebrowser/mainwindow/statusbar/bar.py | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 4439cd4f4..c157fba41 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -2000,9 +2000,10 @@ class UrlPattern(BaseType): class StatusbarWidget(String): - """A Widget for the status bar. + """A widget for the status bar. - Allows some predefined widgets and custom text-widgets via text:$CONTENT.""" + Allows some predefined widgets and custom text-widgets via text:$CONTENT. + """ def _validate_valid_values(self, value: str) -> None: if value.startswith("text:"): diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py index 32a899742..19afa5792 100644 --- a/qutebrowser/mainwindow/statusbar/bar.py +++ b/qutebrowser/mainwindow/statusbar/bar.py @@ -200,7 +200,7 @@ class StatusBar(QWidget): self.tabindex = tabindex.TabIndex() self.keystring = keystring.KeyString() self.prog = progress.Progress(self) - self.text_widgets = [] + self._text_widgets = [] self._draw_widgets() config.instance.changed.connect(self._on_config_changed) @@ -252,12 +252,14 @@ class StatusBar(QWidget): self.prog.enabled = True if tab: self.prog.on_tab_changed(tab) - elif segment.startswith('text'): + elif segment.startswith('text:'): cur_widget = textbase.TextBase() self.text_widgets.append(cur_widget) cur_widget.setText(segment.partition(':')[2]) self._hbox.addWidget(cur_widget) cur_widget.show() + else: + raise utils.Unreachable(segment) def _clear_widgets(self): """Clear widgets before redrawing them.""" -- cgit v1.2.3-54-g00ecf From ded3d6c75aea0c405ef64aebacffea4891d971a9 Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Fri, 9 Apr 2021 10:04:36 +0200 Subject: Fixed incomplete renaming of variable. --- qutebrowser/mainwindow/statusbar/bar.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py index 19afa5792..1ad45ad40 100644 --- a/qutebrowser/mainwindow/statusbar/bar.py +++ b/qutebrowser/mainwindow/statusbar/bar.py @@ -254,7 +254,7 @@ class StatusBar(QWidget): self.prog.on_tab_changed(tab) elif segment.startswith('text:'): cur_widget = textbase.TextBase() - self.text_widgets.append(cur_widget) + self._text_widgets.append(cur_widget) cur_widget.setText(segment.partition(':')[2]) self._hbox.addWidget(cur_widget) cur_widget.show() @@ -266,11 +266,11 @@ class StatusBar(QWidget): # Start with widgets hidden and show them when needed for widget in [self.url, self.percentage, self.backforward, self.tabindex, - self.keystring, self.prog, *self.text_widgets]: + self.keystring, self.prog, *self._text_widgets]: assert isinstance(widget, QWidget) widget.hide() self._hbox.removeWidget(widget) - self.text_widgets.clear() + self._text_widgets.clear() @pyqtSlot() def maybe_hide(self): -- cgit v1.2.3-54-g00ecf From d9d9344fbb870d330529e94476b580d108d403d5 Mon Sep 17 00:00:00 2001 From: Nicholas42 Date: Fri, 9 Apr 2021 10:54:22 +0200 Subject: Changed str.partition to str.split. Co-authored-by: Florian Bruhin --- qutebrowser/mainwindow/statusbar/bar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py index 1ad45ad40..8bad290be 100644 --- a/qutebrowser/mainwindow/statusbar/bar.py +++ b/qutebrowser/mainwindow/statusbar/bar.py @@ -255,7 +255,7 @@ class StatusBar(QWidget): elif segment.startswith('text:'): cur_widget = textbase.TextBase() self._text_widgets.append(cur_widget) - cur_widget.setText(segment.partition(':')[2]) + cur_widget.setText(segment.split(':', maxsplit=1)[1]) self._hbox.addWidget(cur_widget) cur_widget.show() else: -- cgit v1.2.3-54-g00ecf From 770d05af1968022ad71b4afbdcbd17552adb2c49 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 8 Apr 2021 19:25:08 +0200 Subject: Fix clicking systray notifications --- qutebrowser/browser/webengine/notification.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/browser/webengine/notification.py b/qutebrowser/browser/webengine/notification.py index 54ab8012e..0f1a59f3f 100644 --- a/qutebrowser/browser/webengine/notification.py +++ b/qutebrowser/browser/webengine/notification.py @@ -466,7 +466,7 @@ class SystrayNotificationAdapter(AbstractNotificationAdapter): @pyqtSlot() def _on_systray_clicked(self) -> None: - self.on_clicked.emit(self.NOTIFICATION_ID) + self.click_id.emit(self.NOTIFICATION_ID) @pyqtSlot(int) def on_web_closed(self, notification_id: int) -> None: -- cgit v1.2.3-54-g00ecf From 628b6cdbb1606061ccde2cf4e1ef88ec59ec8609 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 8 Apr 2021 19:29:42 +0200 Subject: notifications: Add more info to padding assert --- qutebrowser/browser/webengine/notification.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/browser/webengine/notification.py b/qutebrowser/browser/webengine/notification.py index 0f1a59f3f..682d64bdc 100644 --- a/qutebrowser/browser/webengine/notification.py +++ b/qutebrowser/browser/webengine/notification.py @@ -1029,7 +1029,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter): # Source: # https://github.com/dunst-project/dunst/blob/v1.6.1/src/icon.c#L292-L309 padding = bytes_per_line - width * channel_count - assert 0 <= padding < 3, padding + assert 0 <= padding < 3, (padding, bytes_per_line, width, channel_count) size -= padding if padding and self._quirks.no_padded_images: -- cgit v1.2.3-54-g00ecf From f527eacc7564b3387c8dba0a9f3a37840fa6051a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 8 Apr 2021 19:48:29 +0200 Subject: ci: Try working around macOS DMG timeouts --- scripts/dev/Makefile-dmg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dev/Makefile-dmg b/scripts/dev/Makefile-dmg index 3b1a046df..1545318db 100644 --- a/scripts/dev/Makefile-dmg +++ b/scripts/dev/Makefile-dmg @@ -60,7 +60,7 @@ $(MASTER_DMG): $(WC_DMG) $(addprefix $(SOURCE_DIR)/,$(SOURCE_FILES)) #rm -f "$@" #hdiutil create -srcfolder "$(WC_DIR)" -format UDZO -imagekey zlib-level=9 "$@" -volname "$(NAME) $(VERSION)" -scrub -quiet WC_DEV=`hdiutil info | grep "$(WC_DIR)" | grep "Apple_HFS" | awk '{print $$1}'` && \ - hdiutil detach $$WC_DEV -force -debug + hdiutil detach $$WC_DEV -force -debug || true # timeouts on CI sometimes rm -f "$(MASTER_DMG)" hdiutil convert "$(WC_DMG)" -quiet -format UDZO -imagekey zlib-level=9 -o "$@" rm -rf $(WC_DIR) -- cgit v1.2.3-54-g00ecf From 07b7bbe3a3af6a12bcc79a1381377d0265c46276 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 9 Apr 2021 10:03:47 +0200 Subject: ci: Try additional CodeQL queries --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4d97e2acc..71241fb05 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -190,6 +190,7 @@ jobs: uses: github/codeql-action/init@v1 with: languages: javascript, python + queries: +security-and-quality - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 -- cgit v1.2.3-54-g00ecf From 22884268c2b50651960633bc4a5a7255a43cd79e Mon Sep 17 00:00:00 2001 From: Nicholas Schwab Date: Fri, 9 Apr 2021 16:40:51 +0200 Subject: Added tests for StatusbarWidget. --- tests/unit/config/test_configtypes.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py index 28c52a1e0..3e1d15099 100644 --- a/tests/unit/config/test_configtypes.py +++ b/tests/unit/config/test_configtypes.py @@ -2117,6 +2117,24 @@ class TestUrlPattern: klass().to_py('http://') +class TestStatusbarWidget: + + @pytest.fixture + def klass(self): + return configtypes.StatusbarWidget + + @pytest.mark.parametrize('value', ['text:bar', 'foo']) + def test_validate_valid_values(self, klass, value): + widget = klass(valid_values=configtypes.ValidValues('foo')) + assert widget.to_py(value) == value + + @pytest.mark.parametrize('value', ['text', 'foo:bar']) + def test_validate_invalid_values(self, klass, value): + widget = klass(valid_values=configtypes.ValidValues('foo')) + with pytest.raises(configexc.ValidationError): + widget.to_py(value) + + @pytest.mark.parametrize('first, second, equal', [ (re.compile('foo'), RegexEq('foo'), True), (RegexEq('bar'), re.compile('bar'), True), -- cgit v1.2.3-54-g00ecf