1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 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,
})
|