aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples
diff options
context:
space:
mode:
authorGravatar Mason Larobina <mason.larobina@gmail.com>2009-09-11 03:01:39 +0800
committerGravatar Mason Larobina <mason.larobina@gmail.com>2009-09-11 03:01:39 +0800
commit8d310055087fc84b33f07031ed1853279c4ff4a2 (patch)
tree43b85b9e2b96fd862e528dc029dc274020616d17 /examples
parenta4c2f07ca5dad85f8f965dd1462703c5a3f4e1b8 (diff)
Removed unnecessary class & commented code in the keycmd plugin.
Diffstat (limited to 'examples')
-rw-r--r--examples/data/uzbl/scripts/plugins/keycmd.py283
1 files changed, 169 insertions, 114 deletions
diff --git a/examples/data/uzbl/scripts/plugins/keycmd.py b/examples/data/uzbl/scripts/plugins/keycmd.py
index b96546d..bd38e25 100644
--- a/examples/data/uzbl/scripts/plugins/keycmd.py
+++ b/examples/data/uzbl/scripts/plugins/keycmd.py
@@ -1,11 +1,22 @@
-#TODO: Comment code.
-
import re
-# Regex build cache.
+# Map these functions/variables in the plugins namespace to the uzbl object.
+__export__ = ['clear_keycmd',]
+
+# Regular expression compile cache.
_RE_CACHE = {}
+# Hold the keylets.
+_UZBLS = {}
+
+# Simple key names map.
+_SIMPLEKEYS = {'Control': 'Ctrl', 'ISO_Left_Tab': 'Shift-Tab',}
+
+
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
@@ -13,6 +24,9 @@ def get_regex(regex):
class Keylet(object):
+ '''Small per-instance object that tracks all the keys held and characters
+ typed.'''
+
def __init__(self):
self.cmd = ""
self.held = []
@@ -28,19 +42,12 @@ class Keylet(object):
return "<Keycmd(%r)>" % self.to_string()
- def _clear(self):
- self.cmd = ""
- self._to_string = None
- if self._modcmd:
- self._wasmod = True
-
- self._modcmd = False
-
-
def to_string(self):
- '''Always of the form <Modkey1><ModKey2>+command'''
+ '''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:
@@ -55,12 +62,15 @@ class Keylet(object):
def match(self, regex):
+ '''See if the keycmd string matches the given regex.'''
+
return bool(get_regex(regex)(self.to_string()))
-_SIMPLEKEYS = {'Control': 'Ctrl', 'ISO_Left_Tab': 'Shift-Tab',}
+def make_simple(key):
+ '''Make some obscure names for some keys friendlier.'''
-def makesimple(key):
+ # Remove left-right discrimination.
if key.endswith("_L") or key.endswith("_R"):
key = key[:-2]
@@ -70,139 +80,184 @@ def makesimple(key):
return key
-class KeycmdTracker(dict):
- def key_press(self, uzbl, key):
- if key.startswith("Shift_"):
- return
+def add_instance(uzbl, *args):
+ '''Create the Keylet object for this uzbl instance.'''
- if len(key) > 1:
- key = makesimple(key)
+ _UZBLS[uzbl] = Keylet()
- k = self.get_keylet(uzbl)
- cmdmod = False
- if k.held and k._wasmod:
- k._modcmd = True
- k._wasmod = False
- cmdmod = True
+def del_instance(uzbl, *args):
+ '''Delete the Keylet object for this uzbl instance.'''
- if key == "space":
- if k.cmd:
- k.cmd += " "
- cmdmod = True
+ if uzbl in _UZBLS:
+ del _UZBLS[uzbl]
- 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
+def get_keylet(uzbl):
+ '''Return the corresponding keylet for this uzbl instance.'''
- elif key == "Return":
- uzbl.event("KEYCMD_EXEC", k)
- self.clear(uzbl)
+ # 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)
- elif key == "Escape":
- self.clear(uzbl)
+ keylet = _UZBLS[uzbl]
+ keylet._to_string = None
+ return keylet
- 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()
+def clear_keycmd(uzbl):
+ '''Clear the keycmd for this uzbl instance.'''
- else:
- k.cmd += key
+ k = get_keylet(uzbl)
+ if not k:
+ return
- else:
- cmdmod = True
- if len(key) == 1:
- if key not in k.held:
- k.held.append(key)
- k.held.sort()
+ k.cmd = ""
+ k._to_string = None
- k.cmd += key
+ if k._modcmd:
+ k._wasmod = True
- if cmdmod:
- self.update(uzbl, k)
+ k._modcmd = False
+ uzbl.config['keycmd'] = ""
+ uzbl.event("KEYCMD_CLEAR")
- 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)
-
- elif not k._modcmd and key in k.held:
- k.held.remove(key)
- k.held.sort()
+def update_event(uzbl, keylet):
+ '''Raise keycmd/modcmd update events.'''
+
+ 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 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 last character in the keycmd.
+ b. Return raises a KEYCMD_EXEC event then clears the keycmd.
+ c. Escape clears the keycmd.
+ d. Normal keys are added to held keys list (I.e. <a><b>+c).
+ 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)
+ if not k:
+ return
+
+ 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
- if not k.held and not k.cmd and k._wasmod:
- k._wasmod = False
+ elif not k._modcmd and key == 'BackSpace':
+ if k.cmd:
+ k.cmd = k.cmd[:-1]
+ if not k.cmd:
+ clear_keycmd(uzbl)
+
+ else:
+ cmdmod = True
- if cmdmod:
- self.update(uzbl, k)
+ elif not k._modcmd and key == 'Return':
+ uzbl.event("KEYCMD_EXEC", k)
+ clear_keycmd(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
- def update(self, uzbl, keylet):
- if keylet._modcmd:
- uzbl.config['keycmd'] = keylet.to_string()
- uzbl.event("MODCMD_UPDATE", keylet)
+ elif k._modcmd:
+ cmdmod = True
+ if len(key) > 1:
+ if key not in k.held:
+ k.held.append(key)
+ k.held.sort()
else:
- uzbl.config['keycmd'] = keylet.cmd
- uzbl.event("KEYCMD_UPDATE", keylet)
+ k.cmd += key
+
+ else:
+ cmdmod = True
+ if len(key) == 1:
+ if key not in k.held:
+ k.held.append(key)
+ k.held.sort()
+
+ k.cmd += key
+ if cmdmod:
+ update_event(uzbl, k)
- 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 key_release(uzbl, key):
+ '''Respond to KEY_RELEASE event. Things done by this function include:
- def clear(self, uzbl):
- self.get_keylet(uzbl)._clear()
- uzbl.config['keycmd'] = ""
- uzbl.event("KEYCMD_CLEAR")
+ 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)
- def add_instance(self, uzbl, *args):
- self[uzbl] = Keylet()
+ k = get_keylet(uzbl)
+ if not k:
+ return
+ cmdmod = False
+ if k._modcmd and key in k.held:
+ uzbl.event("MODCMD_EXEC", k)
+ k.held.remove(key)
+ k.held.sort()
+ clear_keycmd(uzbl)
- def del_instance(self, uzbl, *args):
- if uzbl in self:
- del 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
-keycmd = KeycmdTracker()
-export_clear_keycmd = keycmd.clear
+ if cmdmod:
+ update_event(uzbl, k)
def init(uzbl):
+ '''Connect handlers to uzbl events.'''
- uzbl.connect('INSTANCE_START', keycmd.add_instance)
- uzbl.connect('INSTANCE_STOP', keycmd.del_instance)
- uzbl.connect('KEY_PRESS', keycmd.key_press)
- uzbl.connect('KEY_RELEASE', keycmd.key_release)
+ uzbl.connect('INSTANCE_START', add_instance)
+ uzbl.connect('INSTANCE_STOP', del_instance)
+ uzbl.connect('KEY_PRESS', key_press)
+ uzbl.connect('KEY_RELEASE', key_release)