From 604f1d4c1e94ed226d118607b105e52cb189626b Mon Sep 17 00:00:00 2001 From: Mason Larobina Date: Tue, 8 Sep 2009 22:53:35 +0800 Subject: Improved key/command/mod-command handling in keycmd.py plugin. --- examples/data/uzbl/scripts/event_manager.py | 4 +- examples/data/uzbl/scripts/plugins/keycmd.py | 212 +++++++++++++++++++-------- 2 files changed, 152 insertions(+), 64 deletions(-) diff --git a/examples/data/uzbl/scripts/event_manager.py b/examples/data/uzbl/scripts/event_manager.py index 3dc4987..7f3ffce 100755 --- a/examples/data/uzbl/scripts/event_manager.py +++ b/examples/data/uzbl/scripts/event_manager.py @@ -527,7 +527,9 @@ class UzblInstance(object): def handle_event(self, event, args): '''Handle uzbl events internally before dispatch.''' - print event, args + # Silence _printing_ of geo events while still debugging. + if event != "GEOMETRY_CHANGED": + print event, args if event == 'VARIABLE_SET': l = args.split(' ', 2) diff --git a/examples/data/uzbl/scripts/plugins/keycmd.py b/examples/data/uzbl/scripts/plugins/keycmd.py index edfe673..b96546d 100644 --- a/examples/data/uzbl/scripts/plugins/keycmd.py +++ b/examples/data/uzbl/scripts/plugins/keycmd.py @@ -1,118 +1,204 @@ +#TODO: Comment code. + +import re + +# Regex build cache. +_RE_CACHE = {} + +def get_regex(regex): + if regex not in _RE_CACHE: + _RE_CACHE[regex] = re.compile(regex).match + + return _RE_CACHE[regex] + + class Keylet(object): def __init__(self): self.cmd = "" self.held = [] - self.modfirst = False + + # to_string() string building cache. + self._to_string = None + + self._modcmd = False + self._wasmod = True + def __repr__(self): - fmt = "" - if not self.cmd and not self.held: - return fmt % "" + return "" % self.to_string() - elif not len(self.held): - return fmt % self.cmd - helds = '+'.join(["<%s>" % key for key in self.held]) - if not self.cmd: - return fmt % helds + def _clear(self): + self.cmd = "" + self._to_string = None + if self._modcmd: + self._wasmod = True - else: - return fmt % ("%s+%s" % (helds, self.cmd)) + self._modcmd = False -keymap = {'period': '.'} + def to_string(self): + '''Always of the form +command''' -class KeycmdTracker(dict): - def get_cmd(self, uzbl): - '''Returns a tuple of the form (keys held, cmdstr)''' + if self._to_string is not None: + return self._to_string - if uzbl not in self: - return ([], []) + if not self.held: + self._to_string = self.cmd - return self[uzbl] + else: + self._to_string = ''.join(["<%s>" % key for key in self.held]) + if self.cmd: + self._to_string += "+%s" % self.cmd + return self._to_string - def key_press(self, uzbl, key): - if key.startswith("Shift_"): - return + def match(self, regex): + return bool(get_regex(regex)(self.to_string())) - t = self.get_keylet(uzbl) - if key == "BackSpace": - if t.cmd: - t.cmd = t.cmd[:-1] - elif key == "Escape": - self.clear(uzbl) +_SIMPLEKEYS = {'Control': 'Ctrl', 'ISO_Left_Tab': 'Shift-Tab',} - elif key == "space": - if t.cmd: - t.cmd += " " +def makesimple(key): + if key.endswith("_L") or key.endswith("_R"): + key = key[:-2] - elif key in keymap: - t.cmd += keymap[key] + if key in _SIMPLEKEYS: + key = _SIMPLEKEYS[key] - elif len(key) == 1: - t.cmd += key + return key - elif key not in t.held: - if not t.held and not t.cmd and len(key) != 1: - t.modfirst = True - t.held.append(key) +class KeycmdTracker(dict): + def key_press(self, uzbl, key): + if key.startswith("Shift_"): + return - self.raise_event(uzbl) + if len(key) > 1: + key = makesimple(key) + + k = self.get_keylet(uzbl) + cmdmod = False + + if k.held and k._wasmod: + k._modcmd = True + k._wasmod = False + cmdmod = True + + if key == "space": + if k.cmd: + k.cmd += " " + cmdmod = True + + elif not k._modcmd and key in ['BackSpace', 'Return', 'Escape']: + if key == "BackSpace": + if k.cmd: + k.cmd = k.cmd[:-1] + if not k.cmd: + self.clear(uzbl) + + else: + cmdmod = True + + elif key == "Return": + uzbl.event("KEYCMD_EXEC", k) + self.clear(uzbl) + + elif key == "Escape": + self.clear(uzbl) + + elif not k.held and not k.cmd: + k._modcmd = True if len(key) > 1 else False + k.held.append(key) + k.held.sort() + cmdmod = True + if not k._modcmd: + k.cmd += key + + elif k._modcmd: + cmdmod = True + if len(key) > 1: + if key not in k.held: + k.held.append(key) + k.held.sort() + + else: + k.cmd += key + else: + cmdmod = True + if len(key) == 1: + if key not in k.held: + k.held.append(key) + k.held.sort() - def key_release(self, uzbl, key): + k.cmd += key - #if key == "Return": - # TODO: Something here + if cmdmod: + self.update(uzbl, k) - t = self.get_keylet(uzbl) - if key in t.held: - t.held.remove(key) - if key == "Return": + def key_release(self, uzbl, key): + if len(key) > 1: + key = makesimple(key) + + k = self.get_keylet(uzbl) + cmdmod = False + if k._modcmd and key in k.held: + uzbl.event("MODCMD_EXEC", k) + k.held.remove(key) + k.held.sort() self.clear(uzbl) - if t.modfirst and not len(t.held): - self.clear(uzbl) + elif not k._modcmd and key in k.held: + k.held.remove(key) + k.held.sort() + cmdmod = True + + if not k.held and not k.cmd and k._wasmod: + k._wasmod = False - self.raise_event(uzbl) + if cmdmod: + self.update(uzbl, k) + + + def update(self, uzbl, keylet): + if keylet._modcmd: + uzbl.config['keycmd'] = keylet.to_string() + uzbl.event("MODCMD_UPDATE", keylet) + + else: + uzbl.config['keycmd'] = keylet.cmd + uzbl.event("KEYCMD_UPDATE", keylet) def get_keylet(self, uzbl): if uzbl not in self: self.add_instance(uzbl) - + keylet = self[uzbl] + keylet._to_string = None return self[uzbl] def clear(self, uzbl): - t = self.get_keylet(uzbl) - t.cmd = "" - t.modfirst = False + self.get_keylet(uzbl)._clear() + uzbl.config['keycmd'] = "" + uzbl.event("KEYCMD_CLEAR") - def add_instance(self, uzbl): + def add_instance(self, uzbl, *args): self[uzbl] = Keylet() - def del_instance(self, uzbl): + def del_instance(self, uzbl, *args): if uzbl in self: del uzbl - def raise_event(self, uzbl): - '''Raise a custom event.''' - - keylet = self.get_keylet(uzbl) - uzbl.config['keycmd'] = keylet.cmd - uzbl.event('KEYCMD_UPDATE', self.get_keylet(uzbl)) - - keycmd = KeycmdTracker() +export_clear_keycmd = keycmd.clear + def init(uzbl): -- cgit v1.2.3