Fix macros with a mode-switching command

This commit is contained in:
Florian Bruhin 2016-11-10 07:16:52 +01:00
parent 22cd42c515
commit 2ef85d6c35
5 changed files with 27 additions and 6 deletions

View File

@ -70,10 +70,11 @@ class BaseKeyParser(QObject):
request_leave: Emitted to request leaving a mode. request_leave: Emitted to request leaving a mode.
arg 0: Mode to leave. arg 0: Mode to leave.
arg 1: Reason for leaving. arg 1: Reason for leaving.
arg 2: Ignore the request if we're not in that mode
""" """
keystring_updated = pyqtSignal(str) keystring_updated = pyqtSignal(str)
request_leave = pyqtSignal(usertypes.KeyMode, str) request_leave = pyqtSignal(usertypes.KeyMode, str, bool)
do_log = True do_log = True
passthrough = False passthrough = False

View File

@ -276,16 +276,24 @@ class ModeManager(QObject):
raise cmdexc.CommandError("Mode {} does not exist!".format(mode)) raise cmdexc.CommandError("Mode {} does not exist!".format(mode))
self.enter(m, 'command') self.enter(m, 'command')
@pyqtSlot(usertypes.KeyMode, str) @pyqtSlot(usertypes.KeyMode, str, bool)
def leave(self, mode, reason=None): def leave(self, mode, reason=None, maybe=False):
"""Leave a key mode. """Leave a key mode.
Args: Args:
mode: The mode to leave as a usertypes.KeyMode member. mode: The mode to leave as a usertypes.KeyMode member.
reason: Why the mode was left. reason: Why the mode was left.
maybe: If set, ignore the request if we're not in that mode.
""" """
if self.mode != mode: if self.mode != mode:
if maybe:
log.modes.debug("Ignoring leave request for {} (reason {}) as "
"we're in mode {}".format(
mode, reason, self.mode))
return
else:
raise NotInModeError("Not in mode {}!".format(mode)) raise NotInModeError("Not in mode {}!".format(mode))
log.modes.debug("Leaving mode {}{}".format( log.modes.debug("Leaving mode {}{}".format(
mode, '' if reason is None else ' (reason: {})'.format(reason))) mode, '' if reason is None else ' (reason: {})'.format(reason)))
# leaving a mode implies clearing keychain, see # leaving a mode implies clearing keychain, see

View File

@ -315,7 +315,7 @@ class RegisterKeyParser(keyparser.BaseKeyParser):
except (cmdexc.CommandMetaError, cmdexc.CommandError) as err: except (cmdexc.CommandMetaError, cmdexc.CommandError) as err:
message.error(str(err), stack=traceback.format_exc()) message.error(str(err), stack=traceback.format_exc())
self.request_leave.emit(self._mode, "valid register key") self.request_leave.emit(self._mode, "valid register key", True)
return True return True

View File

@ -237,3 +237,15 @@ Feature: Keyboard input
When I run :run-macro bar When I run :run-macro bar
Then the error "No macro recorded in 'bar'!" should be shown Then the error "No macro recorded in 'bar'!" should be shown
And no crash should happen And no crash should happen
Scenario: Running a macro with a mode-switching command
When I open data/hints/html/simple.html
And I run :record-macro a
And I run :hint links normal
And I wait for "hints: *" in the log
And I run :leave-mode
And I run :record-macro a
And I run :run-macro
And I press the key "a"
And I wait for "hints: *" in the log
Then no crash should happen

View File

@ -28,7 +28,7 @@ class FakeKeyparser(QObject):
"""A fake BaseKeyParser which doesn't handle anything.""" """A fake BaseKeyParser which doesn't handle anything."""
request_leave = pyqtSignal(usertypes.KeyMode, str) request_leave = pyqtSignal(usertypes.KeyMode, str, bool)
def __init__(self): def __init__(self):
super().__init__() super().__init__()