diff options
Diffstat (limited to 'examples/data/plugins/keycmd.py')
-rw-r--r-- | examples/data/plugins/keycmd.py | 218 |
1 files changed, 61 insertions, 157 deletions
diff --git a/examples/data/plugins/keycmd.py b/examples/data/plugins/keycmd.py index 928c597..1bb70e3 100644 --- a/examples/data/plugins/keycmd.py +++ b/examples/data/plugins/keycmd.py @@ -17,13 +17,10 @@ def uzbl_escape(str): class Keylet(object): - '''Small per-instance object that tracks all the keys held and characters - typed.''' + '''Small per-instance object that tracks characters typed.''' def __init__(self): # Modcmd tracking - self.held = set() - self.ignored = set() self.modcmd = '' self.is_modcmd = False @@ -33,7 +30,6 @@ class Keylet(object): self.modmaps = {} self.ignores = {} - self.additions = {} def get_keycmd(self): @@ -48,7 +44,7 @@ class Keylet(object): if not self.is_modcmd: return '' - return ''.join(self.held) + self.modcmd + return self.modcmd def modmap_key(self, key): @@ -65,28 +61,6 @@ 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.''' - - # Intersection of (held list + modkey) and additions. - added = (self.held | set([modkey])) & set(self.additions.keys()) - for key in added: - if key == modkey or modkey in self.additions[key]: - self.held -= self.additions[key] - return key - - # Held list + ignored list + modkey. - modkeys = self.held | self.ignored | set([modkey]) - for (key, value) in self.additions.items(): - if modkeys.issuperset(value): - self.held -= value - return key - - return modkey - - def key_ignored(self, key): '''Check if the given key is ignored by any ignore rules.''' @@ -104,9 +78,6 @@ class Keylet(object): if self.is_modcmd: l.append('modcmd=%r' % self.get_modcmd()) - elif self.held: - l.append('held=%r' % ''.join(sorted(self.held))) - if self.keycmd: l.append('keycmd=%r' % self.get_keycmd()) @@ -132,10 +103,7 @@ def add_modmap(uzbl, key, map): assert len(key) modmaps = uzbl.keylet.modmaps - if key[0] == "<" and key[-1] == ">": - key = key[1:-1] - - modmaps[key] = map + modmaps[key.strip('<>')] = map.strip('<>') uzbl.event("NEW_MODMAP", key, map) @@ -171,45 +139,6 @@ 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 <Shift> <Control> <Meta> - @mod_addition <Left> <Up> <Left-Up> - @mod_addition <Right> <Up> <Right-Up> - ... - - Then: - @bind <Right-Up> = <command1> - @bind <Meta>o = <command2> - ... - ''' - - additions = uzbl.keylet.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 clear_keycmd(uzbl, *args): '''Clear the keycmd for this uzbl instance.''' @@ -220,15 +149,12 @@ def clear_keycmd(uzbl, *args): uzbl.event('KEYCMD_CLEARED') -def clear_modcmd(uzbl, clear_held=False): +def clear_modcmd(uzbl): '''Clear the modcmd for this uzbl instance.''' k = uzbl.keylet k.modcmd = '' k.is_modcmd = False - if clear_held: - k.ignored = set() - k.held = set() del uzbl.config['modcmd'] uzbl.event('MODCMD_CLEARED') @@ -244,28 +170,22 @@ def clear_current(uzbl): clear_keycmd(uzbl) -def focus_changed(uzbl, *args): - '''Focus to the uzbl instance has now been lost which means all currently - held keys in the held list will not get a KEY_RELEASE event so clear the - entire held list.''' - - clear_modcmd(uzbl, clear_held=True) - - -def update_event(uzbl, k, execute=True): +def update_event(uzbl, modstate, k, execute=True): '''Raise keycmd & modcmd update events.''' - keycmd, modcmd = k.get_keycmd(), k.get_modcmd() + keycmd, modcmd = k.get_keycmd(), ''.join(modstate) + k.get_modcmd() if k.is_modcmd: - uzbl.event('MODCMD_UPDATE', k) + logger.debug('modcmd_update, %s' % modcmd) + uzbl.event('MODCMD_UPDATE', modstate, k) else: - uzbl.event('KEYCMD_UPDATE', k) + logger.debug('keycmd_update, %s' % keycmd) + uzbl.event('KEYCMD_UPDATE', modstate, k) if uzbl.config.get('modcmd_updates', '1') == '1': - new_modcmd = k.get_modcmd() - if not new_modcmd: + new_modcmd = ''.join(modstate) + k.get_modcmd() + if not new_modcmd or not k.is_modcmd: del uzbl.config['modcmd'] elif new_modcmd == modcmd: @@ -293,54 +213,38 @@ def inject_str(str, index, inj): return "%s%s%s" % (str[:index], inj, str[index:]) -def get_keylet_and_key(uzbl, key, add=True): - '''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.''' - +def parse_key_event(uzbl, key): + ''' Build a set from the modstate part of the event, and pass all keys through modmap ''' keylet = uzbl.keylet - key = keylet.modmap_key(key) - if len(key) == 1: - return (keylet, key) - - modkey = "<%s>" % key.strip("<>") - - if keylet.key_ignored(modkey): - if add: - keylet.ignored.add(modkey) - - elif modkey in keylet.ignored: - keylet.ignored.remove(modkey) - modkey = keylet.find_addition(modkey) - - if keylet.key_ignored(modkey): - return (keylet, None) - - return (keylet, modkey) + modstate, key = splitquoted(key) + modstate = set(['<%s>' % keylet.modmap_key(k) for k in modstate.split('|') if k]) + + key = keylet.modmap_key(key) + return modstate, key def key_press(uzbl, key): '''Handle KEY_PRESS events. Things done by this function include: 1. Ignore all shift key presses (shift can be detected by capital chars) - 3. In non-modcmd mode: + 2. In non-modcmd mode: a. append char to keycmd - 4. If not in modcmd mode and a modkey was pressed set modcmd mode. - 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.''' + 3. If not in modcmd mode and a modkey was pressed set modcmd mode. + 4. Keycmd is updated and events raised if anything is changed.''' - (k, key) = get_keylet_and_key(uzbl, key.strip()) - if not key: - return + k = uzbl.keylet + modstate, key = parse_key_event(uzbl, key) + k.is_modcmd = any(not k.key_ignored(m) for m in modstate) - if key.lower() == '<space>' and not k.held and k.keycmd: + logger.debug('key press modstate=%s' % str(modstate)) + if key.lower() == 'space' and not k.is_modcmd and k.keycmd: k.keycmd = inject_str(k.keycmd, k.cursor, ' ') k.cursor += 1 - elif not k.held and len(key) == 1: - + elif not k.is_modcmd and len(key) == 1: if uzbl.config.get('keycmd_events', '1') != '1': + # TODO, make a note on what's going on here k.keycmd = '' k.cursor = 0 del uzbl.config['keycmd'] @@ -349,33 +253,29 @@ def key_press(uzbl, key): k.keycmd = inject_str(k.keycmd, k.cursor, key) k.cursor += 1 - elif len(key) > 1: - k.is_modcmd = True - if key not in k.held: - k.held.add(key) + elif len(key) == 1: + k.modcmd += key else: - k.is_modcmd = True - k.modcmd += key + if not k.key_ignored('<%s>' % key): + modstate.add('<%s>' % key) + k.is_modcmd = True - update_event(uzbl, k) + update_event(uzbl, modstate, k) def key_release(uzbl, key): '''Respond to KEY_RELEASE event. Things done by this function include: - 1. Remove the key from the keylet held list. - 2. If in a mod-command then raise a MODCMD_EXEC. - 3. Check if any modkey is held, if so set modcmd mode. - 4. Update the keycmd uzbl variable if anything changed.''' - - (k, key) = get_keylet_and_key(uzbl, key.strip(), add=False) + 1. If in a mod-command then raise a MODCMD_EXEC. + 2. Update the keycmd uzbl variable if anything changed.''' + k = uzbl.keylet + modstate, key = parse_key_event(uzbl, key) - if key in k.held: + if len(key) > 1: if k.is_modcmd: - uzbl.event('MODCMD_EXEC', k) + uzbl.event('MODCMD_EXEC', modstate, k) - k.held.remove(key) clear_modcmd(uzbl) @@ -385,7 +285,7 @@ def set_keycmd(uzbl, keycmd): k = uzbl.keylet k.keycmd = keycmd k.cursor = len(keycmd) - update_event(uzbl, k, False) + update_event(uzbl, set(), k, False) def inject_keycmd(uzbl, keycmd): @@ -394,7 +294,7 @@ def inject_keycmd(uzbl, keycmd): k = uzbl.keylet k.keycmd = inject_str(k.keycmd, k.cursor, keycmd) k.cursor += len(keycmd) - update_event(uzbl, k, False) + update_event(uzbl, set(), k, False) def append_keycmd(uzbl, keycmd): @@ -403,23 +303,29 @@ def append_keycmd(uzbl, keycmd): k = uzbl.keylet k.keycmd += keycmd k.cursor = len(k.keycmd) - update_event(uzbl, k, False) + update_event(uzbl, set(), k, False) -def keycmd_strip_word(uzbl, sep): +def keycmd_strip_word(uzbl, seps): ''' Removes the last word from the keycmd, similar to readline ^W ''' - sep = sep or ' ' + seps = seps or ' ' k = uzbl.keylet if not k.keycmd: return - head, tail = k.keycmd[:k.cursor].rstrip(sep), k.keycmd[k.cursor:] - rfind = head.rfind(sep) + head, tail = k.keycmd[:k.cursor].rstrip(seps), k.keycmd[k.cursor:] + rfind = -1 + for sep in seps: + p = head.rfind(sep) + if p >= 0 and rfind < p + 1: + rfind = p + 1 + if rfind == len(head) and head[-1] in seps: + rfind -= 1 head = head[:rfind] if rfind + 1 else '' k.keycmd = head + tail k.cursor = len(head) - update_event(uzbl, k, False) + update_event(uzbl, set(), k, False) def keycmd_backspace(uzbl, *args): @@ -431,7 +337,7 @@ def keycmd_backspace(uzbl, *args): k.keycmd = k.keycmd[:k.cursor-1] + k.keycmd[k.cursor:] k.cursor -= 1 - update_event(uzbl, k, False) + update_event(uzbl, set(), k, False) def keycmd_delete(uzbl, *args): @@ -442,14 +348,14 @@ def keycmd_delete(uzbl, *args): return k.keycmd = k.keycmd[:k.cursor] + k.keycmd[k.cursor+1:] - update_event(uzbl, k, False) + update_event(uzbl, set(), k, False) def keycmd_exec_current(uzbl, *args): '''Raise a KEYCMD_EXEC with the current keylet and then clear the keycmd.''' - uzbl.event('KEYCMD_EXEC', uzbl.keylet) + uzbl.event('KEYCMD_EXEC', set(), uzbl.keylet) clear_keycmd(uzbl) @@ -476,7 +382,7 @@ def set_cursor_pos(uzbl, index): cursor = len(k.keycmd) k.cursor = cursor - update_event(uzbl, k, False) + update_event(uzbl, set(), k, False) # plugin init hook @@ -485,8 +391,6 @@ def init(uzbl): connect_dict(uzbl, { 'APPEND_KEYCMD': append_keycmd, - 'FOCUS_GAINED': focus_changed, - 'FOCUS_LOST': focus_changed, 'IGNORE_KEY': add_key_ignore, 'INJECT_KEYCMD': inject_keycmd, 'KEYCMD_BACKSPACE': keycmd_backspace, @@ -496,7 +400,8 @@ def init(uzbl): 'KEYCMD_CLEAR': clear_keycmd, 'KEY_PRESS': key_press, 'KEY_RELEASE': key_release, - 'MODKEY_ADDITION': modkey_addition_parse, + 'MOD_PRESS': key_press, + 'MOD_RELEASE': key_release, 'MODMAP': modmap_parse, 'SET_CURSOR_POS': set_cursor_pos, 'SET_KEYCMD': set_keycmd, @@ -504,7 +409,6 @@ def init(uzbl): export_dict(uzbl, { 'add_key_ignore': add_key_ignore, - 'add_modkey_addition': add_modkey_addition, 'add_modmap': add_modmap, 'append_keycmd': append_keycmd, 'clear_current': clear_current, |