aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples/data/uzbl/plugins/bind.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/data/uzbl/plugins/bind.py')
-rw-r--r--examples/data/uzbl/plugins/bind.py92
1 files changed, 35 insertions, 57 deletions
diff --git a/examples/data/uzbl/plugins/bind.py b/examples/data/uzbl/plugins/bind.py
index 89b0831..ea04af6 100644
--- a/examples/data/uzbl/plugins/bind.py
+++ b/examples/data/uzbl/plugins/bind.py
@@ -12,10 +12,10 @@ And it is also possible to execute a function on activation:
import sys
import re
-# Export these variables/functions to uzbl.<name>
+# Export these functions to uzbl.<name>
__export__ = ['bind', 'del_bind', 'del_bind_by_glob', 'get_binds']
-# Hold the bind lists per uzbl instance.
+# Hold the bind dicts for each uzbl instance.
UZBLS = {}
# Commonly used regular expressions.
@@ -23,15 +23,7 @@ starts_with_mod = re.compile('^<([A-Z][A-Za-z0-9-_]*)>')
find_prompts = re.compile('<([^:>]*):(\"[^\"]*\"|\'[^\']*\'|[^>]*)>').split
# For accessing a bind glob stack.
-MOD_CMD, ON_EXEC, HAS_ARGS, GLOB, MORE = range(5)
-
-
-class BindParseError(Exception):
- pass
-
-
-def error(msg):
- sys.stderr.write('bind plugin: error: %s\n' % msg)
+ON_EXEC, HAS_ARGS, MOD_CMD, GLOB, MORE = range(5)
def ismodbind(glob):
@@ -40,25 +32,25 @@ def ismodbind(glob):
return bool(starts_with_mod.match(glob))
-def sort_mods(glob):
- '''Mods are sorted in the keylet.to_string() result so make sure that
- bind commands also have their mod keys sorted.'''
+def split_glob(glob):
+ '''Take a string of the form "<Mod1><Mod2>cmd _" and return a list of the
+ modkeys in the glob and the command.'''
- mods = []
+ mods = set()
while True:
match = starts_with_mod.match(glob)
if not match:
break
end = match.span()[1]
- mods.append(glob[:end])
+ mods.add(glob[:end].strip("<>"))
glob = glob[end:]
- return '%s%s' % (''.join(sorted(mods)), glob)
+ return (mods, glob)
def add_instance(uzbl, *args):
- UZBLS[uzbl] = {'binds': [], 'depth': 0, 'filter': [],
+ UZBLS[uzbl] = {'binds': [], 'depth': 0, 'stack': [],
'args': [], 'last_mode': ''}
@@ -94,7 +86,7 @@ def get_filtered_binds(uzbl):
bind_dict = get_bind_dict(uzbl)
if bind_dict['depth']:
- return list(bind_dict['filter'])
+ return list(bind_dict['stack'])
return list(bind_dict['binds'])
@@ -169,13 +161,13 @@ class Bind(object):
for glob in split[:-1:3]:
if glob.endswith('*'):
msg = "token '*' not at the end of a prompt bind: %r" % split
- raise BindParseError(msg)
+ raise SyntaxError(msg)
# Check that there is nothing like: fl<prompt1:><prompt2:>_
for glob in split[3::3]:
if not glob:
msg = 'found null segment after first prompt: %r' % split
- raise BindParseError(msg)
+ raise SyntaxError(msg)
stack = []
for (index, glob) in enumerate(reversed(split[::3])):
@@ -189,7 +181,8 @@ class Bind(object):
has_args = True if glob[-1] in ['*', '_'] else False
glob = glob[:-1] if has_args else glob
- stack.append((mod_cmd, on_exec, has_args, glob, index))
+ mods, glob = split_glob(glob)
+ stack.append((on_exec, has_args, mods, glob, index))
self.stack = list(reversed(stack))
self.is_global = (len(self.stack) == 1 and self.stack[0][MOD_CMD])
@@ -259,7 +252,6 @@ def bind(uzbl, glob, handler, *args, **kargs):
# Mods come from the keycmd sorted so make sure the modkeys in the bind
# command are sorted too.
- glob = sort_mods(glob)
del_bind_by_glob(uzbl, glob)
binds = get_binds(uzbl)
@@ -275,11 +267,11 @@ def parse_bind_event(uzbl, args):
'''Break "event BIND fl* = js follownums.js" into (glob, command).'''
if not args:
- return error('missing bind arguments')
+ raise ArgumentError('missing bind arguments')
split = map(unicode.strip, args.split('=', 1))
if len(split) != 2:
- return error('missing "=" in bind definition: %r' % args)
+ raise ArgumentError('missing delimiter in bind: %r' % args)
glob, command = split
bind(uzbl, glob, command)
@@ -307,40 +299,30 @@ def clear_stack(uzbl, mode):
if mode != "stack":
bind_dict = get_bind_dict(uzbl)
- bind_dict['filter'] = []
+ bind_dict['stack'] = []
bind_dict['depth'] = 0
bind_dict['args'] = []
bind_dict['last_mode'] = mode
-def filter_bind(uzbl, bind_dict, bind):
- '''Remove a bind from the stack filter list.'''
-
- if bind in bind_dict['filter']:
- bind_dict['filter'].remove(bind)
-
- if not bind_dict['filter']:
- uzbl.set_mode()
+def match_and_exec(uzbl, bind, depth, keylet, mod_event=False):
+ bind_dict = get_bind_dict(uzbl)
+ (on_exec, has_args, mod_cmd, glob, more) = bind[depth]
+ held = keylet.held
+ cmd = keylet.modcmd if mod_cmd else keylet.keycmd
-def match_and_exec(uzbl, bind, depth, keycmd):
- bind_dict = get_bind_dict(uzbl)
- (mod_cmd, on_exec, has_args, glob, more) = bind[depth]
+ if mod_cmd and held != mod_cmd:
+ return False
if has_args:
- if not keycmd.startswith(glob):
- if not mod_cmd:
- filter_bind(uzbl, bind_dict, bind)
-
+ if not cmd.startswith(glob):
return False
- args = [keycmd[len(glob):],]
-
- elif keycmd != glob:
- if not mod_cmd:
- filter_bind(uzbl, bind_dict, bind)
+ args = [cmd[len(glob):],]
+ elif cmd != glob:
return False
else:
@@ -356,12 +338,12 @@ def match_and_exec(uzbl, bind, depth, keycmd):
elif more:
if bind_dict['depth'] == depth:
globalcmds = [cmd for cmd in bind_dict['binds'] if cmd.is_global]
- bind_dict['filter'] = [bind,] + globalcmds
+ bind_dict['stack'] = [bind,] + globalcmds
bind_dict['args'] += args
bind_dict['depth'] = depth + 1
- elif bind not in bind_dict['filter']:
- bind_dict['filter'].append(bind)
+ elif bind not in bind_dict['stack']:
+ bind_dict['stack'].append(bind)
set_stack_mode(uzbl, bind.prompts[depth])
return False
@@ -377,49 +359,45 @@ def match_and_exec(uzbl, bind, depth, keycmd):
def keycmd_update(uzbl, keylet):
depth = get_stack_depth(uzbl)
- keycmd = keylet.get_keycmd()
for bind in get_filtered_binds(uzbl):
t = bind[depth]
if t[MOD_CMD] or t[ON_EXEC]:
continue
- if match_and_exec(uzbl, bind, depth, keycmd):
+ if match_and_exec(uzbl, bind, depth, keylet):
return
def keycmd_exec(uzbl, keylet):
depth = get_stack_depth(uzbl)
- keycmd = keylet.get_keycmd()
for bind in get_filtered_binds(uzbl):
t = bind[depth]
if t[MOD_CMD] or not t[ON_EXEC]:
continue
- if match_and_exec(uzbl, bind, depth, keycmd):
+ if match_and_exec(uzbl, bind, depth, keylet):
return uzbl.clear_keycmd()
def modcmd_update(uzbl, keylet):
depth = get_stack_depth(uzbl)
- keycmd = keylet.get_modcmd()
for bind in get_filtered_binds(uzbl):
t = bind[depth]
if not t[MOD_CMD] or t[ON_EXEC]:
continue
- if match_and_exec(uzbl, bind, depth, keycmd):
+ if match_and_exec(uzbl, bind, depth, keylet):
return
def modcmd_exec(uzbl, keylet):
depth = get_stack_depth(uzbl)
- keycmd = keylet.get_modcmd()
for bind in get_filtered_binds(uzbl):
t = bind[depth]
if not t[MOD_CMD] or not t[ON_EXEC]:
continue
- if match_and_exec(uzbl, bind, depth, keycmd):
+ if match_and_exec(uzbl, bind, depth, keylet):
return uzbl.clear_modcmd()