diff options
Diffstat (limited to 'examples/data/uzbl/plugins/keycmd.py')
-rw-r--r-- | examples/data/uzbl/plugins/keycmd.py | 213 |
1 files changed, 98 insertions, 115 deletions
diff --git a/examples/data/uzbl/plugins/keycmd.py b/examples/data/uzbl/plugins/keycmd.py index 3dd6f37..79a96e4 100644 --- a/examples/data/uzbl/plugins/keycmd.py +++ b/examples/data/uzbl/plugins/keycmd.py @@ -57,12 +57,22 @@ class Keylet(object): self._to_string = None self.modcmd = False - self.wasmod = False + + def mod_held(self): + ''' returns true if any modkey is held. ''' + return any([len(x) != 1 for x in self.held]) + + def key_cmd(self): + ''' get the keycmd-part of the keylet. ''' + return self.cmd + + def mod_cmd(self): + ''' get the modcmd-part of the keylet. ''' + return ''.join(['<%s>' % key for key in self.held]) def __repr__(self): return '<Keycmd(%r)>' % self.to_string() - def to_string(self): '''Return a string representation of the keys held and pressed that have been recorded.''' @@ -70,15 +80,8 @@ class Keylet(object): if self._to_string is not None: # Return cached keycmd string. return self._to_string - - if not self.held: - self._to_string = self.cmd - - else: - self._to_string = ''.join(['<%s>' % key for key in self.held]) - if self.cmd: - self._to_string += self.cmd - + + self._to_string = self.mod_cmd() + self.key_cmd() return self._to_string @@ -135,10 +138,7 @@ def clear_keycmd(uzbl): k.cursor = 0 k._to_string = None - if k.modcmd: - k.wasmod = True - - k.modcmd = False + k.modcmd = k.mod_held() config = uzbl.get_config() if 'keycmd' not in config or config['keycmd'] != '': config['keycmd'] = '' @@ -146,13 +146,14 @@ def clear_keycmd(uzbl): uzbl.event('KEYCMD_CLEAR') -def update_event(uzbl, k): +def update_event(uzbl, k, execute=True): '''Raise keycmd & modcmd update events.''' config = uzbl.get_config() if k.modcmd: keycmd = k.to_string() - uzbl.event('MODCMD_UPDATE', k) + if execute: + uzbl.event('MODCMD_UPDATE', k) if keycmd != k.to_string(): return @@ -165,7 +166,8 @@ def update_event(uzbl, k): return keycmd = k.cmd - uzbl.event('KEYCMD_UPDATE', k) + if execute: + uzbl.event('KEYCMD_UPDATE', k) if keycmd != k.cmd: return @@ -187,19 +189,10 @@ 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) - 2. Re-enable modcmd var if the user presses another key with at least one - modkey still held from the previous modcmd (I.e. <Ctrl>+t, clear & - <Ctrl>+o without having to re-press <Ctrl>) 3. In non-modcmd mode: - a. BackSpace deletes the character before the cursor position. - b. Delete deletes the character at the cursor position. - c. End moves the cursor to the end of the keycmd. - d. Home moves the cursor to the beginning of the keycmd. - e. Return raises a KEYCMD_EXEC event then clears the keycmd. - f. Escape clears the keycmd. - 4. If keycmd and held keys are both empty/null and a modkey was pressed - set modcmd mode. - 5. If in modcmd mode only mod keys are added to the held keys list. + 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.''' if key.startswith('Shift_'): @@ -210,82 +203,17 @@ def key_press(uzbl, key): k = get_keylet(uzbl) cmdmod = False - if k.held and k.wasmod: - k.modcmd = True - k.wasmod = False - cmdmod = True - if k.cmd and key == 'Space': + if k.cmd and not k.modcmd and key == 'Space': k.cmd = "%s %s" % (k.cmd[:k.cursor], k.cmd[k.cursor:]) k.cursor += 1 cmdmod = True - elif not k.modcmd and k.cmd and key in ['BackSpace', 'Delete']: - if key == 'BackSpace' and k.cursor > 0: - k.cursor -= 1 - k.cmd = k.cmd[:k.cursor] + k.cmd[k.cursor+1:] - - elif key == 'Delete': - cmd = k.cmd - k.cmd = k.cmd[:k.cursor] + k.cmd[k.cursor+1:] - if k.cmd != cmd: - cmdmod = True - - if not k.cmd: - clear_keycmd(uzbl) - - elif key == 'BackSpace': - cmdmod = True - - elif not k.modcmd and key == 'Return': - if k.cmd: - uzbl.event('KEYCMD_EXEC', k) - - clear_keycmd(uzbl) - - elif not k.modcmd and key == 'Escape': - clear_keycmd(uzbl) - - elif not k.modcmd and k.cmd and key == 'Left': - if k.cursor > 0: - k.cursor -= 1 - cmdmod = True - - elif not k.modcmd and k.cmd and key == 'Right': - if k.cursor < len(k.cmd): - k.cursor += 1 - cmdmod = True - - elif not k.modcmd and k.cmd and key == 'End': - if k.cursor != len(k.cmd): - k.cursor = len(k.cmd) - cmdmod = True - - elif not k.modcmd and k.cmd and key == 'Home': - if k.cursor: - k.cursor = 0 - cmdmod = True - - elif not k.held and not k.cmd and len(key) > 1: + elif len(key) > 1: k.modcmd = True - k.held.append(key) - cmdmod = True - - elif k.modcmd: cmdmod = True - if len(key) > 1: - if key == 'Shift-Tab' and 'Tab' in k.held: - k.held.remove('Tab') - - if key not in k.held: - k.held.append(key) - k.held.sort() - else: - k.cmd = "%s%s%s" % (k.cmd[:k.cursor], key, k.cmd[k.cursor:]) - k.cursor += 1 - - else: + elif not k.modcmd: config = uzbl.get_config() if 'keycmd_events' not in config or config['keycmd_events'] == '1': if len(key) == 1: @@ -298,6 +226,15 @@ def key_press(uzbl, key): k.cmd = '' k.cursor = 0 + if k.modcmd: + if key == 'Shift-Tab' and 'Tab' in k.held: + k.held.remove('Tab') + + if key not in k.held: + k.held.append(key) + k.held.sort() + cmdmod = True + if cmdmod: update_event(uzbl, k) @@ -306,10 +243,8 @@ 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 the key removed was a mod key and it was in a mod-command then - raise a MODCMD_EXEC event then clear the keycmd. - 3. Stop trying to restore mod-command status with wasmod if both the - keycmd and held list are empty/null. + 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.''' if len(key) > 1: @@ -325,15 +260,12 @@ def key_release(uzbl, key): key = 'Meta' if key in k.held: + cmdmod = True + k.held.remove(key) + k.modcmd = k.mod_held() if k.modcmd: uzbl.event('MODCMD_EXEC', k) - k.held.remove(key) - clear_keycmd(uzbl) - - if not k.held and not k.cmd and k.wasmod: - k.wasmod = False - if cmdmod: update_event(uzbl, k) @@ -342,22 +274,70 @@ def set_keycmd(uzbl, keycmd): '''Allow setting of the keycmd externally.''' k = get_keylet(uzbl) - k.wasmod = k.modcmd = False + k.modcmd = False k._to_string = None k.cmd = keycmd k.cursor = len(keycmd) - update_event(uzbl, k) + + update_event(uzbl, k, False) + + +def keycmd_strip_word(uzbl, sep): + ''' Removes the last word from the keycmd, similar to readline ^W ''' + sep = sep or ' ' + k = get_keylet(uzbl) + if not k.cmd: + return + + cmd = k.cmd[:k.cursor] + tail = len(k.cmd) - k.cursor + + if sep in cmd: + tmp = cmd.rstrip(sep).rsplit(sep, 1) + else: + tmp = ('',) + + k.cmd = tmp[0] + (sep if len(tmp) == 2 else '') + k.cmd[k.cursor:] + k.cursor = len(tmp[0]) + (len(tmp) - 1) + + assert len(k.cmd) - k.cursor == tail, "tail size changed (%s) (%s - %s)" % (tail, len(k.cmd), k.cursor) + + update_event(uzbl, k, False) + + +def keycmd_backspace(uzbl, _foo): + ''' Removes the last char of the keycmd ''' + k = get_keylet(uzbl) + if not k.cmd: + return + + k.cmd = k.cmd[:k.cursor-1] + k.cmd[k.cursor:] + k.cursor -= 1 + + update_event(uzbl, k, False) + + +def keycmd_exec_current(uzbl, _foo): + ''' Raise a KEYCMD_EXEC with the current keylet and then clear the keycmd ''' + k = get_keylet(uzbl) + uzbl.event('KEYCMD_EXEC', k) + clear_keycmd(uzbl) def set_cursor_pos(uzbl, index): '''Allow setting of the cursor position externally. Supports negative - indexing.''' + indexing and relative stepping with '+' and '-'.''' - cursor = int(index.strip()) k = get_keylet(uzbl) - if cursor < 0: - cursor = len(k.cmd) + cursor + if index == '-': + cursor = k.cursor - 1 + elif index == '+': + cursor = k.cursor + 1 + else: + cursor = int(index.strip()) + if cursor < 0: + cursor = len(k.cmd) + cursor + 1 if cursor < 0: cursor = 0 @@ -366,7 +346,7 @@ def set_cursor_pos(uzbl, index): cursor = len(k.cmd) k.cursor = cursor - update_event(uzbl, k) + update_event(uzbl, k, False) def init(uzbl): @@ -377,6 +357,9 @@ def init(uzbl): 'KEY_PRESS': key_press, 'KEY_RELEASE': key_release, 'SET_KEYCMD': set_keycmd, + 'KEYCMD_STRIP_WORD': keycmd_strip_word, + 'KEYCMD_BACKSPACE': keycmd_backspace, + 'KEYCMD_EXEC_CURRENT': keycmd_exec_current, 'SET_CURSOR_POS': set_cursor_pos} uzbl.connect_dict(connects) |