1 # -*- coding: utf-8 -*-
2 # Copyright Neil Brown (c)2020-2023 <neil@brown.name>
3 # May be distributed under terms of GPLv2 - see file:COPYING
5 # This module supports keyboard-macros, both recording and replaying.
6 # To start recording, we request Keystroke-notify from the display and record
7 # keystrokes until asked to stop, and which point we discard the last couple
8 # as advised. The set of keystrokes, as a comma-separated string, is added
10 # Individual macros in this history can be named with attributes at the start
11 # of the line. A macro can then be accessed by index from end, or by name.
12 # A macro can be replayed by sending keystrokes until one returns an error.
14 # While capturing keystrokes we register a pane to receive the notifications.
15 # This is a child of the root.
16 # Other functionality is available simply through global commands.
21 docname = "*Macro History*"
23 # A macro is a list of keystroke separated by commas
24 # A keystroke can contain a comma, but only preceeded by a '-'.
47 class CapturePane(edlib.Pane):
48 def __init__(self, focus):
50 while root.parent != root:
52 edlib.Pane.__init__(self, root)
53 focus.call("Window:request:Keystroke-notify", self)
54 focus.call("Window:request:macro:capture-active", self)
55 focus.call("Window:request:macro:capture-done", self)
56 focus.call("Mode:set-mode", str2 = "()")
59 def capture_active(self, key, focus, **a):
60 "handle:macro:capture-active"
63 def capture_key(self, key, focus, str, **a):
64 "handle:Keystroke-notify"
68 def capture_done(self, key, focus, num, **a):
69 "handle:macro:capture-done"
74 ret = self.call("history:add", docname, macro_join(self.line));
76 self.call("global-load-module", "lib-history")
77 ret = self.call("history:add", docname, macro_join(self.line))
80 focus.call("Mode:set-mode", str2 = "")
84 def start_capture(key, focus, **a):
85 if focus.call("Window:notify:macro:capture-active") >= 1:
86 # capture currently active
89 if focus.call("Window:notify:macro:capture-active") >= 1:
90 # Good, it is active now
94 def end_capture(key, focus, num, **a):
96 if focus.call("Window:notify:macro:capture-active") <= 0:
97 # capture currently active
99 except edlib.commandfailed:
101 ret = focus.call("Window:notify:macro:capture-done", num)
108 def play_macro(key, focus, num, str, **a):
110 mac = focus.call("history:get-last", docname, str, ret='str')
112 mac = focus.call("history:get-last", docname, num, ret='str')
115 keys = macro_split(mac)
118 while not error and i < len(keys):
120 if focus.call("Keystroke", keys[i]) < 0:
124 except edlib.commandfailed:
130 def name_macro(key, focus, num, str, **a):
131 # Give name 'str' to macro numbered 'num'
134 focus.call("history:get-last", num, docname, str)
136 edlib.editor.call("global-set-command", "macro:capture", start_capture)
137 edlib.editor.call("global-set-command", "macro:finished", end_capture)
138 edlib.editor.call("global-set-command", "macro:replay", play_macro)
139 edlib.editor.call("global-set-command", "macro:name", name_macro)