From 932d77bd50196a2c665e5d65de732b1349ed1925 Mon Sep 17 00:00:00 2001 From: Mason Larobina Date: Sat, 28 Nov 2009 15:35:58 +0800 Subject: Added modkey addition to keycmd plugin. We are now able to remove the hardcoded "+ -> " and "+ -> " modkey transformations from the key_press and key_release functions. --- examples/config/uzbl/config | 9 ++- examples/data/uzbl/plugins/keycmd.py | 127 ++++++++++++++++++++++++++++------- 2 files changed, 111 insertions(+), 25 deletions(-) diff --git a/examples/config/uzbl/config b/examples/config/uzbl/config index 62b5315..dc91e59 100644 --- a/examples/config/uzbl/config +++ b/examples/config/uzbl/config @@ -19,6 +19,8 @@ set progress = request PROGRESS_CONFIG set modmap = request MODMAP # request IGNORE_KEY set ignore_key = request IGNORE_KEY +# request MODKEY_ADDITION +set modkey_addition = request MODKEY_ADDITION set set_mode = set mode = set set_status = set status_message = @@ -108,15 +110,20 @@ set socket_dir = /tmp # === Key modmapping and ignoring ============================================ -#modmap from to +#modmap @modmap @modmap @modmap +#modkey_addition +@modkey_addition +@modkey_addition + #ignore_key @ignore_key @ignore_key + # === Keyboard & Mouse bindings ============================================== # With this command you can enter in any command at runtime when prefixed with diff --git a/examples/data/uzbl/plugins/keycmd.py b/examples/data/uzbl/plugins/keycmd.py index 8a509bb..4c88fd8 100644 --- a/examples/data/uzbl/plugins/keycmd.py +++ b/examples/data/uzbl/plugins/keycmd.py @@ -3,7 +3,7 @@ import re # Map these functions/variables in the plugins namespace to the uzbl object. __export__ = ['clear_keycmd', 'set_keycmd', 'set_cursor_pos', 'get_keylet', 'clear_current', 'clear_modcmd', 'add_modmap', 'add_key_ignore', - 'append_keycmd', 'inject_keycmd'] + 'append_keycmd', 'inject_keycmd', 'add_modkey_addition'] # Hold the keylets. UZBLS = {} @@ -42,6 +42,7 @@ class Keylet(object): self.modmaps = {} self.ignores = {} + self.additions = {} # Keylet string repr cache. self._repr_cache = None @@ -76,6 +77,25 @@ class Keylet(object): return key + def find_addition(self, modkey): + '''Key has just been pressed, check if this key + the held list + results in a modkey addition. Return that addition and remove all + modkeys that created it.''' + + already_added = self.held & set(self.additions.keys()) + for key in already_added: + if modkey in self.additions[key]: + return key + + modkeys = set(list(self.held) + [modkey,]) + for (key, value) in self.additions.items(): + if modkeys.issuperset(value): + self.held = modkeys ^ value + return key + + return modkey + + def key_ignored(self, key): '''Check if the given key is ignored by any ignore rules.''' @@ -107,7 +127,20 @@ class Keylet(object): def add_modmap(uzbl, key, map): - '''Add modmaps.''' + '''Add modmaps. + + Examples: + set modmap = request MODMAP + @modmap + @modmap + ... + + Then: + @bind = + @bind x = + ... + + ''' assert len(key) modmaps = get_keylet(uzbl).modmaps @@ -131,7 +164,14 @@ def modmap_parse(uzbl, map): def add_key_ignore(uzbl, glob): - '''Add an ignore definition.''' + '''Add an ignore definition. + + Examples: + set ignore_key = request IGNORE_KEY + @ignore_key + @ignore_key + ... + ''' assert len(glob) > 1 ignores = get_keylet(uzbl).ignores @@ -144,6 +184,45 @@ def add_key_ignore(uzbl, glob): uzbl.event('NEW_KEY_IGNORE', glob) +def add_modkey_addition(uzbl, modkeys, result): + '''Add a modkey addition definition. + + Examples: + set mod_addition = request MODKEY_ADDITION + @mod_addition + @mod_addition + @mod_addition + ... + + Then: + @bind = + @bind o = + ... + ''' + + additions = get_keylet(uzbl).additions + modkeys = set(modkeys) + + assert len(modkeys) and result and result not in modkeys + + for (existing_result, existing_modkeys) in additions.items(): + if existing_result != result: + assert modkeys != existing_modkeys + + additions[result] = modkeys + uzbl.event('NEW_MODKEY_ADDITION', modkeys, result) + + +def modkey_addition_parse(uzbl, modkeys): + '''Parse modkey addition definition.''' + + keys = filter(None, map(unicode.strip, modkeys.split(" "))) + keys = ['<%s>' % key.strip("<>") for key in keys if key.strip("<>")] + + assert len(keys) > 1 + add_modkey_addition(uzbl, keys[:-1], keys[-1]) + + def add_instance(uzbl, *args): '''Create the Keylet object for this uzbl instance.''' @@ -259,14 +338,23 @@ def inject_str(str, index, inj): return "%s%s%s" % (str[:index], inj, str[index:]) -def chevronate(key): - '''If a modkey isn't already chevronated then chevronate it. Ignore all - other keys.''' +def get_keylet_and_key(uzbl, key): + '''Return the keylet and apply any transformations to the key as defined + by the modmapping or modkey addition rules. Return None if the key is + ignored.''' + keylet = get_keylet(uzbl) + key = keylet.modmap_key(key) if len(key) == 1: - return key + return (keylet, key) + + modkey = "<%s>" % key.strip("<>") + modkey = keylet.find_addition(modkey) + + if keylet.key_ignored(modkey): + return (keylet, None) - return "<%s>" % key.strip("<>") + return (keylet, modkey) def key_press(uzbl, key): @@ -279,10 +367,8 @@ def key_press(uzbl, key): 5. If in modcmd mode the pressed key is added to the held keys list. 6. Keycmd is updated and events raised if anything is changed.''' - k = get_keylet(uzbl) - key = chevronate(k.modmap_key(key.strip())) - - if k.key_ignored(key): + (k, key) = get_keylet_and_key(uzbl, key.strip()) + if not key: return if key.lower() == '' and not k.held and k.keycmd: @@ -304,9 +390,6 @@ def key_press(uzbl, key): elif len(key) > 1: k.is_modcmd = True - if key == '' and '' in k.held: - k.held.remove('') - if key not in k.held: k.held.add(key) @@ -325,14 +408,9 @@ def key_release(uzbl, key): 3. Check if any modkey is held, if so set modcmd mode. 4. Update the keycmd uzbl variable if anything changed.''' - k = get_keylet(uzbl) - key = chevronate(k.modmap_key(key)) - - if key in ['', ''] and '' in k.held: - key = '' - - elif key in ['', ''] and '' in k.held: - key = '' + (k, key) = get_keylet_and_key(uzbl, key.strip()) + if not key: + return if key in k.held: if k.is_modcmd: @@ -464,6 +542,7 @@ def init(uzbl): 'MODMAP': modmap_parse, 'APPEND_KEYCMD': append_keycmd, 'INJECT_KEYCMD': inject_keycmd, - 'IGNORE_KEY': add_key_ignore} + 'IGNORE_KEY': add_key_ignore, + 'MODKEY_ADDITION': modkey_addition_parse} uzbl.connect_dict(connects) -- cgit v1.2.3