diff options
-rw-r--r-- | lib/commandmanager.py | 2 | ||||
-rw-r--r-- | lib/completionmanager.py | 84 | ||||
-rw-r--r-- | lib/outputmanager.py | 2 | ||||
-rwxr-xr-x | pywhoisd_dataloader.py | 6 |
4 files changed, 83 insertions, 11 deletions
diff --git a/lib/commandmanager.py b/lib/commandmanager.py index 3a06f99..bec2a33 100644 --- a/lib/commandmanager.py +++ b/lib/commandmanager.py @@ -31,7 +31,7 @@ class CommandManager: if cmd in self.cmds: return self.cmds[cmd] else: - raise CmdNotFoundException(cmd + 'is not a valid command.') + raise CmdNotFoundException(cmd + ' is not a valid command.') def commands(self): return self.cmds.keys() diff --git a/lib/completionmanager.py b/lib/completionmanager.py index fe6f099..72458f8 100644 --- a/lib/completionmanager.py +++ b/lib/completionmanager.py @@ -1,9 +1,81 @@ +# Almost all code is based on themole completion. http://themole.nasel.com.ar + +import readline, re + +import sys + class CompletionManager: - def __init__(self): - pass + 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) + - def generate_commands(self): - pass + - def generate_parameters(self): - pass diff --git a/lib/outputmanager.py b/lib/outputmanager.py index d9d4af1..7427783 100644 --- a/lib/outputmanager.py +++ b/lib/outputmanager.py @@ -3,7 +3,7 @@ import sys class OutputManager: def __init__(self): - + self.last_line_length = 0 self.echo_output = True def line_break(self): diff --git a/pywhoisd_dataloader.py b/pywhoisd_dataloader.py index 7b80ef5..e67c853 100755 --- a/pywhoisd_dataloader.py +++ b/pywhoisd_dataloader.py @@ -10,7 +10,7 @@ from lib.exceptions import CmdNotFoundException, CommandException class Manager: def __init__(self): self.loader = None - self.completer = CompletionManager() + self.completer = CompletionManager(cmd_manager, self.loader) def start(self): try: @@ -34,7 +34,7 @@ class Manager: output_manager.normal('Usage: {0}'.format(cmd.usage(line[0]))).line_break() except CmdNotFoundException as err: - output_manager.error('Error: {0}'.format(str(err))).linebreak() + output_manager.error('Error: {0}'.format(str(err))).line_break() except EOFError: output_manager.line_break() @@ -44,8 +44,8 @@ class Manager: if __name__ == '__main__': try: - manager = Manager() cmd_manager = CommandManager() + manager = Manager() output_manager = OutputManager() manager.start() |