16 # Call the completer when tab is hit
17 readline.set_completer(self.complete)
18 readline.parse_and_bind('tab: complete')
20 readline.set_completion_display_matches_hook(self.display_matches)
22 # remove some word breaks
24 readline.set_completer_delims(delims)
26 def display_matches(self, sustitution, matches, longest_match_length):
30 print("%s%s"%(self.prompt, readline.get_line_buffer()),
31 end = "", flush = True)
32 readline.forced_update_display()
34 def add_context(self, name, ctx):
35 assert(not name in self.contexts), "duplicate context name %s"%(name)
36 self.contexts[name] = ctx
38 def set_context(self, name):
39 self.context = self.contexts[name]
41 def set_prompt(self, prompt):
44 def complete(self, text, state):
47 # state is not 0, the list of completions is already stored in
48 # self.completions[]: just return the next one
50 if state >= len(self.completions):
52 return self.completions[state]
54 # else, try to build the completion list
56 line = readline.get_line_buffer() # full line
57 end = readline.get_endidx() # cursor
59 #print("<%s>"%origline[:end])
62 tokens = shlex.split(in_buf, comments = False) # XXX check all calls to shlex
63 # whitespace after the first token, it means we want to complete
65 if len(tokens) == 0 or not in_buf.endswith(tokens[-1]):
67 completions = self.context.complete(tokens)
69 # Build the completion list in the readline format (a list of
70 # string). It may include the help if tab is pressed twice.
72 completion_type = readline.get_completion_type()
73 # completion_key = readline.get_completion_invoking_key() # XXX
75 if chr(completion_type) == "?":
77 help_str = c.cmd.get_help()
79 self.completions.append(c.cmd.to_expr() + ": " + help_str)
81 self.completions.append(c.token)
83 self.completions.append(c.token + ": " + help_str)
84 # check if it matches the command, in this case display [return]
85 # XXX does it work well?
87 for cmd in self.context:
88 result = cmd.match(tokens)
90 self.completions.append("[return]")
96 if c.terminal == True:
97 self.completions.append(c.token + " ")
99 self.completions.append(c.token)
101 if len(self.completions) == 0:
104 return self.completions[0]
107 traceback.print_exc()
111 def input_loop(self):
113 while line != 'stop':
115 line = input(self.prompt)
116 except KeyboardInterrupt:
122 tokens = shlex.split(line, comments = True) # XXX
125 assert(self.context != None), "context not set, use set_context()"
127 for cmd in self.context:
128 result = cmd.match(tokens)
132 print("Invalid command or syntax error")
134 assert(cmd.cb != None), \
135 "no callback function for %s"%(cmd)