aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples/data/uzbl/plugins/on_event.py
blob: 9d2525b678d11b337a277c5f89b00b36336c86d2 (plain)
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
'''Plugin provides arbitrary binding of uzbl events to uzbl commands.

Formatting options:
  %s = space separated string of the arguments
  %r = escaped and quoted version of %s
  %1 = argument 1
  %2 = argument 2
  %n = argument n

Usage:
  request ON_EVENT LINK_HOVER set selected_uri = $1
    --> LINK_HOVER http://uzbl.org/
    <-- set selected_uri = http://uzbl.org/

  request ON_EVENT CONFIG_CHANGED print Config changed: %1 = %2
    --> CONFIG_CHANGED selected_uri http://uzbl.org/
    <-- print Config changed: selected_uri = http://uzbl.org/
'''

import sys
import re

__export__ = ['get_on_events', 'on_event']

UZBLS = {}


def error(msg):
    sys.stderr.write('on_event plugin: error: %s\n' % msg)


def add_instance(uzbl, *args):
    UZBLS[uzbl] = {}


def del_instance(uzbl, *args):
    if uzbl in UZBLS:
        del UZBLS[uzbl]


def get_on_events(uzbl):
    if uzbl not in UZBLS:
        add_instance(uzbl)

    return UZBLS[uzbl]


def expand(cmd, args):
    '''Replaces "%s %1 %2 %3..." with "<all args> <arg 0> <arg 1>...".'''

    # Direct string replace.
    if '%s' in cmd:
        cmd = cmd.replace('%s', ' '.join(map(unicode, args)))

    # Escaped and quoted string replace.
    if '%r' in cmd:
        joined = ('%r' % ' '.join(map(unicode, args)))[1:]
        for char in ['\\', '@']:
            joined = joined.replace(char, '\\'+char)

        cmd = cmd.replace('%r', joined)

    # Arg index string replace.
    for (index, arg) in enumerate(args):
        index += 1
        if '%%%d' % index in cmd:
            cmd = cmd.replace('%%%d' % index, unicode(arg))

    return cmd


def event_handler(uzbl, *args, **kargs):
    '''This function handles all the events being watched by various
    on_event definitions and responds accordingly.'''

    events = get_on_events(uzbl)
    event = kargs['on_event']
    if event not in events:
        return

    commands = events[event]
    for cmd in commands:
        cmd = expand(cmd, args)
        uzbl.send(cmd)


def on_event(uzbl, event, cmd):
    '''Add a new event to watch and respond to.'''

    event = event.upper()
    events = get_on_events(uzbl)
    if event not in events:
        uzbl.connect(event, event_handler, on_event=event)
        events[event] = []

    cmds = events[event]
    if cmd not in cmds:
        cmds.append(cmd)


def parse_on_event(uzbl, args):
    '''Parse ON_EVENT events and pass them to the on_event function.

    Syntax: "event ON_EVENT <EVENT_NAME> commands".'''

    if not args:
        return error("missing on_event arguments")

    split = args.split(' ', 1)
    if len(split) != 2:
        return error("invalid ON_EVENT syntax: %r" % args)

    event, cmd = split
    on_event(uzbl, event, cmd)


def init(uzbl):

    connects = {'ON_EVENT': parse_on_event,
      'INSTANCE_START': add_instance,
      'INSTANCE_EXIT': del_instance}

    uzbl.connect_dict(connects)