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
23
from itertools import chain
27
from bzrlib import osutils
28
from bzrlib.branch import Branch
29
from bzrlib.config import config_dir, ensure_config_dir_exists
30
from bzrlib.commands import get_cmd_object, get_all_cmds, get_alias
24
31
from bzrlib.errors import BzrError
25
from bzrlib.commands import get_cmd_object, get_all_cmds
32
from bzrlib.workingtree import WorkingTree
27
37
SHELL_BLACKLIST = set(['rm', 'ls'])
28
38
COMPLETION_BLACKLIST = set(['shell'])
30
41
class BlackListedCommand(BzrError):
31
42
def __init__(self, command):
32
43
BzrError.__init__(self, "The command %s is blacklisted for shell use" %
47
class CompletionContext(object):
48
def __init__(self, text, command=None, prev_opt=None, arg_pos=None):
50
self.command = command
51
self.prev_opt = prev_opt
54
def get_completions(self):
56
return self.get_completions_or_raise()
61
def get_option_completions(self):
63
command_obj = get_cmd_object(self.command)
66
opts = [o+" " for o in iter_opt_completions(command_obj)]
67
return list(filter_completions(opts, self.text))
69
def get_completions_or_raise(self):
70
if self.command is None:
72
iter = iter_executables(self.text)
74
iter = (c+" " for c in iter_command_names() if
75
c not in COMPLETION_BLACKLIST)
76
return list(filter_completions(iter, self.text))
77
if self.prev_opt is None:
78
completions = self.get_option_completions()
79
if self.command == "cd":
80
iter = iter_dir_completions(self.text)
81
completions.extend(list(filter_completions(iter, self.text)))
83
iter = iter_file_completions(self.text)
84
completions.extend(filter_completions(iter, self.text))
35
88
class PromptCmd(cmd.Cmd):
36
90
def __init__(self):
37
91
cmd.Cmd.__init__(self)
38
92
self.prompt = "bzr> "
40
self.tree = arch.tree_root(".")
94
self.tree = WorkingTree.open_containing('.')[0]
45
99
self.identchars += '-'
46
self.history_file = os.path.expanduser("~/.bazaar/shell-history")
100
ensure_config_dir_exists()
101
self.history_file = osutils.pathjoin(config_dir(), 'shell-history')
47
102
readline.set_completer_delims(string.whitespace)
48
103
if os.access(self.history_file, os.R_OK) and \
49
104
os.path.isfile(self.history_file):
145
202
def completenames(self, text, line, begidx, endidx):
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))
203
return CompletionContext(text).get_completions()
159
205
def completedefault(self, text, line, begidx, endidx):
160
206
"""Perform completion for native commands.
162
208
:param text: The text to complete
164
210
:param line: The entire line to complete
171
217
(cmd, args, foo) = self.parseline(line)
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)
220
return CompletionContext(text, command=cmd).get_completions()
263
288
if name == real_cmd_name or not real_cmd_name.startswith(name):
292
def iter_executables(path):
293
dirname, partial = os.path.split(path)
294
for filename in os.listdir(dirname):
295
if not filename.startswith(partial):
297
fullpath = os.path.join(dirname, filename)
298
mode=os.lstat(fullpath)[stat.ST_MODE]
299
if stat.S_ISREG(mode) and 0111 & mode:
303
def filter_completions(iter, arg):
304
return (c for c in iter if c.startswith(arg))
266
307
def iter_munged_completions(iter, arg, text):
267
308
for completion in iter:
268
309
completion = str(completion)
269
310
if completion.startswith(arg):
270
311
yield completion[len(arg)-len(text):]+" "
272
314
def too_complicated(line):
273
for char in '|<>"\"':