Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/services/console/lib/purk/scripts/completion.py
blob: 1719702c2261963acbb11d68993a9c545fbf36bb (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
124
125
126
127
128
129
130
131
132
133
134
135
import windows
import chaninfo
from conf import conf

def channel_completer(window, left, right, text):
    if isinstance(window, windows.ChannelWindow):
        yield window.id

    for w in windows.get_with(wclass=windows.ChannelWindow, network=window.network):
        if w is not window:
            yield w.id

    for w in windows.get_with(wclass=windows.ChannelWindow):
        if w.network is not window.network:
            yield w.id

# normal server commands
srv_commands = ('ping', 'join', 'part', 'mode', 'server', 'kick',
                'quit', 'nick', 'privmsg', 'notice', 'topic')
            
def command_completer(window, left, right, text):
    for c in srv_commands:
        yield '/%s' % c
    
    if 'CMDS' in window.network.isupport:
        for c in window.network.isupport['CMDS'].split(','):
            yield '/%s' % c.lower()
    
    for c in core.events.all_events:
        if c.startswith('Command') and c != 'Command':
            yield '/%s' % c[7:].lower()

def nick_completer(window, left, right, text):  
    if type(window) == windows.QueryWindow:
        yield window.id
    
    recent_speakers = getattr(window, 'recent_speakers', ())
    
    for nick in recent_speakers:
        if chaninfo.ison(window.network, window.id, nick):
            yield nick

    for nick in chaninfo.nicks(window.network, window.id):
        if nick not in recent_speakers:
            yield nick
    
def script_completer(window, left, right, text):
    return core.events.loaded.iterkeys()
    
def network_completer(window, left, right, text):
    return conf.get('networks', {}).iterkeys()

def get_completer_for(window):
    input = window.input

    left, right = input.text[:input.cursor], input.text[input.cursor:]
            
    text = left.split(' ')[-1]

    while True:
        suffix = ''
        if text and text[0] in window.network.isupport.get('CHANTYPES', '#&+'):
            candidates = channel_completer(window, left, right, text)
            
        elif input.text.startswith('/reload '):
            candidates = script_completer(window, left, right, text)
        
        elif input.text.startswith('/edit '):
            candidates = script_completer(window, left, right, text)
            
        elif input.text.startswith('/server '):
            candidates = network_completer(window, left, right, text)
            
        elif text.startswith('/'):
            candidates = command_completer(window, left, right, text)
            suffix = ' '
            
        else:
            candidates = nick_completer(window, left, right, text)
            
            if left == text:
                suffix = ': '
            else:
                suffix = ' '
                
        if text:
            before = left[:-len(text)]
        else:
            before = left
            
        insert_text = '%s%s%s%s' % (before, '%s', suffix, right)
        cursor_pos = len(before + suffix)

        original = window.input.text, window.input.cursor

        for cand in candidates:
            if cand.lower().startswith(text.lower()):
                window.input.text, window.input.cursor = insert_text % cand, cursor_pos + len(cand)
                yield None
                
        window.input.text, window.input.cursor = original
        yield None
     
# generator--use recent_completer.next() to continue cycling through whatever
recent_completer = None

def onKeyPress(e):
    global recent_completer

    if e.key == 'Tab':
        if not recent_completer:
            recent_completer = get_completer_for(e.window)

        recent_completer.next()
    
    else:
        recent_completer = None

def onActive(e):
    global recent_completer
    
    recent_completer = None

def onText(e):
    if chaninfo.ischan(e.network, e.target):
        if not hasattr(e.window, 'recent_speakers'):
            e.window.recent_speakers = []

        for nick in e.window.recent_speakers:
            if nick == e.source or not chaninfo.ison(e.network, e.target, nick):
                e.window.recent_speakers.remove(nick)

        e.window.recent_speakers.insert(0, e.source)

onAction = onText