Interactively get macro register
This commit is contained in:
parent
7aaaadac1a
commit
33ff0ba715
@ -606,15 +606,12 @@ Quit qutebrowser.
|
|||||||
|
|
||||||
[[record-macro]]
|
[[record-macro]]
|
||||||
=== record-macro
|
=== record-macro
|
||||||
Syntax: +:record-macro ['name']+
|
Syntax: +:record-macro ['register']+
|
||||||
|
|
||||||
Start or stop recording a macro.
|
Start or stop recording a macro.
|
||||||
|
|
||||||
==== positional arguments
|
==== positional arguments
|
||||||
* +'name'+: Which name to give the macro.
|
* +'register'+: Which register to store the macro in.
|
||||||
|
|
||||||
==== note
|
|
||||||
* This command does not split arguments after the last argument and handles quotes literally.
|
|
||||||
|
|
||||||
[[reload]]
|
[[reload]]
|
||||||
=== reload
|
=== reload
|
||||||
@ -653,19 +650,16 @@ Restart qutebrowser while keeping existing tabs open.
|
|||||||
|
|
||||||
[[run-macro]]
|
[[run-macro]]
|
||||||
=== run-macro
|
=== run-macro
|
||||||
Syntax: +:run-macro ['name']+
|
Syntax: +:run-macro ['register']+
|
||||||
|
|
||||||
Run a recorded macro.
|
Run a recorded macro.
|
||||||
|
|
||||||
==== positional arguments
|
==== positional arguments
|
||||||
* +'name'+: Which macro to run.
|
* +'register'+: Which macro to run.
|
||||||
|
|
||||||
==== count
|
==== count
|
||||||
How many times to run the macro.
|
How many times to run the macro.
|
||||||
|
|
||||||
==== note
|
|
||||||
* This command does not split arguments after the last argument and handles quotes literally.
|
|
||||||
|
|
||||||
[[save]]
|
[[save]]
|
||||||
=== save
|
=== save
|
||||||
Syntax: +:save ['what' ['what' ...]]+
|
Syntax: +:save ['what' ['what' ...]]+
|
||||||
|
@ -34,8 +34,10 @@ from qutebrowser.misc import split
|
|||||||
ParseResult = collections.namedtuple('ParseResult', ['cmd', 'args', 'cmdline',
|
ParseResult = collections.namedtuple('ParseResult', ['cmd', 'args', 'cmdline',
|
||||||
'count'])
|
'count'])
|
||||||
last_command = {}
|
last_command = {}
|
||||||
|
|
||||||
macro = {}
|
macro = {}
|
||||||
recording_macro = None
|
recording_macro = None
|
||||||
|
macro_count = {}
|
||||||
|
|
||||||
|
|
||||||
def _current_url(tabbed_browser):
|
def _current_url(tabbed_browser):
|
||||||
|
@ -78,8 +78,10 @@ def init(win_id, parent):
|
|||||||
warn=False),
|
warn=False),
|
||||||
KM.yesno: modeparsers.PromptKeyParser(win_id, modeman),
|
KM.yesno: modeparsers.PromptKeyParser(win_id, modeman),
|
||||||
KM.caret: modeparsers.CaretKeyParser(win_id, modeman),
|
KM.caret: modeparsers.CaretKeyParser(win_id, modeman),
|
||||||
KM.set_mark: modeparsers.MarkKeyParser(win_id, KM.set_mark, modeman),
|
KM.set_mark: modeparsers.RegisterKeyParser(win_id, KM.set_mark, modeman),
|
||||||
KM.jump_mark: modeparsers.MarkKeyParser(win_id, KM.jump_mark, modeman),
|
KM.jump_mark: modeparsers.RegisterKeyParser(win_id, KM.jump_mark, modeman),
|
||||||
|
KM.record_macro: modeparsers.RegisterKeyParser(win_id, KM.record_macro, modeman),
|
||||||
|
KM.run_macro: modeparsers.RegisterKeyParser(win_id, KM.run_macro, modeman),
|
||||||
}
|
}
|
||||||
objreg.register('keyparsers', keyparsers, scope='window', window=win_id)
|
objreg.register('keyparsers', keyparsers, scope='window', window=win_id)
|
||||||
modeman.destroyed.connect(
|
modeman.destroyed.connect(
|
||||||
|
@ -27,6 +27,7 @@ from PyQt5.QtCore import pyqtSlot, Qt
|
|||||||
|
|
||||||
from qutebrowser.config import config
|
from qutebrowser.config import config
|
||||||
from qutebrowser.keyinput import keyparser
|
from qutebrowser.keyinput import keyparser
|
||||||
|
from qutebrowser.misc import utilcmds
|
||||||
from qutebrowser.utils import usertypes, log, objreg, utils
|
from qutebrowser.utils import usertypes, log, objreg, utils
|
||||||
|
|
||||||
|
|
||||||
@ -264,12 +265,13 @@ class CaretKeyParser(keyparser.CommandKeyParser):
|
|||||||
self.read_config('caret')
|
self.read_config('caret')
|
||||||
|
|
||||||
|
|
||||||
class MarkKeyParser(keyparser.BaseKeyParser):
|
class RegisterKeyParser(keyparser.BaseKeyParser):
|
||||||
|
|
||||||
"""KeyParser for set_mark and jump_mark mode.
|
"""KeyParser for modes that record a register key.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
_mode: Either KeyMode.set_mark or KeyMode.jump_mark.
|
_mode: One of KeyMode.set_mark, KeyMode.jump_mark, KeyMode.record_macro
|
||||||
|
and KeyMode.run_macro.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, win_id, mode, parent=None):
|
def __init__(self, win_id, mode, parent=None):
|
||||||
@ -278,7 +280,7 @@ class MarkKeyParser(keyparser.BaseKeyParser):
|
|||||||
self._mode = mode
|
self._mode = mode
|
||||||
|
|
||||||
def handle(self, e):
|
def handle(self, e):
|
||||||
"""Override handle to always match the next key and create a mark.
|
"""Override handle to always match the next key and use the register.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
e: the KeyPressEvent from Qt.
|
e: the KeyPressEvent from Qt.
|
||||||
@ -299,18 +301,22 @@ class MarkKeyParser(keyparser.BaseKeyParser):
|
|||||||
tabbed_browser.set_mark(key)
|
tabbed_browser.set_mark(key)
|
||||||
elif self._mode == usertypes.KeyMode.jump_mark:
|
elif self._mode == usertypes.KeyMode.jump_mark:
|
||||||
tabbed_browser.jump_mark(key)
|
tabbed_browser.jump_mark(key)
|
||||||
|
elif self._mode == usertypes.KeyMode.record_macro:
|
||||||
|
utilcmds.record_macro(key)
|
||||||
|
elif self._mode == usertypes.KeyMode.run_macro:
|
||||||
|
utilcmds.run_macro(self._win_id, key)
|
||||||
else:
|
else:
|
||||||
raise ValueError("{} is not a valid mark mode".format(self._mode))
|
raise ValueError("{} is not a valid register key".format(self._mode))
|
||||||
|
|
||||||
self.request_leave.emit(self._mode, "valid mark key")
|
self.request_leave.emit(self._mode, "valid register key")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def on_keyconfig_changed(self, mode):
|
def on_keyconfig_changed(self, mode):
|
||||||
"""MarkKeyParser has no config section (no bindable keys)."""
|
"""RegisterKeyParser has no config section (no bindable keys)."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def execute(self, cmdstr, _keytype, count=None):
|
def execute(self, cmdstr, _keytype, count=None):
|
||||||
"""Should never be called on MarkKeyParser."""
|
"""Should never be called on RegisterKeyParser."""
|
||||||
assert False
|
assert False
|
||||||
|
@ -234,42 +234,57 @@ def repeat_command(win_id, count=None):
|
|||||||
commandrunner.run(cmd[0], count if count is not None else cmd[1])
|
commandrunner.run(cmd[0], count if count is not None else cmd[1])
|
||||||
|
|
||||||
|
|
||||||
@cmdutils.register(maxsplit=0)
|
@cmdutils.register(instance='mode-manager', name='record-macro', scope='window')
|
||||||
@cmdutils.argument('name')
|
@cmdutils.argument('register')
|
||||||
def record_macro(name=""):
|
def record_macro_command(self, register=None):
|
||||||
"""Start or stop recording a macro.
|
"""Start or stop recording a macro.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name: Which name to give the macro.
|
register: Which register to store the macro in.
|
||||||
"""
|
"""
|
||||||
if runners.recording_macro is None:
|
if runners.recording_macro is None:
|
||||||
message.info("Defining macro...")
|
if register is None:
|
||||||
runners.macro[name] = []
|
self.enter(usertypes.KeyMode.record_macro, 'record_macro')
|
||||||
runners.recording_macro = name
|
else:
|
||||||
elif runners.recording_macro == name:
|
record_macro(register)
|
||||||
message.info("Macro defined.")
|
|
||||||
runners.recording_macro = None
|
|
||||||
else:
|
else:
|
||||||
raise cmdexc.CommandError(
|
message.info("Macro recorded.")
|
||||||
"Already recording macro '{}'".format(runners.recording_macro))
|
runners.recording_macro = None
|
||||||
|
|
||||||
|
|
||||||
@cmdutils.register(maxsplit=0)
|
def record_macro(register):
|
||||||
|
"""Start recording a macro."""
|
||||||
|
message.info("Recording macro...")
|
||||||
|
runners.macro[register] = []
|
||||||
|
runners.recording_macro = register
|
||||||
|
|
||||||
|
|
||||||
|
@cmdutils.register(instance='mode-manager', name='run-macro', scope='window')
|
||||||
@cmdutils.argument('win_id', win_id=True)
|
@cmdutils.argument('win_id', win_id=True)
|
||||||
@cmdutils.argument('count', count=True)
|
@cmdutils.argument('count', count=True)
|
||||||
@cmdutils.argument('name')
|
@cmdutils.argument('register')
|
||||||
def run_macro(win_id, count=1, name=""):
|
def run_macro_command(self, win_id, count=1, register=None):
|
||||||
"""Run a recorded macro.
|
"""Run a recorded macro.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
count: How many times to run the macro.
|
count: How many times to run the macro.
|
||||||
name: Which macro to run.
|
register: Which macro to run.
|
||||||
"""
|
"""
|
||||||
if name not in runners.macro:
|
runners.macro_count[win_id] = count
|
||||||
raise cmdexc.CommandError("No macro defined!")
|
if register is None:
|
||||||
|
self.enter(usertypes.KeyMode.run_macro, 'run_macro')
|
||||||
|
else:
|
||||||
|
run_macro(win_id, register)
|
||||||
|
|
||||||
|
|
||||||
|
def run_macro(win_id, register):
|
||||||
|
"""Run a recorded macro."""
|
||||||
|
if register not in runners.macro:
|
||||||
|
raise cmdexc.CommandError(
|
||||||
|
"No macro recorded in '{}'!".format(register))
|
||||||
commandrunner = runners.CommandRunner(win_id)
|
commandrunner = runners.CommandRunner(win_id)
|
||||||
for _ in range(count):
|
for _ in range(runners.macro_count[win_id]):
|
||||||
for cmd in runners.macro[name]:
|
for cmd in runners.macro[register]:
|
||||||
commandrunner.run(*cmd)
|
commandrunner.run(*cmd)
|
||||||
|
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ ClickTarget = enum('ClickTarget', ['normal', 'tab', 'tab_bg', 'window',
|
|||||||
# Key input modes
|
# Key input modes
|
||||||
KeyMode = enum('KeyMode', ['normal', 'hint', 'command', 'yesno', 'prompt',
|
KeyMode = enum('KeyMode', ['normal', 'hint', 'command', 'yesno', 'prompt',
|
||||||
'insert', 'passthrough', 'caret', 'set_mark',
|
'insert', 'passthrough', 'caret', 'set_mark',
|
||||||
'jump_mark'])
|
'jump_mark', 'record_macro', 'run_macro'])
|
||||||
|
|
||||||
|
|
||||||
# Available command completions
|
# Available command completions
|
||||||
|
@ -121,11 +121,11 @@ Feature: Keyboard input
|
|||||||
When I open data/keyinput/log.html
|
When I open data/keyinput/log.html
|
||||||
And I set general -> log-javascript-console to info
|
And I set general -> log-javascript-console to info
|
||||||
And I set input -> forward-unbound-keys to all
|
And I set input -> forward-unbound-keys to all
|
||||||
And I press the key "q"
|
And I press the key ","
|
||||||
And I press the key "<F1>"
|
And I press the key "<F1>"
|
||||||
# q
|
# ,
|
||||||
Then the javascript message "key press: 81" should be logged
|
Then the javascript message "key press: 188" should be logged
|
||||||
And the javascript message "key release: 81" should be logged
|
And the javascript message "key release: 188" should be logged
|
||||||
# <F1>
|
# <F1>
|
||||||
And the javascript message "key press: 112" should be logged
|
And the javascript message "key press: 112" should be logged
|
||||||
And the javascript message "key release: 112" should be logged
|
And the javascript message "key release: 112" should be logged
|
||||||
|
@ -625,18 +625,20 @@ Feature: Various utility commands.
|
|||||||
Scenario: Recording a simple macro
|
Scenario: Recording a simple macro
|
||||||
Given I open data/scroll/simple.html
|
Given I open data/scroll/simple.html
|
||||||
And I run :tab-only
|
And I run :tab-only
|
||||||
When I run :scroll down with count 5
|
When I run :scroll down with count 6
|
||||||
And I run :record-macro
|
And I run :record-macro
|
||||||
|
And I press the key "a"
|
||||||
And I run :scroll up
|
And I run :scroll up
|
||||||
And I run :scroll up
|
And I run :scroll up
|
||||||
And I run :record-macro
|
And I run :record-macro
|
||||||
And I run :run-macro with count 2
|
And I run :run-macro with count 2
|
||||||
|
And I press the key "a"
|
||||||
Then the page should not be scrolled
|
Then the page should not be scrolled
|
||||||
|
|
||||||
Scenario: Recording a named macro
|
Scenario: Recording a named macro
|
||||||
Given I open data/scroll/simple.html
|
Given I open data/scroll/simple.html
|
||||||
And I run :tab-only
|
And I run :tab-only
|
||||||
When I run :scroll down with count 5
|
When I run :scroll down with count 6
|
||||||
And I run :record-macro foo
|
And I run :record-macro foo
|
||||||
And I run :scroll up
|
And I run :scroll up
|
||||||
And I run :scroll up
|
And I run :scroll up
|
||||||
|
Loading…
Reference in New Issue
Block a user