aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples/data/plugins/mode.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/data/plugins/mode.py')
-rw-r--r--examples/data/plugins/mode.py176
1 files changed, 176 insertions, 0 deletions
diff --git a/examples/data/plugins/mode.py b/examples/data/plugins/mode.py
new file mode 100644
index 0000000..54d865a
--- /dev/null
+++ b/examples/data/plugins/mode.py
@@ -0,0 +1,176 @@
+import sys
+import re
+
+__export__ = ['set_mode', 'get_mode', 'set_mode_config', 'get_mode_config']
+
+UZBLS = {}
+
+DEFAULTS = {
+ 'mode': '',
+ 'modes': {
+ 'insert': {
+ 'forward_keys': True,
+ 'keycmd_events': False,
+ 'modcmd_updates': False,
+ 'mode_indicator': 'I'},
+ 'command': {
+ 'forward_keys': False,
+ 'keycmd_events': True,
+ 'modcmd_updates': True,
+ 'mode_indicator': 'C'}}}
+
+FINDSPACES = re.compile("\s+")
+VALID_KEY = re.compile("^[\w_]+$").match
+
+
+def add_instance(uzbl, *args):
+ UZBLS[uzbl] = dict(DEFAULTS)
+
+
+def del_instance(uzbl, *args):
+ if uzbl in UZBLS:
+ del UZBLS[uzbl]
+
+
+def get_mode_dict(uzbl):
+ '''Return the mode dict for an instance.'''
+
+ if uzbl not in UZBLS:
+ add_instance(uzbl)
+
+ return UZBLS[uzbl]
+
+
+def get_mode_config(uzbl, mode):
+ '''Return the mode config for a given mode.'''
+
+ modes = get_mode_dict(uzbl)['modes']
+ if mode not in modes:
+ modes[mode] = {}
+
+ return modes[mode]
+
+
+def get_mode(uzbl):
+ return get_mode_dict(uzbl)['mode']
+
+
+def mode_changed(uzbl, mode):
+ '''The mode has just been changed, now set the per-mode config.'''
+
+ if get_mode(uzbl) != mode:
+ return
+
+ config = uzbl.get_config()
+ mode_config = get_mode_config(uzbl, mode)
+ for (key, value) in mode_config.items():
+ uzbl.set(key, value, config=config)
+
+ if 'mode_indicator' not in mode_config:
+ config['mode_indicator'] = mode
+
+ uzbl.clear_keycmd()
+ uzbl.clear_modcmd()
+
+
+def set_mode(uzbl, mode=None):
+ '''Set the mode and raise the MODE_CHANGED event if the mode has changed.
+ Fallback on the default mode if no mode argument was given and the default
+ mode is not null.'''
+
+ config = uzbl.get_config()
+ mode_dict = get_mode_dict(uzbl)
+ if mode is None:
+ mode_dict['mode'] = ''
+ if 'default_mode' in config:
+ mode = config['default_mode']
+
+ else:
+ mode = 'command'
+
+ if not VALID_KEY(mode):
+ raise KeyError("invalid mode name: %r" % mode)
+
+ if 'mode' not in config or config['mode'] != mode:
+ config['mode'] = mode
+
+ elif mode_dict['mode'] != mode:
+ mode_dict['mode'] = mode
+ uzbl.event("MODE_CHANGED", mode)
+
+
+def config_changed(uzbl, key, value):
+ '''Check for mode related config changes.'''
+
+ value = None if not value else value
+ if key == 'default_mode':
+ if not get_mode(uzbl):
+ set_mode(uzbl, value)
+
+ elif key == 'mode':
+ set_mode(uzbl, value)
+
+
+def set_mode_config(uzbl, mode, key, value):
+ '''Set mode specific configs. If the mode being modified is the current
+ mode then apply the changes on the go.'''
+
+ assert VALID_KEY(mode) and VALID_KEY(key)
+
+ mode_config = get_mode_config(uzbl, mode)
+ mode_config[key] = value
+
+ if get_mode(uzbl) == mode:
+ uzbl.set(key, value)
+
+
+def mode_config(uzbl, args):
+ '''Parse mode config events.'''
+
+ split = map(unicode.strip, FINDSPACES.split(args.lstrip(), 1))
+ if len(split) != 2:
+ raise SyntaxError('invalid mode config syntax: %r' % args)
+
+ mode, set = split
+ split = map(unicode.strip, set.split('=', 1))
+ if len(split) != 2:
+ raise SyntaxError('invalid set syntax: %r' % args)
+
+ key, value = split
+ set_mode_config(uzbl, mode, key, value)
+
+
+def toggle_modes(uzbl, modes):
+ '''Toggle or cycle between or through a list of modes.'''
+
+ assert len(modes.strip())
+
+ modelist = filter(None, map(unicode.strip, modes.split(' ')))
+ mode = get_mode(uzbl)
+
+ index = 0
+ if mode in modelist:
+ index = (modelist.index(mode)+1) % len(modelist)
+
+ set_mode(uzbl, modelist[index])
+
+
+def init(uzbl):
+ # Event handling hooks.
+ uzbl.connect_dict({
+ 'CONFIG_CHANGED': config_changed,
+ 'INSTANCE_EXIT': del_instance,
+ 'INSTANCE_START': add_instance,
+ 'MODE_CHANGED': mode_changed,
+ 'MODE_CONFIG': mode_config,
+ 'TOGGLE_MODES': toggle_modes,
+ })
+
+ # Function exports to the uzbl object, `function(uzbl, *args, ..)`
+ # becomes `uzbl.function(*args, ..)`.
+ uzbl.export_dict({
+ 'get_mode': get_mode,
+ 'get_mode_config': get_mode_config,
+ 'set_mode': set_mode,
+ 'set_mode_config': set_mode_config,
+ })