Allow to bind numbers in keybindings
This mostly reverts 4ef5db1bc4
for #1966, but
fixes #3684 by allowing numbers to be bound again. If the user wants to bind
numbers instead of using them for a count, why not let them.
This commit is contained in:
parent
34815f5cf8
commit
514138aad2
@ -1654,13 +1654,6 @@ class Key(BaseType):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
seq = keyutils.KeySequence.parse(value)
|
return keyutils.KeySequence.parse(value)
|
||||||
except keyutils.KeyParseError as e:
|
except keyutils.KeyParseError as e:
|
||||||
raise configexc.ValidationError(value, str(e))
|
raise configexc.ValidationError(value, str(e))
|
||||||
|
|
||||||
for info in seq:
|
|
||||||
if Qt.Key_1 <= info.key <= Qt.Key_9 and not info.modifiers:
|
|
||||||
raise configexc.ValidationError(
|
|
||||||
value, "Numbers are reserved for counts!")
|
|
||||||
|
|
||||||
return seq
|
|
||||||
|
@ -139,13 +139,6 @@ class BaseKeyParser(QObject):
|
|||||||
self._debug_log("Ignoring, only modifier")
|
self._debug_log("Ignoring, only modifier")
|
||||||
return QKeySequence.NoMatch
|
return QKeySequence.NoMatch
|
||||||
|
|
||||||
if (txt.isdigit() and self._supports_count and not
|
|
||||||
(not self._count and txt == '0')):
|
|
||||||
assert len(txt) == 1, txt
|
|
||||||
if not dry_run:
|
|
||||||
self._count += txt
|
|
||||||
return QKeySequence.ExactMatch
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sequence = self._sequence.append_event(e)
|
sequence = self._sequence.append_event(e)
|
||||||
except keyutils.KeyParseError as ex:
|
except keyutils.KeyParseError as ex:
|
||||||
@ -153,7 +146,10 @@ class BaseKeyParser(QObject):
|
|||||||
self.clear_keystring()
|
self.clear_keystring()
|
||||||
return QKeySequence.NoMatch
|
return QKeySequence.NoMatch
|
||||||
|
|
||||||
|
# First, try a straightforward match
|
||||||
match, binding = self._match_key(sequence)
|
match, binding = self._match_key(sequence)
|
||||||
|
|
||||||
|
# If that doesn't match, try a key_mapping
|
||||||
if match == QKeySequence.NoMatch:
|
if match == QKeySequence.NoMatch:
|
||||||
mapped = sequence.with_mappings(config.val.bindings.key_mappings)
|
mapped = sequence.with_mappings(config.val.bindings.key_mappings)
|
||||||
if sequence != mapped:
|
if sequence != mapped:
|
||||||
@ -162,6 +158,16 @@ class BaseKeyParser(QObject):
|
|||||||
match, binding = self._match_key(mapped)
|
match, binding = self._match_key(mapped)
|
||||||
sequence = mapped
|
sequence = mapped
|
||||||
|
|
||||||
|
# If that doesn't match either, try treating it as count.
|
||||||
|
if (match == QKeySequence.NoMatch and
|
||||||
|
txt.isdigit() and
|
||||||
|
self._supports_count and
|
||||||
|
not (not self._count and txt == '0')):
|
||||||
|
assert len(txt) == 1, txt
|
||||||
|
if not dry_run:
|
||||||
|
self._count += txt
|
||||||
|
return QKeySequence.ExactMatch
|
||||||
|
|
||||||
if dry_run:
|
if dry_run:
|
||||||
return match
|
return match
|
||||||
|
|
||||||
|
@ -2063,11 +2063,13 @@ class TestKey:
|
|||||||
('<Control-x>', keyutils.KeySequence.parse('<ctrl+x>')),
|
('<Control-x>', keyutils.KeySequence.parse('<ctrl+x>')),
|
||||||
('<alt-1>', keyutils.KeySequence.parse('<alt+1>')),
|
('<alt-1>', keyutils.KeySequence.parse('<alt+1>')),
|
||||||
('0', keyutils.KeySequence.parse('0')),
|
('0', keyutils.KeySequence.parse('0')),
|
||||||
|
('1', keyutils.KeySequence.parse('1')),
|
||||||
|
('a1', keyutils.KeySequence.parse('a1')),
|
||||||
])
|
])
|
||||||
def test_to_py_valid(self, klass, val, expected):
|
def test_to_py_valid(self, klass, val, expected):
|
||||||
assert klass().to_py(val) == expected
|
assert klass().to_py(val) == expected
|
||||||
|
|
||||||
@pytest.mark.parametrize('val', ['\U00010000', '<blub>', '1', 'a1'])
|
@pytest.mark.parametrize('val', ['\U00010000', '<blub>'])
|
||||||
def test_to_py_invalid(self, klass, val):
|
def test_to_py_invalid(self, klass, val):
|
||||||
with pytest.raises(configexc.ValidationError):
|
with pytest.raises(configexc.ValidationError):
|
||||||
klass().to_py(val)
|
klass().to_py(val)
|
||||||
|
@ -33,7 +33,8 @@ BINDINGS = {'prompt': {'<Ctrl-a>': 'message-info ctrla',
|
|||||||
'ax': 'message-info ax',
|
'ax': 'message-info ax',
|
||||||
'ccc': 'message-info ccc',
|
'ccc': 'message-info ccc',
|
||||||
'yY': 'yank -s',
|
'yY': 'yank -s',
|
||||||
'0': 'message-info 0'},
|
'0': 'message-info 0',
|
||||||
|
'1': 'message-info 1'},
|
||||||
'command': {'foo': 'message-info bar',
|
'command': {'foo': 'message-info bar',
|
||||||
'<Ctrl+X>': 'message-info ctrlx'},
|
'<Ctrl+X>': 'message-info ctrlx'},
|
||||||
'normal': {'a': 'message-info a', 'ba': 'message-info ba'}}
|
'normal': {'a': 'message-info a', 'ba': 'message-info ba'}}
|
||||||
|
@ -192,9 +192,11 @@ class TestHandle:
|
|||||||
keyparser.execute.assert_called_with('message-info ba', None)
|
keyparser.execute.assert_called_with('message-info ba', None)
|
||||||
assert not keyparser._sequence
|
assert not keyparser._sequence
|
||||||
|
|
||||||
def test_0_press(self, handle_text, keyparser):
|
@pytest.mark.parametrize('key, number', [(Qt.Key_0, 0), (Qt.Key_1, 1)])
|
||||||
handle_text(Qt.Key_0)
|
def test_number_press(self, handle_text, keyparser, key, number):
|
||||||
keyparser.execute.assert_called_once_with('message-info 0', None)
|
handle_text(key)
|
||||||
|
command = 'message-info {}'.format(number)
|
||||||
|
keyparser.execute.assert_called_once_with(command, None)
|
||||||
assert not keyparser._sequence
|
assert not keyparser._sequence
|
||||||
|
|
||||||
def test_umlauts(self, handle_text, keyparser, config_stub):
|
def test_umlauts(self, handle_text, keyparser, config_stub):
|
||||||
|
Loading…
Reference in New Issue
Block a user