diff options
Diffstat (limited to 'examples/data/uzbl/scripts/plugins/keycmd.py')
-rw-r--r-- | examples/data/uzbl/scripts/plugins/keycmd.py | 382 |
1 files changed, 0 insertions, 382 deletions
diff --git a/examples/data/uzbl/scripts/plugins/keycmd.py b/examples/data/uzbl/scripts/plugins/keycmd.py deleted file mode 100644 index 3dd6f37..0000000 --- a/examples/data/uzbl/scripts/plugins/keycmd.py +++ /dev/null @@ -1,382 +0,0 @@ -import re - -# Map these functions/variables in the plugins namespace to the uzbl object. -__export__ = ['clear_keycmd', 'set_keycmd', 'set_cursor_pos', 'get_keylet'] - -# Regular expression compile cache. -_RE_CACHE = {} - -# Hold the keylets. -UZBLS = {} - -# Simple key names map. -_SIMPLEKEYS = { - 'Control': 'Ctrl', - 'ISO_Left_Tab': 'Shift-Tab', - 'space':'Space', -} - -# Keycmd format which includes the markup for the cursor. -KEYCMD_FORMAT = "%s<span @cursor_style>%s</span>%s" - - -def escape(str): - '''Prevent outgoing keycmd values from expanding inside the - status_format.''' - - if not str: - return '' - - for char in ['\\', '@']: - if char in str: - str = str.replace(char, '\\'+char) - - return "@[%s]@" % str - - -def get_regex(regex): - '''Compiling regular expressions is a very time consuming so return a - pre-compiled regex match object if possible.''' - - if regex not in _RE_CACHE: - _RE_CACHE[regex] = re.compile(regex).match - - return _RE_CACHE[regex] - - -class Keylet(object): - '''Small per-instance object that tracks all the keys held and characters - typed.''' - - def __init__(self): - self.cmd = '' - self.cursor = 0 - self.held = [] - - # to_string() string building cache. - self._to_string = None - - self.modcmd = False - self.wasmod = False - - 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.''' - - 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 - - return self._to_string - - - def match(self, regex): - '''See if the keycmd string matches the given regex.''' - - return bool(get_regex(regex)(self.to_string())) - - -def make_simple(key): - '''Make some obscure names for some keys friendlier.''' - - # Remove left-right discrimination. - if key.endswith('_L') or key.endswith('_R'): - key = key[:-2] - - if key in _SIMPLEKEYS: - key = _SIMPLEKEYS[key] - - return key - - -def add_instance(uzbl, *args): - '''Create the Keylet object for this uzbl instance.''' - - UZBLS[uzbl] = Keylet() - - -def del_instance(uzbl, *args): - '''Delete the Keylet object for this uzbl instance.''' - - if uzbl in UZBLS: - del UZBLS[uzbl] - - -def get_keylet(uzbl): - '''Return the corresponding keylet for this uzbl instance.''' - - # Startup events are not correctly captured and sent over the uzbl socket - # yet so this line is needed because the INSTANCE_START event is lost. - if uzbl not in UZBLS: - add_instance(uzbl) - - keylet = UZBLS[uzbl] - keylet._to_string = None - return keylet - - -def clear_keycmd(uzbl): - '''Clear the keycmd for this uzbl instance.''' - - k = get_keylet(uzbl) - k.cmd = '' - k.cursor = 0 - k._to_string = None - - if k.modcmd: - k.wasmod = True - - k.modcmd = False - config = uzbl.get_config() - if 'keycmd' not in config or config['keycmd'] != '': - config['keycmd'] = '' - - uzbl.event('KEYCMD_CLEAR') - - -def update_event(uzbl, k): - '''Raise keycmd & modcmd update events.''' - - config = uzbl.get_config() - if k.modcmd: - keycmd = k.to_string() - uzbl.event('MODCMD_UPDATE', k) - if keycmd != k.to_string(): - return - - if 'modcmd_updates' in config and config['modcmd_updates'] != '1': - return - - return uzbl.set('keycmd', escape(keycmd)) - - if 'keycmd_events' in config and config['keycmd_events'] != '1': - return - - keycmd = k.cmd - uzbl.event('KEYCMD_UPDATE', k) - if keycmd != k.cmd: - return - - if not k.cmd: - return uzbl.set('keycmd', '') - - # Generate the pango markup for the cursor in the keycmd. - if k.cursor < len(k.cmd): - cursor = k.cmd[k.cursor] - - else: - cursor = ' ' - - chunks = map(escape, [k.cmd[:k.cursor], cursor, k.cmd[k.cursor+1:]]) - uzbl.set('keycmd', KEYCMD_FORMAT % tuple(chunks)) - - -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. - 6. Keycmd is updated and events raised if anything is changed.''' - - if key.startswith('Shift_'): - return - - if len(key) > 1: - key = make_simple(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': - 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: - 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: - config = uzbl.get_config() - if 'keycmd_events' not in config or config['keycmd_events'] == '1': - if len(key) == 1: - cmdmod = True - k.cmd = "%s%s%s" % (k.cmd[:k.cursor], key, k.cmd[k.cursor:]) - k.cursor += 1 - - elif k.cmd: - cmdmod = True - k.cmd = '' - k.cursor = 0 - - if cmdmod: - update_event(uzbl, 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 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. - 4. Update the keycmd uzbl variable if anything changed.''' - - if len(key) > 1: - key = make_simple(key) - - k = get_keylet(uzbl) - - cmdmod = False - if key in ['Shift', 'Tab'] and 'Shift-Tab' in k.held: - key = 'Shift-Tab' - - elif key in ['Shift', 'Alt'] and 'Meta' in k.held: - key = 'Meta' - - if key in k.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) - - -def set_keycmd(uzbl, keycmd): - '''Allow setting of the keycmd externally.''' - - k = get_keylet(uzbl) - k.wasmod = k.modcmd = False - k._to_string = None - k.cmd = keycmd - k.cursor = len(keycmd) - update_event(uzbl, k) - - -def set_cursor_pos(uzbl, index): - '''Allow setting of the cursor position externally. Supports negative - indexing.''' - - cursor = int(index.strip()) - k = get_keylet(uzbl) - - if cursor < 0: - cursor = len(k.cmd) + cursor - - if cursor < 0: - cursor = 0 - - if cursor > len(k.cmd): - cursor = len(k.cmd) - - k.cursor = cursor - update_event(uzbl, k) - - -def init(uzbl): - '''Connect handlers to uzbl events.''' - - connects = {'INSTANCE_START': add_instance, - 'INSTANCE_EXIT': del_instance, - 'KEY_PRESS': key_press, - 'KEY_RELEASE': key_release, - 'SET_KEYCMD': set_keycmd, - 'SET_CURSOR_POS': set_cursor_pos} - - uzbl.connect_dict(connects) |