23
from itertools import chain
23
24
from bzrlib.errors import BzrError
24
from bzrlib.commands import get_cmd_object
25
from bzrlib.commands import get_cmd_object, get_all_cmds
27
SHELL_BLACKLIST = set(['rm', 'ls'])
28
COMPLETION_BLACKLIST = set(['shell'])
30
class BlackListedCommand(BzrError):
31
def __init__(self, command):
32
BzrError.__init__(self, "The command %s is blacklisted for shell use" %
35
class CompletionContext(object):
36
def __init__(self, text, command=None, prev_opt=None, arg_pos=None):
38
self.command = command
39
self.prev_opt = prev_opt
42
def get_completions(self):
44
iter = (c for c in iter_command_names() if
45
c not in COMPLETION_BLACKLIST)
48
arg = line.split()[-1]
51
iter = list(iter_munged_completions(iter, arg, text))
26
57
class PromptCmd(cmd.Cmd):
27
58
def __init__(self):
105
136
def do_help(self, line):
137
self.default("help "+line)
108
139
def default(self, line):
109
140
args = line.split()
110
141
commandname = args.pop(0)
142
for char in ('|', '<', '>'):
143
commandname = commandname.split(char)[0]
144
if commandname[-1] in ('|', '<', '>'):
145
commandname = commandname[:-1]
147
if commandname in SHELL_BLACKLIST:
148
raise BlackListedCommand(commandname)
112
149
cmd_obj = get_cmd_object(commandname)
150
except (BlackListedCommand, BzrError):
114
151
return os.system(line)
118
return (cmd_obj.run_argv(args) or 0)
154
if too_complicated(line):
155
return os.system("bzr "+line)
157
return (cmd_obj.run_argv(args) or 0)
119
158
except BzrError, e:
121
160
except KeyboardInterrupt, e:
128
167
def completenames(self, text, line, begidx, endidx):
130
iter = iter_command_names(self.fake_aba)
169
iter = (c for c in iter_command_names() if
170
c not in COMPLETION_BLACKLIST)
132
172
if len(line) > 0:
133
173
arg = line.split()[-1]
136
iter = cmdutil.iter_munged_completions(iter, arg, text)
176
iter = list(iter_munged_completions(iter, arg, text))
137
177
except Exception, e:
139
179
return list(iter)
141
181
def completedefault(self, text, line, begidx, endidx):
150
190
:param endidx: The end of the text in the line
151
191
:type endidx: int
154
(cmd, args, foo) = self.parseline(line)
155
command_obj=find_command(cmd)
193
(cmd, args, foo) = self.parseline(line)
196
return self.completenames(text, line, begidx, endidx)
200
command_obj = get_cmd_object(cmd)
156
204
if command_obj is not None:
157
return command_obj.complete(args.split(), text)
158
elif not self.fake_aba.is_command(cmd) and \
159
cmdutil.is_tla_command(cmd):
160
iter = cmdutil.iter_supported_switches(cmd)
162
arg = args.split()[-1]
165
if arg.startswith("-"):
166
return list(cmdutil.iter_munged_completions(iter, arg,
169
return list(cmdutil.iter_munged_completions(
170
cmdutil.iter_file_completions(arg), arg, text))
206
for option_name, option in command_obj.options().items():
207
opts.append("--" + option_name)
208
short_name = option.short_name()
210
opts.append("-" + short_name)
211
q = list(iter_munged_completions(opts, args, text))
212
return list(iter_munged_completions(opts, args, text))
173
213
elif cmd == "cd":
174
214
if len(args) > 0:
175
215
arg = args.split()[-1]
178
iter = cmdutil.iter_dir_completions(arg)
179
iter = cmdutil.iter_munged_completions(iter, arg, text)
218
iter = iter_dir_completions(arg)
219
iter = iter_munged_completions(iter, arg, text)
180
220
return list(iter)
181
221
elif len(args)>0:
182
222
arg = args.split()[-1]
183
iter = cmdutil.iter_file_completions(arg)
184
return list(cmdutil.iter_munged_completions(iter, arg, text))
223
iter = iter_file_completions(arg)
224
return list(iter_munged_completions(iter, arg, text))
186
226
return self.completenames(text, line, begidx, endidx)
187
227
except Exception, e:
195
prompt.write_history()
236
prompt.write_history()
237
except StopIteration:
197
240
def iter_file_completions(arg, only_dirs = False):
198
241
"""Generate an iterator that iterates through filename completions.
234
277
return iter_file_completions(arg, True)
279
def iter_command_names(hidden=False):
280
for real_cmd_name, cmd_class in get_all_cmds():
281
if not hidden and cmd_class.hidden:
283
for name in [real_cmd_name] + cmd_class.aliases:
284
# Don't complete on aliases that are prefixes of the canonical name
285
if name == real_cmd_name or not real_cmd_name.startswith(name):
288
def iter_munged_completions(iter, arg, text):
289
for completion in iter:
290
completion = str(completion)
291
if completion.startswith(arg):
292
yield completion[len(arg)-len(text):]+" "
294
def too_complicated(line):
295
for char in '|<>"\"*?':