Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace hints.uppercase with hints.labels #7661

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions doc/help/settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@
|<<hints.dictionary,hints.dictionary>>|Dictionary file to be used by the word hints.
|<<hints.find_implementation,hints.find_implementation>>|Which implementation to use to find elements to hint.
|<<hints.hide_unmatched_rapid_hints,hints.hide_unmatched_rapid_hints>>|Hide unmatched hints in rapid mode.
|<<hints.labels,hints.labels>>|Labels for hint characters.
|<<hints.leave_on_load,hints.leave_on_load>>|Leave hint mode when starting a new page load.
|<<hints.min_chars,hints.min_chars>>|Minimum number of characters used for hint strings.
|<<hints.mode,hints.mode>>|Mode to use for hints.
Expand All @@ -263,7 +264,6 @@
|<<hints.radius,hints.radius>>|Rounding radius (in pixels) for the edges of hints.
|<<hints.scatter,hints.scatter>>|Scatter hint key chains (like Vimium) or not (like dwb).
|<<hints.selectors,hints.selectors>>|CSS selectors used to determine which elements on a page should have hints.
|<<hints.uppercase,hints.uppercase>>|Make characters in hint strings uppercase.
|<<history_gap_interval,history_gap_interval>>|Maximum time (in minutes) between two history items for them to be considered being from the same browsing session.
|<<input.escape_quits_reporter,input.escape_quits_reporter>>|Allow Escape to quit the crash reporter.
|<<input.forward_unbound_keys,input.forward_unbound_keys>>|Which unbound keys to forward to the webview in normal mode.
Expand Down Expand Up @@ -3356,6 +3356,15 @@ Type: <<types,Bool>>

Default: +pass:[true]+

[[hints.labels]]
=== hints.labels
Labels for hint characters.
To replace the deprecated `hints.uppercase` setting set `c.hints.labels = c.hints.chars.upper()` in `config.py`.

Type: <<types,UniqueCharString>>

Default: empty

[[hints.leave_on_load]]
=== hints.leave_on_load
Leave hint mode when starting a new page load.
Expand Down Expand Up @@ -3523,14 +3532,6 @@ Default:
* +pass:[[src\]]+
* +pass:[[href\]]+

[[hints.uppercase]]
=== hints.uppercase
Make characters in hint strings uppercase.

Type: <<types,Bool>>

Default: +pass:[false]+

