summaryrefslogtreecommitdiff
path: root/lib/completionmanager.py
blob: 72458f816eb61bee6bd348ddb1a00b6a5d2ae93f (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
# Almost all code is based on themole completion. http://themole.nasel.com.ar

import readline, re

import sys

class CompletionManager:
    def __init__(self, cmd_manager, loader):
        self.manager = cmd_manager
        self.loader = loader

        readline.parse_and_bind("tab: complete")
        readline.set_completer(self.completer)
        readline.set_completer_delims(' \t\n`~!@#$%^&*()=+[{]}\\|;:\'",<>/?')

        self.parse_regex = re.compile('("[^"]*"|\'[^\']+\')')

    def completer(self, text, state):
        if readline.get_begidx() == 0:
            return self.generate_commands(text, state)
        else:
            return self.generate_parameters(text, state)

    def get_completion(self, text, state):
        if self.current == len(self.available):
            return None
        else:
            tmp = self.available[self.current]
            self.current += 1

            return tmp + ' '

    def generate_commands(self, text, state):
        if state == 0:
            self.available = []
            self.current = 0

            for c in self.manager.commands():
                if c[0:len(text)] == text:
                    self.available.append(c)

            self.available.sort()
            if len(self.available) == 1 and self.available[0] == text:
                self.available = []
                self.current = 0

                return text + ' '                

        return self.get_completion(text, state)            

    def generate_parameters(self, text, state):
        if state == 0:
            self.available = []
            self.current = 0
      
            try:
                line = readline.get_line_buffer()[:readline.get_endidx()].split(' ')
                cmd = self.manager.find(line[0])
            except:
                return 0

            current_params = list(filter(lambda x: len(x.strip()) > 0, line[1:-1] if len(line) > 2 else []))
            if ',' in text:
                text = text.split(',')[-1]

            for i in cmd.parameters(self.loader, current_params):
                if i[:len(text)] == text:
                    self.available.append(i)

            self.available.sort()
            if len(self.available) == 1:
                self.available = []
                self.current = 0

                return text + cmd.parameter_separator(current_params)

        return self.get_completion(text, state)


            
nihil fit ex nihilo