aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--examples/config/uzbl/config22
-rw-r--r--examples/data/uzbl/plugins/bind.py85
-rw-r--r--examples/data/uzbl/plugins/completion.py33
-rw-r--r--examples/data/uzbl/plugins/config.py16
-rw-r--r--examples/data/uzbl/plugins/keycmd.py134
-rw-r--r--examples/data/uzbl/plugins/mode.py132
-rw-r--r--examples/data/uzbl/plugins/on_event.py8
-rwxr-xr-xexamples/data/uzbl/scripts/scheme.py2
-rwxr-xr-xexamples/data/uzbl/scripts/uzbl-event-manager12
9 files changed, 296 insertions, 148 deletions
diff --git a/examples/config/uzbl/config b/examples/config/uzbl/config
index 8abe554..29cb365 100644
--- a/examples/config/uzbl/config
+++ b/examples/config/uzbl/config
@@ -3,7 +3,7 @@
set prefix = /usr/local
-# === Shortcuts ==============================================================
+# === Shortcuts / Aliases ===================================================
# request BIND <keycmd> = <command>
set bind = request BIND
@@ -19,6 +19,8 @@ set progress = request PROGRESS_CONFIG
set modmap = request MODMAP
# request IGNORE_KEY <glob>
set ignore_key = request IGNORE_KEY
+# request MODKEY_ADDITION <key1> <key2> <keyn> <result>
+set modkey_addition = request MODKEY_ADDITION
set set_mode = set mode =
set set_status = set status_message =
@@ -108,25 +110,32 @@ set socket_dir = /tmp
# === Key modmapping and ignoring ============================================
-#modmap from to
+#modmap <From> <To>
@modmap <Control> <Ctrl>
@modmap <ISO_Left_Tab> <Shift-Tab>
@modmap <space> <Space>
+#modkey_addition <Key1> <Key2> <Result>
+@modkey_addition <Shift> <Ctrl> <Meta>
+@modkey_addition <Shift> <Tab> <Shift-Tab>
+
#ignore_key <glob>
@ignore_key <ISO_*>
@ignore_key <Shift>
+
# === Keyboard & Mouse bindings ==============================================
# With this command you can enter in any command at runtime when prefixed with
# a colon.
-@bind :_ = chain '%s'
+@bind :_ = %s
# Middle click
# if clicked on a link open the link in a new uzbl window
# otherwise open the selection in the current window
-@bind <Button2> = sh 'if [ "\@SELECTED_URI" ]; then uzbl-browser -u \@SELECTED_URI; else echo "uri $(xclip -o)" > $4; fi'
+set load_from_xclip = sh 'echo "uri $(xclip -o)" > $4'
+set open_new_window = sh 'uzbl-browser -u \@SELECTED_URI'
+@bind <Button2> = js if("\@SELECTED_URI") { Uzbl.run("\@open_new_window"); } else { Uzbl.run("\\\@load_from_xclip"); }
@bind j = scroll vertical 20
@bind <Page_Down> = scroll vertical 100%
@@ -157,7 +166,7 @@ set socket_dir = /tmp
@bind gh = uri http://www.uzbl.org
# shortcut to set variables
@bind s _ = set %s
-@bind \wiki _ = uri http://wiki.archlinux.org/index.php/Special:Search?search=%s&go=Go
+@bind \\wiki _ = uri http://wiki.archlinux.org/index.php/Special:Search?search=%s&go=Go
@bind gg _ = uri http://www.google.com/search?q=%s
# Enclose the executable in quotes if it has spaces. Any additional parameters you use will
# appear AFTER the default parameters
@@ -285,6 +294,7 @@ set stack = @mode_config stack
# Multi-stage-binding mode config.
@stack keycmd_events = 1
@stack modcmd_updates = 1
+@stack forward_keys = 0
@stack keycmd_style = foreground="red"
@stack prompt_style = foreground="#888" weight="light"
@stack status_background = #202020
@@ -300,7 +310,7 @@ set default_mode = command
set toggle_cmd_ins = @toggle_modes command insert
@bind i = @toggle_cmd_ins
-@bind <Ctrl><i> = @toggle_cmd_ins
+@bind <Ctrl>i = @toggle_cmd_ins
# === Post-load misc commands ===============================================
diff --git a/examples/data/uzbl/plugins/bind.py b/examples/data/uzbl/plugins/bind.py
index 530cc80..3169b15 100644
--- a/examples/data/uzbl/plugins/bind.py
+++ b/examples/data/uzbl/plugins/bind.py
@@ -17,6 +17,7 @@ __export__ = ['bind', 'del_bind', 'del_bind_by_glob', 'get_binds']
# Hold the bind dicts for each uzbl instance.
UZBLS = {}
+DEFAULTS = {'binds': [], 'depth': 0, 'stack': [], 'args': [], 'last_mode': ''}
# Commonly used regular expressions.
starts_with_mod = re.compile('^<([A-Z][A-Za-z0-9-_]*)>')
@@ -50,8 +51,7 @@ def split_glob(glob):
def add_instance(uzbl, *args):
- UZBLS[uzbl] = {'binds': [], 'depth': 0, 'stack': [],
- 'args': [], 'last_mode': ''}
+ UZBLS[uzbl] = dict(DEFAULTS)
def del_instance(uzbl, *args):
@@ -259,7 +259,6 @@ def bind(uzbl, glob, handler, *args, **kargs):
bind = Bind(glob, handler, *args, **kargs)
binds.append(bind)
- print bind
uzbl.event('ADDED_BIND', bind)
@@ -277,36 +276,64 @@ def parse_bind_event(uzbl, args):
bind(uzbl, glob, command)
-def set_stack_mode(uzbl, prompt):
- prompt, set = prompt
+def mode_changed(uzbl, mode):
+ '''Clear the stack on all non-stack mode changes.'''
+
+ if mode != 'stack':
+ clear_stack(uzbl)
+
+
+def clear_stack(uzbl):
+ '''Clear everything related to stacked binds.'''
+
+ bind_dict = get_bind_dict(uzbl)
+ bind_dict['stack'] = []
+ bind_dict['depth'] = 0
+ bind_dict['args'] = []
+ if bind_dict['last_mode']:
+ uzbl.set_mode(bind_dict['last_mode'])
+ bind_dict['last_mode'] = ''
+
+ uzbl.set('keycmd_prompt', force=False)
+
+
+def stack_bind(uzbl, bind, args, depth):
+ '''Increment the stack depth in the bind dict, generate filtered bind
+ list for stack mode and set keycmd prompt.'''
+
+ bind_dict = get_bind_dict(uzbl)
+ if bind_dict['depth'] != depth:
+ if bind not in bind_dict['stack']:
+ bind_dict['stack'].append(bind)
+
+ return
+
if uzbl.get_mode() != 'stack':
+ bind_dict['last_mode'] = uzbl.get_mode()
uzbl.set_mode('stack')
+ globalcmds = [cmd for cmd in bind_dict['binds'] if cmd.is_global]
+ bind_dict['stack'] = [bind,] + globalcmds
+ bind_dict['args'] += args
+ bind_dict['depth'] = depth + 1
+
+ uzbl.send('event BIND_STACK_LEVEL %d' % bind_dict['depth'])
+
+ (prompt, set) = bind.prompts[depth]
if prompt:
- prompt = "%s: " % prompt
+ uzbl.set('keycmd_prompt', '%s:' % prompt)
- uzbl.set('keycmd_prompt', prompt)
+ else:
+ uzbl.set('keycmd_prompt')
if set:
- # Go through uzbl-core to expand potential @-variables
uzbl.send('event SET_KEYCMD %s' % set)
-
-def clear_stack(uzbl, mode):
- bind_dict = get_bind_dict(uzbl)
- if mode != "stack" and bind_dict['last_mode'] == "stack":
- uzbl.set('keycmd_prompt', '')
-
- if mode != "stack":
- bind_dict = get_bind_dict(uzbl)
- bind_dict['stack'] = []
- bind_dict['depth'] = 0
- bind_dict['args'] = []
-
- bind_dict['last_mode'] = mode
+ else:
+ uzbl.clear_keycmd()
-def match_and_exec(uzbl, bind, depth, keylet, mod_event=False):
+def match_and_exec(uzbl, bind, depth, keylet):
bind_dict = get_bind_dict(uzbl)
(on_exec, has_args, mod_cmd, glob, more) = bind[depth]
@@ -336,22 +363,14 @@ def match_and_exec(uzbl, bind, depth, keylet, mod_event=False):
return True
elif more:
- if bind_dict['depth'] == depth:
- globalcmds = [cmd for cmd in bind_dict['binds'] if cmd.is_global]
- bind_dict['stack'] = [bind,] + globalcmds
- bind_dict['args'] += args
- bind_dict['depth'] = depth + 1
-
- elif bind not in bind_dict['stack']:
- bind_dict['stack'].append(bind)
-
- set_stack_mode(uzbl, bind.prompts[depth])
+ stack_bind(uzbl, bind, args, depth)
return False
args = bind_dict['args'] + args
exec_bind(uzbl, bind, *args)
uzbl.set_mode()
if not has_args:
+ clear_stack(uzbl)
uzbl.clear_current()
return True
@@ -407,6 +426,6 @@ def init(uzbl):
'MODCMD_UPDATE': modcmd_update,
'KEYCMD_EXEC': keycmd_exec,
'MODCMD_EXEC': modcmd_exec,
- 'MODE_CHANGED': clear_stack}
+ 'MODE_CHANGED': mode_changed}
uzbl.connect_dict(connects)
diff --git a/examples/data/uzbl/plugins/completion.py b/examples/data/uzbl/plugins/completion.py
index 2da42ba..42e7e17 100644
--- a/examples/data/uzbl/plugins/completion.py
+++ b/examples/data/uzbl/plugins/completion.py
@@ -9,13 +9,13 @@ import re
UZBLS = {}
# Completion level
-NONE, ONCE, LIST = range(3)
+NONE, ONCE, LIST, COMPLETE = range(4)
# Default instance dict.
DEFAULTS = {'completions': [], 'level': NONE, 'lock': False}
# The reverse keyword finding re.
-FIND_SEGMENT = re.compile("(\@[\w_]+|[\w_]+)$").findall
+FIND_SEGMENT = re.compile("(\@[\w_]+|set[\s]+[\w_]+|[\w_]+)$").findall
# Formats
LIST_FORMAT = "<span> %s </span>"
@@ -52,7 +52,11 @@ def get_incomplete_keyword(uzbl):
keylet = uzbl.get_keylet()
left_segment = keylet.keycmd[:keylet.cursor]
- return (FIND_SEGMENT(left_segment) + ['',])[0].lstrip()
+ partial = (FIND_SEGMENT(left_segment) + ['',])[0].lstrip()
+ if partial.startswith('set '):
+ return ('@%s' % partial[4:].lstrip(), True)
+
+ return (partial, False)
def stop_completion(uzbl, *args):
@@ -63,11 +67,16 @@ def stop_completion(uzbl, *args):
uzbl.set('completion_list')
-def complete_completion(uzbl, partial, hint):
+def complete_completion(uzbl, partial, hint, set_completion=False):
'''Inject the remaining porition of the keyword into the keycmd then stop
the completioning.'''
- remainder = "%s " % hint[len(partial):]
+ if set_completion:
+ remainder = "%s = " % hint[len(partial):]
+
+ else:
+ remainder = "%s " % hint[len(partial):]
+
uzbl.inject_keycmd(remainder)
stop_completion(uzbl)
@@ -83,12 +92,12 @@ def update_completion_list(uzbl, *args):
'''Checks if the user still has a partially completed keyword under his
cursor then update the completion hints list.'''
- partial = get_incomplete_keyword(uzbl)
+ partial = get_incomplete_keyword(uzbl)[0]
if not partial:
return stop_completion(uzbl)
d = get_completion_dict(uzbl)
- if d['level'] != LIST:
+ if d['level'] < LIST:
return
hints = [h for h in d['completions'] if h.startswith(partial)]
@@ -106,11 +115,11 @@ def start_completion(uzbl, *args):
if d['lock']:
return
- partial = get_incomplete_keyword(uzbl)
+ (partial, set_completion) = get_incomplete_keyword(uzbl)
if not partial:
return stop_completion(uzbl)
- if d['level'] < LIST:
+ if d['level'] < COMPLETE:
d['level'] += 1
hints = [h for h in d['completions'] if h.startswith(partial)]
@@ -119,13 +128,13 @@ def start_completion(uzbl, *args):
elif len(hints) == 1:
d['lock'] = True
- complete_completion(uzbl, partial, hints[0])
+ complete_completion(uzbl, partial, hints[0], set_completion)
d['lock'] = False
return
- elif partial in hints:
+ elif partial in hints and d['level'] == COMPLETE:
d['lock'] = True
- complete_completion(uzbl, partial, partial)
+ complete_completion(uzbl, partial, partial, set_completion)
d['lock'] = False
return
diff --git a/examples/data/uzbl/plugins/config.py b/examples/data/uzbl/plugins/config.py
index 57c2403..47b59f9 100644
--- a/examples/data/uzbl/plugins/config.py
+++ b/examples/data/uzbl/plugins/config.py
@@ -22,12 +22,16 @@ def get_config(uzbl):
return UZBLS[uzbl]
-def set(uzbl, key, value=''):
- '''Sends a: "set key = value" command to the uzbl instance.'''
+def set(uzbl, key, value='', force=True):
+ '''Sends a: "set key = value" command to the uzbl instance. If force is
+ False then only send a set command if the values aren't equal.'''
if type(value) == types.BooleanType:
value = int(value)
+ else:
+ value = unicode(value)
+
if not _VALIDSETKEY(key):
raise KeyError("%r" % key)
@@ -35,6 +39,11 @@ def set(uzbl, key, value=''):
if '\n' in value:
value = value.replace("\n", "\\n")
+ if not force:
+ config = get_config(uzbl)
+ if key in config and config[key] == value:
+ return
+
uzbl.send('set %s = %s' % (key, value))
@@ -61,8 +70,7 @@ class ConfigDict(dict):
def __setitem__(self, key, value):
'''Makes "config[key] = value" a wrapper for the set function.'''
- if key not in self or unicode(self[key]) != unicode(value):
- set(self._uzbl, key, value)
+ set(self._uzbl, key, value, force=False)
def variable_set(uzbl, args):
diff --git a/examples/data/uzbl/plugins/keycmd.py b/examples/data/uzbl/plugins/keycmd.py
index b1e8299..4c88fd8 100644
--- a/examples/data/uzbl/plugins/keycmd.py
+++ b/examples/data/uzbl/plugins/keycmd.py
@@ -3,7 +3,7 @@ import re
# Map these functions/variables in the plugins namespace to the uzbl object.
__export__ = ['clear_keycmd', 'set_keycmd', 'set_cursor_pos', 'get_keylet',
'clear_current', 'clear_modcmd', 'add_modmap', 'add_key_ignore',
- 'append_keycmd', 'inject_keycmd']
+ 'append_keycmd', 'inject_keycmd', 'add_modkey_addition']
# Hold the keylets.
UZBLS = {}
@@ -42,6 +42,7 @@ class Keylet(object):
self.modmaps = {}
self.ignores = {}
+ self.additions = {}
# Keylet string repr cache.
self._repr_cache = None
@@ -76,6 +77,25 @@ class Keylet(object):
return key
+ def find_addition(self, modkey):
+ '''Key has just been pressed, check if this key + the held list
+ results in a modkey addition. Return that addition and remove all
+ modkeys that created it.'''
+
+ already_added = self.held & set(self.additions.keys())
+ for key in already_added:
+ if modkey in self.additions[key]:
+ return key
+
+ modkeys = set(list(self.held) + [modkey,])
+ for (key, value) in self.additions.items():
+ if modkeys.issuperset(value):
+ self.held = modkeys ^ value
+ return key
+
+ return modkey
+
+
def key_ignored(self, key):
'''Check if the given key is ignored by any ignore rules.'''
@@ -107,7 +127,20 @@ class Keylet(object):
def add_modmap(uzbl, key, map):
- '''Add modmaps.'''
+ '''Add modmaps.
+
+ Examples:
+ set modmap = request MODMAP
+ @modmap <Control> <Ctrl>
+ @modmap <ISO_Left_Tab> <Shift-Tab>
+ ...
+
+ Then:
+ @bind <Shift-Tab> = <command1>
+ @bind <Ctrl>x = <command2>
+ ...
+
+ '''
assert len(key)
modmaps = get_keylet(uzbl).modmaps
@@ -131,7 +164,14 @@ def modmap_parse(uzbl, map):
def add_key_ignore(uzbl, glob):
- '''Add an ignore definition.'''
+ '''Add an ignore definition.
+
+ Examples:
+ set ignore_key = request IGNORE_KEY
+ @ignore_key <Shift>
+ @ignore_key <ISO_*>
+ ...
+ '''
assert len(glob) > 1
ignores = get_keylet(uzbl).ignores
@@ -144,6 +184,45 @@ def add_key_ignore(uzbl, glob):
uzbl.event('NEW_KEY_IGNORE', glob)
+def add_modkey_addition(uzbl, modkeys, result):
+ '''Add a modkey addition definition.
+
+ Examples:
+ set mod_addition = request MODKEY_ADDITION
+ @mod_addition <Shift> <Control> <Meta>
+ @mod_addition <Left> <Up> <Left-Up>
+ @mod_addition <Right> <Up> <Right-Up>
+ ...
+
+ Then:
+ @bind <Right-Up> = <command1>
+ @bind <Meta>o = <command2>
+ ...
+ '''
+
+ additions = get_keylet(uzbl).additions
+ modkeys = set(modkeys)
+
+ assert len(modkeys) and result and result not in modkeys
+
+ for (existing_result, existing_modkeys) in additions.items():
+ if existing_result != result:
+ assert modkeys != existing_modkeys
+
+ additions[result] = modkeys
+ uzbl.event('NEW_MODKEY_ADDITION', modkeys, result)
+
+
+def modkey_addition_parse(uzbl, modkeys):
+ '''Parse modkey addition definition.'''
+
+ keys = filter(None, map(unicode.strip, modkeys.split(" ")))
+ keys = ['<%s>' % key.strip("<>") for key in keys if key.strip("<>")]
+
+ assert len(keys) > 1
+ add_modkey_addition(uzbl, keys[:-1], keys[-1])
+
+
def add_instance(uzbl, *args):
'''Create the Keylet object for this uzbl instance.'''
@@ -234,8 +313,11 @@ def update_event(uzbl, k, execute=True):
if 'modcmd_updates' not in config or config['modcmd_updates'] == '1':
new_modcmd = k.get_modcmd()
- if not new_modcmd or new_modcmd == modcmd:
- uzbl.set('modcmd', uzbl_escape(new_modcmd))
+ if not new_modcmd:
+ uzbl.set('modcmd')
+
+ elif new_modcmd == modcmd:
+ uzbl.set('modcmd', "<span> %s </span>" % uzbl_escape(new_modcmd))
if 'keycmd_events' in config and config['keycmd_events'] != '1':
return
@@ -256,14 +338,23 @@ def inject_str(str, index, inj):
return "%s%s%s" % (str[:index], inj, str[index:])
-def chevronate(key):
- '''If a modkey isn't already chevronated then chevronate it. Ignore all
- other keys.'''
+def get_keylet_and_key(uzbl, key):
+ '''Return the keylet and apply any transformations to the key as defined
+ by the modmapping or modkey addition rules. Return None if the key is
+ ignored.'''
+ keylet = get_keylet(uzbl)
+ key = keylet.modmap_key(key)
if len(key) == 1:
- return key
+ return (keylet, key)
+
+ modkey = "<%s>" % key.strip("<>")
+ modkey = keylet.find_addition(modkey)
+
+ if keylet.key_ignored(modkey):
+ return (keylet, None)
- return "<%s>" % key.strip("<>")
+ return (keylet, modkey)
def key_press(uzbl, key):
@@ -276,10 +367,8 @@ def key_press(uzbl, key):
5. If in modcmd mode the pressed key is added to the held keys list.
6. Keycmd is updated and events raised if anything is changed.'''
- k = get_keylet(uzbl)
- key = chevronate(k.modmap_key(key.strip()))
-
- if k.key_ignored(key):
+ (k, key) = get_keylet_and_key(uzbl, key.strip())
+ if not key:
return
if key.lower() == '<space>' and not k.held and k.keycmd:
@@ -301,9 +390,6 @@ def key_press(uzbl, key):
elif len(key) > 1:
k.is_modcmd = True
- if key == '<Shift-Tab>' and '<Tab>' in k.held:
- k.held.remove('<Tab>')
-
if key not in k.held:
k.held.add(key)
@@ -322,14 +408,9 @@ def key_release(uzbl, key):
3. Check if any modkey is held, if so set modcmd mode.
4. Update the keycmd uzbl variable if anything changed.'''
- k = get_keylet(uzbl)
- key = chevronate(k.modmap_key(key))
-
- if key in ['<Shift>', '<Tab>'] and '<Shift-Tab>' in k.held:
- key = '<Shift-Tab>'
-
- elif key in ['<Shift>', '<Alt>'] and '<Meta>' in k.held:
- key = '<Meta>'
+ (k, key) = get_keylet_and_key(uzbl, key.strip())
+ if not key:
+ return
if key in k.held:
if k.is_modcmd:
@@ -461,6 +542,7 @@ def init(uzbl):
'MODMAP': modmap_parse,
'APPEND_KEYCMD': append_keycmd,
'INJECT_KEYCMD': inject_keycmd,
- 'IGNORE_KEY': add_key_ignore}
+ 'IGNORE_KEY': add_key_ignore,
+ 'MODKEY_ADDITION': modkey_addition_parse}
uzbl.connect_dict(connects)
diff --git a/examples/data/uzbl/plugins/mode.py b/examples/data/uzbl/plugins/mode.py
index e7705a0..52b104a 100644
--- a/examples/data/uzbl/plugins/mode.py
+++ b/examples/data/uzbl/plugins/mode.py
@@ -1,30 +1,26 @@
import sys
import re
-__export__ = ['set_mode', 'get_mode']
+__export__ = ['set_mode', 'get_mode', 'set_mode_config', 'get_mode_config']
UZBLS = {}
DEFAULTS = {
'mode': '',
- 'default': '',
'modes': {
'insert': {
'forward_keys': True,
'keycmd_events': False,
'modcmd_updates': False,
- 'indicator': 'I'},
+ 'mode_indicator': 'I'},
'command': {
'forward_keys': False,
'keycmd_events': True,
'modcmd_updates': True,
- 'indicator': 'C'}}}
+ 'mode_indicator': 'C'}}}
-_RE_FINDSPACES = re.compile("\s+")
-
-
-def error(msg):
- sys.stderr.write("mode plugin: error: %s\n" % msg)
+FINDSPACES = re.compile("\s+")
+VALID_KEY = re.compile("^[\w_]+$").match
def add_instance(uzbl, *args):
@@ -37,6 +33,8 @@ def del_instance(uzbl, *args):
def get_mode_dict(uzbl):
+ '''Return the mode dict for an instance.'''
+
if uzbl not in UZBLS:
add_instance(uzbl)
@@ -44,6 +42,8 @@ def get_mode_dict(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] = {}
@@ -55,28 +55,13 @@ def get_mode(uzbl):
return get_mode_dict(uzbl)['mode']
-def key_press(uzbl, key):
- if key != "Escape":
- return
-
- set_mode(uzbl)
+def mode_changed(uzbl, mode):
+ '''The mode has just been changed, now set the per-mode config.'''
-
-def set_mode(uzbl, mode=None):
- mode_dict = get_mode_dict(uzbl)
- if mode is None:
- if not mode_dict['default']:
- return error("no default mode to fallback on")
-
- mode = mode_dict['default']
+ get_mode_dict(uzbl)['mode'] = mode
config = uzbl.get_config()
- if 'mode' not in config or config['mode'] != mode:
- config['mode'] = mode
-
- mode_dict['mode'] = mode
mode_config = get_mode_config(uzbl, mode)
-
for (key, value) in mode_config.items():
if key not in config:
config[key] = value
@@ -88,35 +73,55 @@ def set_mode(uzbl, mode=None):
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
+ return
+
+ elif get_mode(uzbl) == mode:
+ return
+
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':
- mode_dict = get_mode_dict(uzbl)
- mode_dict['default'] = value
- if value and not mode_dict['mode']:
+ if not get_mode(uzbl):
set_mode(uzbl, value)
elif key == 'mode':
- if not value:
- value = None
-
set_mode(uzbl, value)
-def mode_config(uzbl, args):
-
- split = map(unicode.strip, _RE_FINDSPACES.split(args.lstrip(), 1))
- if len(split) != 2:
- return error("invalid MODE_CONFIG syntax: %r" % args)
+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.'''
- mode, set = split
- split = map(unicode.strip, set.split('=', 1))
- if len(split) != 2:
- return error("invalid MODE_CONFIG set command: %r" % args)
+ assert VALID_KEY(mode) and VALID_KEY(key)
- key, value = split
mode_config = get_mode_config(uzbl, mode)
mode_config[key] = value
@@ -124,25 +129,35 @@ def mode_config(uzbl, args):
uzbl.set(key, value)
-def load_reset(uzbl, *args):
- config = uzbl.get_config()
- if 'reset_on_commit' not in config or config['reset_on_commit'] == '1':
- set_mode(uzbl)
+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.'''
- modelist = [s.strip() for s in modes.split(' ') if s]
- if not len(modelist):
- return error("no modes specified to toggle")
+ assert len(modes.strip())
- mode_dict = get_mode_dict(uzbl)
- oldmode = mode_dict['mode']
- if oldmode not in modelist:
- return set_mode(uzbl, modelist[0])
+ 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)
- newmode = modelist[(modelist.index(oldmode)+1) % len(modelist)]
- set_mode(uzbl, newmode)
+ set_mode(uzbl, modelist[index])
def init(uzbl):
@@ -150,9 +165,8 @@ def init(uzbl):
connects = {'CONFIG_CHANGED': config_changed,
'INSTANCE_EXIT': del_instance,
'INSTANCE_START': add_instance,
- 'KEY_PRESS': key_press,
'MODE_CONFIG': mode_config,
- 'LOAD_START': load_reset,
- 'TOGGLE_MODES': toggle_modes}
+ 'TOGGLE_MODES': toggle_modes,
+ 'MODE_CHANGED': mode_changed}
uzbl.connect_dict(connects)
diff --git a/examples/data/uzbl/plugins/on_event.py b/examples/data/uzbl/plugins/on_event.py
index 3dfc3fa..afee4e6 100644
--- a/examples/data/uzbl/plugins/on_event.py
+++ b/examples/data/uzbl/plugins/on_event.py
@@ -1,7 +1,7 @@
'''Plugin provides arbitrary binding of uzbl events to uzbl commands.
Formatting options:
- %@ = space separated string of the arguments
+ %s = space separated string of the arguments
%1 = argument 1
%2 = argument 2
%n = argument n
@@ -45,10 +45,10 @@ def get_on_events(uzbl):
def expand(cmd, args):
- '''Replaces "%@ %1 %2 %3..." with "<all args> <arg 0> <arg 1>...".'''
+ '''Replaces "%s %1 %2 %3..." with "<all args> <arg 0> <arg 1>...".'''
- if '%@' in cmd:
- cmd = cmd.replace('%@', ' '.join(map(unicode, args)))
+ if '%s' in cmd:
+ cmd = cmd.replace('%s', ' '.join(map(unicode, args)))
for (index, arg) in enumerate(args):
index += 1
diff --git a/examples/data/uzbl/scripts/scheme.py b/examples/data/uzbl/scripts/scheme.py
index 7286703..a54476f 100755
--- a/examples/data/uzbl/scripts/scheme.py
+++ b/examples/data/uzbl/scripts/scheme.py
@@ -16,7 +16,7 @@ if __name__ == '__main__':
uri = sys.argv[8]
u = urlparse.urlparse(uri)
if u.scheme == 'mailto':
- detach_open(['xterm', '-e', 'mail %s' % u.path])
+ detach_open(['xterm', '-e', 'mail %r' % u.path])
elif u.scheme == 'xmpp':
detach_open(['gajim-remote', 'open_chat', uri])
elif u.scheme == 'git':
diff --git a/examples/data/uzbl/scripts/uzbl-event-manager b/examples/data/uzbl/scripts/uzbl-event-manager
index 8f43836..0054ff6 100755
--- a/examples/data/uzbl/scripts/uzbl-event-manager
+++ b/examples/data/uzbl/scripts/uzbl-event-manager
@@ -343,6 +343,7 @@ class UzblInstance(object):
self._parent = parent
self._client_socket = client_socket
+ self.depth = 0
self.buffer = ''
# Call the init() function in every plugin. Inside the init function
@@ -397,12 +398,13 @@ class UzblInstance(object):
def send(self, msg):
'''Send a command to the uzbl instance via the socket file.'''
+ msg = msg.strip()
if self._client_socket:
- print '<-- %s' % msg
+ print '%s<-- %s' % (' ' * self.depth, msg)
self._client_socket.send(("%s\n" % msg).encode('utf-8'))
else:
- print '!-- %s' % msg
+ print '%s!-- %s' % (' ' * self.depth, msg)
def connect(self, event, handler, *args, **kargs):
@@ -468,18 +470,22 @@ class UzblInstance(object):
# Silence _printing_ of geo events while debugging.
if event != "GEOMETRY_CHANGED":
- print "--> %s %s %s" % (event, args, '' if not kargs else kargs)
+ print "%s--> %s %s %s" % (' ' * self.depth, event, args,
+ '' if not kargs else kargs)
if event not in self._handlers:
return
for handler in self._handlers[event]:
+ self.depth += 1
try:
self.exec_handler(handler, *args, **kargs)
except:
print_exc()
+ self.depth -= 1
+
def close(self):
'''Close the client socket and clean up.'''