Clean up Completer.on_selection_changed.
Remove the dependency on the class variables _empty_item_index and _cursor_part to make the code easier to follow. If _update_completion is refactored in a similar way these variables can be removed.
This commit is contained in:
parent
eb384fdda0
commit
581d7659ba
@ -179,6 +179,27 @@ class Completer(QObject):
|
|||||||
else:
|
else:
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
def _partition(self):
|
||||||
|
parts = [x for x in self._split(keep=True) if x]
|
||||||
|
pos = self._cmd.cursorPosition() - len(self._cmd.prefix())
|
||||||
|
log.completion.debug('partitioning {} around position {}'.format(parts,
|
||||||
|
pos))
|
||||||
|
for i, part in enumerate(parts):
|
||||||
|
pos -= len(part)
|
||||||
|
if pos <= 0:
|
||||||
|
if part[pos-1:pos+1].isspace():
|
||||||
|
# cursor is in a space between two existing words
|
||||||
|
parts.insert(i, '')
|
||||||
|
prefix = [x.strip() for x in parts[:i]]
|
||||||
|
center = parts[i].strip()
|
||||||
|
# strip trailing whitepsace included as a separate token
|
||||||
|
postfix = [x.strip() for x in parts[i+1:] if not x.isspace()]
|
||||||
|
log.completion.debug(
|
||||||
|
'partitioned: {} {} {}'.format(prefix, center, postfix))
|
||||||
|
return prefix, center, postfix
|
||||||
|
log.completion.debug('empty partition result')
|
||||||
|
return [], '', []
|
||||||
|
|
||||||
@pyqtSlot(QItemSelection)
|
@pyqtSlot(QItemSelection)
|
||||||
def on_selection_changed(self, selected):
|
def on_selection_changed(self, selected):
|
||||||
"""Change the completed part if a new item was selected.
|
"""Change the completed part if a new item was selected.
|
||||||
@ -355,29 +376,18 @@ class Completer(QObject):
|
|||||||
including a trailing space and we shouldn't continue
|
including a trailing space and we shouldn't continue
|
||||||
completing the current item.
|
completing the current item.
|
||||||
"""
|
"""
|
||||||
parts = self._split()
|
before, center, after = self._partition()
|
||||||
log.completion.debug("changing part {} to '{}'".format(
|
log.completion.debug("changing {} to '{}'".format(center, newtext))
|
||||||
self._cursor_part, newtext))
|
text = self._cmd.prefix() + ' '.join([*before, newtext])
|
||||||
try:
|
pos = len(text) + (1 if immediate else 0)
|
||||||
parts[self._cursor_part] = newtext
|
if after:
|
||||||
except IndexError:
|
text += ' ' + ' '.join(after)
|
||||||
parts.append(newtext)
|
elif immediate:
|
||||||
# We want to place the cursor directly after the part we just changed.
|
# pad with a space if quick-completing the last entry
|
||||||
cursor_str = self._cmd.prefix() + ' '.join(
|
|
||||||
parts[:self._cursor_part + 1])
|
|
||||||
if immediate:
|
|
||||||
# If we should complete immediately, we want to move the cursor by
|
|
||||||
# one more char, to get to the next field.
|
|
||||||
cursor_str += ' '
|
|
||||||
text = self._cmd.prefix() + ' '.join(parts)
|
|
||||||
if immediate and self._cursor_part == len(parts) - 1:
|
|
||||||
# If we should complete immediately and we're completing the last
|
|
||||||
# part in the commandline, we automatically add a space.
|
|
||||||
text += ' '
|
text += ' '
|
||||||
|
log.completion.debug("setting text = '{}', pos = {}".format(text, pos))
|
||||||
self._cmd.setText(text)
|
self._cmd.setText(text)
|
||||||
log.completion.debug("Placing cursor after '{}'".format(cursor_str))
|
self._cmd.setCursorPosition(pos)
|
||||||
log.modes.debug("Completion triggered, focusing {!r}".format(self))
|
|
||||||
self._cmd.setCursorPosition(len(cursor_str))
|
|
||||||
self._cmd.setFocus()
|
self._cmd.setFocus()
|
||||||
self._cmd.show_cmd.emit()
|
self._cmd.show_cmd.emit()
|
||||||
|
|
||||||
|
@ -204,6 +204,7 @@ def test_update_completion(txt, expected, status_command_stub, completer_obj,
|
|||||||
(':|set', 'set', ':set|'),
|
(':|set', 'set', ':set|'),
|
||||||
(':|set ', 'set', ':set|'),
|
(':|set ', 'set', ':set|'),
|
||||||
(':|se', 'set', ':set|'),
|
(':|se', 'set', ':set|'),
|
||||||
|
(':|se ', 'set', ':set|'),
|
||||||
(':s|e', 'set', ':set|'),
|
(':s|e', 'set', ':set|'),
|
||||||
(':se|', 'set', ':set|'),
|
(':se|', 'set', ':set|'),
|
||||||
(':|se fonts', 'set', ':set| fonts'),
|
(':|se fonts', 'set', ':set| fonts'),
|
||||||
@ -248,8 +249,6 @@ def test_on_selection_changed(before, newtxt, after, completer_obj,
|
|||||||
config_stub.data['completion']['quick-complete'] = quick_complete
|
config_stub.data['completion']['quick-complete'] = quick_complete
|
||||||
model.count = unittest.mock.Mock(return_value=count)
|
model.count = unittest.mock.Mock(return_value=count)
|
||||||
_set_cmd_prompt(status_command_stub, before)
|
_set_cmd_prompt(status_command_stub, before)
|
||||||
# TODO: refactor so cursor_part is a local rather than class variable
|
|
||||||
completer_obj._update_cursor_part()
|
|
||||||
completer_obj.on_selection_changed(selection)
|
completer_obj.on_selection_changed(selection)
|
||||||
model.data.assert_called_with(indexes[0])
|
model.data.assert_called_with(indexes[0])
|
||||||
assert status_command_stub.text() == expected_txt
|
assert status_command_stub.text() == expected_txt
|
||||||
|
Loading…
Reference in New Issue
Block a user