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,
})
|