[[history_gap_interval]]
=== history_gap_interval
Maximum time (in minutes) between two history items for them to be considered being from the same browsing session.
Expand Down
9 changes: 6 additions & 3 deletions qutebrowser/browser/hints.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,13 @@ def update_text(self, matched: str, unmatched: str) -> None:
matched: The part of the text which was typed.
unmatched: The part of the text which was not typed yet.
"""
if (config.cache['hints.uppercase'] and
if (config.cache['hints.labels'] and
self._context.hint_mode in ['letter', 'word']):
matched = html.escape(matched.upper())
unmatched = html.escape(unmatched.upper())
chars = config.val.hints.chars
labels = config.val.hints.labels
table = str.maketrans(dict(zip(chars, labels)))
matched = html.escape(matched.translate(table))
unmatched = html.escape(unmatched.translate(table))
else:
matched = html.escape(matched)
unmatched = html.escape(unmatched)
Expand Down
21 changes: 16 additions & 5 deletions qutebrowser/config/configdata.yml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the description is sufficient here. I only understand it because I have read the discussion leading to this feature. Also, I would assume that most users do not use a config.py and setting one up to preserve the previous functionality seems a bit too much IMHO. Couldn't we use some special value that would be interpreted as hints.chars.upper()?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

People can always just set it to ASDFGHJKL (assuming hints.chars set to asdfghjkl) - in fact, that's what the config migration does too!

Yeah, it's a bit cumbersome because you need to change things at two places - but at the same time, having a special <upper> value or whatever seems weird to me as well.

As for the description, what would you suggest? Would something like a "For every character in hints.chars, the character of this setting at the same position will be shown as the corresponding hint text." or so suffice?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah maybe the description could be more concrete. I think the line proposed by @The-Compiler is good and descriptive, but I'll throw my hat into the ring: "In hint text, characters of this settings will be shown instead of characters of hints.chars." A little less descriptive, but a bit more concise.

Original file line number Diff line number Diff line change
Expand Up @@ -1621,9 +1621,25 @@ hints.chars:
completions:
- ['asdfghjkl', "Home row"]
- ['aoeuidnths', "Home row (Dvorak)"]
- ['hjkl', "Directional keys (Vim)"]
- ['hjklyubn', "Directional keys (roguelike)"]
- ['abcdefghijklmnopqrstuvwxyz', "All letters"]
desc: Characters used for hint strings.

hints.labels:
default:
type:
name: UniqueCharString
none_ok: true
completions:
- ['←↓↑→', "Arrows for directional keys (Vim)"]
tcftbl marked this conversation as resolved.
Show resolved Hide resolved
- ['←↓↑→↖↗↙↘', "Arrows for directional keys (roguelike)"]
tcftbl marked this conversation as resolved.
Show resolved Hide resolved
desc: >-
Labels for hint characters.

To replace the removed `hints.uppercase` setting, set `c.hints.labels =
c.hints.chars.upper()` in `config.py`.

hints.dictionary:
default: /usr/share/dict/words
type:
Expand Down Expand Up @@ -1775,11 +1791,6 @@ hints.selectors:
desc: CSS selectors used to determine which elements on a page should have
hints.

hints.uppercase:
default: false
type: Bool
desc: Make characters in hint strings uppercase.

hints.leave_on_load:
default: false
type: Bool
Expand Down
18 changes: 18 additions & 0 deletions qutebrowser/config/configfiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@ def migrate(self) -> None:
self._migrate_bindings_default()
self._migrate_font_default_family()
self._migrate_font_replacements()
self._migrate_hints_uppercase()

self._migrate_bool('tabs.favicons.show', 'always', 'never')
self._migrate_bool('scrolling.bar', 'always', 'overlay')
Expand Down Expand Up @@ -553,6 +554,23 @@ def _migrate_bindings_default(self) -> None:
del self._settings['bindings.default']
self.changed.emit()

def _migrate_hints_uppercase(self) -> None:
tcftbl marked this conversation as resolved.
Show resolved Hide resolved
if 'hints.uppercase' not in self._settings:
return

self._settings['hints.labels'] = {}

for scope, val in self._settings['hints.uppercase'].items():
if val and 'hints.chars' in self._settings:
labels = self._settings['hints.chars'][scope].upper()
self._settings['hints.labels'][scope] = labels
elif val and 'hints.chars' not in self._settings:
labels = configdata.DATA['hints.chars'].default.upper()
self._settings['hints.labels'][scope] = labels

del self._settings['hints.uppercase']
self.changed.emit()

def _migrate_font_default_family(self) -> None:
old_name = 'fonts.monospace'
new_name = 'fonts.default_family'
Expand Down
34 changes: 34 additions & 0 deletions tests/unit/config/test_configfiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,40 @@ def test_content_media_capture(self, yaml, autoconfig):
'content.media.video_capture']:
assert data[setting]['global'] == val

@pytest.mark.parametrize('chars, uppercase', [
('aoeuidnths', True),
('abcdefghijklmnopqrstuvwxyz', True),
(None, True),
('aoeuidnths', False),
('abcdefghijklmnopqrstuvwxyz', False),
(None, False),
('aoeuidnths', None),
('abcdefghijklmnopqrstuvwxyz', None),
(None, None),
])
def test_hints_uppercase(self, yaml, autoconfig, chars, uppercase):
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not super happy with this test. I dislike the use None values, but I couldn't figure out how to do this in a nicer way. The problem is the interdependence of hints.chars and hints.uppercase. We have to test for the possibility that one or both of them is unset. Is there a better way to represent this than the use of None values?

settings = {}
if chars is not None:
settings['hints.chars'] = {'global': chars}
if uppercase is not None:
settings['hints.uppercase'] = {'global': uppercase}

autoconfig.write(settings)

yaml.load()
yaml._save()

data = autoconfig.read()
if uppercase:
if 'hints.chars' in data:
labels = data['hints.chars']['global'].upper()
assert data['hints.labels']['global'] == labels
else:
labels = configdata.DATA['hints.chars'].default.upper()
assert data['hints.labels']['global'] == labels
else:
assert 'hints.labels' not in data

def test_empty_pattern(self, yaml, autoconfig):
valid_pattern = 'https://example.com/*'
invalid_pattern = '*://*./*'
Expand Down
Loading