14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
from itertools import chain
27
from bzrlib.branch import Branch
28
from bzrlib.commands import get_cmd_object, get_all_cmds, get_alias
23
from itertools import chain
29
24
from bzrlib.errors import BzrError
30
from bzrlib.workingtree import WorkingTree
25
from bzrlib.commands import get_cmd_object, get_all_cmds
35
27
SHELL_BLACKLIST = set(['rm', 'ls'])
36
28
COMPLETION_BLACKLIST = set(['shell'])
39
30
class BlackListedCommand(BzrError):
40
31
def __init__(self, command):
41
32
BzrError.__init__(self, "The command %s is blacklisted for shell use" %
45
class CompletionContext(object):
46
def __init__(self, text, command=None, prev_opt=None, arg_pos=None):
48
self.command = command
49
self.prev_opt = prev_opt
52
def get_completions(self):
54
return self.get_completions_or_raise()
59
def get_option_completions(self):
61
command_obj = get_cmd_object(self.command)
64
opts = [o+" " for o in iter_opt_completions(command_obj)]
65
return list(filter_completions(opts, self.text))
67
def get_completions_or_raise(self):
68
if self.command is None:
70
iter = iter_executables(self.text)
72
iter = (c+" " for c in iter_command_names() if
73
c not in COMPLETION_BLACKLIST)
74
return list(filter_completions(iter, self.text))
75
if self.prev_opt is None:
76
completions = self.get_option_completions()
77
if self.command == "cd":
78
iter = iter_dir_completions(self.text)
79
completions.extend(list(filter_completions(iter, self.text)))
81
iter = iter_file_completions(self.text)
82
completions.extend(filter_completions(iter, self.text))
86
35
class PromptCmd(cmd.Cmd):
87
36
def __init__(self):
88
37
cmd.Cmd.__init__(self)
89
38
self.prompt = "bzr> "
91
self.tree = WorkingTree.open_containing('.')[0]
40
self.tree = arch.tree_root(".")
122
71
def set_prompt(self):
123
72
if self.tree is not None:
125
prompt_data = (self.tree.branch.nick, self.tree.branch.revno(),
126
self.tree.relpath('.'))
127
prompt = " %s:%d/%s" % prompt_data
74
prompt = pylon.alias_or_version(self.tree.tree_version,
77
if prompt is not None:
78
prompt = " " + prompt +":"+ pylon.tree_cwd(self.tree)
164
115
self.default("help "+line)
166
117
def default(self, line):
167
args = shlex.split(line)
168
alias_args = get_alias(args[0])
169
if alias_args is not None:
170
args[0] = alias_args.pop(0)
172
119
commandname = args.pop(0)
173
120
for char in ('|', '<', '>'):
174
121
commandname = commandname.split(char)[0]
198
145
def completenames(self, text, line, begidx, endidx):
199
return CompletionContext(text).get_completions()
147
iter = (c for c in iter_command_names() if
148
c not in COMPLETION_BLACKLIST)
151
arg = line.split()[-1]
154
iter = list(iter_munged_completions(iter, arg, text))
201
159
def completedefault(self, text, line, begidx, endidx):
202
160
"""Perform completion for native commands.
204
162
:param text: The text to complete
206
164
:param line: The entire line to complete
213
171
(cmd, args, foo) = self.parseline(line)
216
return CompletionContext(text, command=cmd).get_completions()
174
return self.completenames(text, line, begidx, endidx)
178
command_obj = get_cmd_object(cmd)
182
if command_obj is not None:
184
for option_name, option in command_obj.options().items():
185
opts.append("--" + option_name)
186
short_name = option.short_name()
188
opts.append("-" + short_name)
189
q = list(iter_munged_completions(opts, args, text))
190
return list(iter_munged_completions(opts, args, text))
193
arg = args.split()[-1]
196
iter = iter_dir_completions(arg)
197
iter = iter_munged_completions(iter, arg, text)
200
arg = args.split()[-1]
201
iter = iter_file_completions(arg)
202
return list(iter_munged_completions(iter, arg, text))
204
return self.completenames(text, line, begidx, endidx)
226
215
except StopIteration:
230
def iter_opt_completions(command_obj):
231
for option_name, option in command_obj.options().items():
232
yield "--" + option_name
233
short_name = option.short_name()
235
yield "-" + short_name
238
218
def iter_file_completions(arg, only_dirs = False):
239
219
"""Generate an iterator that iterates through filename completions.
284
263
if name == real_cmd_name or not real_cmd_name.startswith(name):
288
def iter_executables(path):
289
dirname, partial = os.path.split(path)
290
for filename in os.listdir(dirname):
291
if not filename.startswith(partial):
293
fullpath = os.path.join(dirname, filename)
294
mode=os.lstat(fullpath)[stat.ST_MODE]
295
if stat.S_ISREG(mode) and 0111 & mode:
299
def filter_completions(iter, arg):
300
return (c for c in iter if c.startswith(arg))
303
266
def iter_munged_completions(iter, arg, text):
304
267
for completion in iter:
305
268
completion = str(completion)
306
269
if completion.startswith(arg):
307
270
yield completion[len(arg)-len(text):]+" "
310
272
def too_complicated(line):
273
for char in '|<>"\"':