23
23
from itertools import chain
24
24
from bzrlib.errors import BzrError
25
25
from bzrlib.commands import get_cmd_object, get_all_cmds
26
from bzrlib.branch import Branch
27
28
SHELL_BLACKLIST = set(['rm', 'ls'])
29
COMPLETION_BLACKLIST = set(['shell'])
29
31
class BlackListedCommand(BzrError):
30
32
def __init__(self, command):
31
33
BzrError.__init__(self, "The command %s is blacklisted for shell use" %
36
class CompletionContext(object):
37
def __init__(self, text, command=None, prev_opt=None, arg_pos=None):
39
self.command = command
40
self.prev_opt = prev_opt
43
def get_completions(self):
45
return self.get_completions_or_raise()
50
def get_option_completions(self):
52
command_obj = get_cmd_object(self.command)
55
opts = [o+" " for o in iter_opt_completions(command_obj)]
56
return list(filter_completions(opts, self.text))
58
def get_completions_or_raise(self):
59
if self.command is None:
60
iter = (c+" " for c in iter_command_names() if
61
c not in COMPLETION_BLACKLIST)
62
return list(filter_completions(iter, self.text))
63
if self.prev_opt is None:
64
completions = self.get_option_completions()
65
if self.command == "cd":
66
iter = iter_dir_completions(self.text)
67
completions.extend(list(filter_completions(iter, self.text)))
69
iter = iter_file_completions(self.text)
70
completions.extend([f+" " for f in
71
filter_completions(iter, self.text)])
34
75
class PromptCmd(cmd.Cmd):
35
76
def __init__(self):
36
77
cmd.Cmd.__init__(self)
37
78
self.prompt = "bzr> "
39
self.tree = arch.tree_root(".")
80
self.branch = Branch.open_containing('.')[0]
44
85
self.identchars += '-'
70
111
def set_prompt(self):
71
if self.tree is not None:
112
if self.branch is not None:
73
prompt = pylon.alias_or_version(self.tree.tree_version,
76
if prompt is not None:
77
prompt = " " + prompt +":"+ pylon.tree_cwd(self.tree)
114
prompt_data = (self.branch.nick, self.branch.revno(),
115
self.branch.working_tree().relpath('.'))
116
prompt = " %s:%d/%s" % prompt_data
84
123
def set_title(self, command=None):
86
version = pylon.alias_or_version(self.tree.tree_version, self.tree,
125
b = Branch.open_containing('.')[0]
126
version = "%s:%d" % (b.nick, b.revno())
89
128
version = "[no version]"
90
129
if command is None:
144
183
def completenames(self, text, line, begidx, endidx):
146
iter = iter_command_names()
149
arg = line.split()[-1]
152
iter = list(iter_munged_completions(iter, arg, text))
184
return CompletionContext(text).get_completions()
157
186
def completedefault(self, text, line, begidx, endidx):
158
187
"""Perform completion for native commands.
169
198
(cmd, args, foo) = self.parseline(line)
172
return self.completenames(text, line, begidx, endidx)
176
command_obj = get_cmd_object(cmd)
180
if command_obj is not None:
182
for option_name, option in command_obj.options().items():
183
opts.append("--" + option_name)
184
short_name = option.short_name()
186
opts.append("-" + short_name)
187
q = list(iter_munged_completions(opts, args, text))
188
return list(iter_munged_completions(opts, args, text))
191
arg = args.split()[-1]
194
iter = iter_dir_completions(arg)
195
iter = iter_munged_completions(iter, arg, text)
198
arg = args.split()[-1]
199
iter = iter_file_completions(arg)
200
return list(iter_munged_completions(iter, arg, text))
202
return self.completenames(text, line, begidx, endidx)
201
return CompletionContext(text, command=cmd).get_completions()
213
210
except StopIteration:
213
def iter_opt_completions(command_obj):
214
for option_name, option in command_obj.options().items():
215
yield "--" + option_name
216
short_name = option.short_name()
218
yield "-" + short_name
216
220
def iter_file_completions(arg, only_dirs = False):
217
221
"""Generate an iterator that iterates through filename completions.
261
265
if name == real_cmd_name or not real_cmd_name.startswith(name):
268
def filter_completions(iter, arg):
269
return (c for c in iter if c.startswith(arg))
264
271
def iter_munged_completions(iter, arg, text):
265
272
for completion in iter:
266
273
completion = str(completion)