~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to shell.py

  • Committer: Aaron Bentley
  • Date: 2005-12-03 23:53:59 UTC
  • mto: (147.4.30 trunk)
  • mto: This revision was merged to the branch mainline in revision 324.
  • Revision ID: aaron.bentley@utoronto.ca-20051203235359-5134805afd538781
Recorded Robey's bug

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
17
 
 
18
17
import cmd
19
 
from itertools import chain
 
18
import sys
20
19
import os
 
20
import terminal
21
21
import readline
22
 
import shlex
23
 
import stat
24
22
import string
25
 
import sys
26
 
 
 
23
from itertools import chain
 
24
from bzrlib.errors import BzrError
 
25
from bzrlib.commands import get_cmd_object, get_all_cmds
27
26
from bzrlib.branch import Branch
28
 
from bzrlib.commands import get_cmd_object, get_all_cmds, get_alias
29
 
from bzrlib.errors import BzrError
30
 
from bzrlib.workingtree import WorkingTree
31
 
 
32
 
import terminal
33
 
 
34
27
 
35
28
SHELL_BLACKLIST = set(['rm', 'ls'])
36
29
COMPLETION_BLACKLIST = set(['shell'])
37
30
 
38
 
 
39
31
class BlackListedCommand(BzrError):
40
32
    def __init__(self, command):
41
33
        BzrError.__init__(self, "The command %s is blacklisted for shell use" %
42
34
                          command)
43
35
 
44
 
 
45
36
class CompletionContext(object):
46
37
    def __init__(self, text, command=None, prev_opt=None, arg_pos=None):
47
38
        self.text = text
66
57
 
67
58
    def get_completions_or_raise(self):
68
59
        if self.command is None:
69
 
            if '/' in self.text:
70
 
                iter = iter_executables(self.text)
71
 
            else:
72
 
                iter = (c+" " for c in iter_command_names() if
73
 
                        c not in COMPLETION_BLACKLIST)
 
60
            iter = (c+" " for c in iter_command_names() if
 
61
                    c not in COMPLETION_BLACKLIST)
74
62
            return list(filter_completions(iter, self.text))
75
63
        if self.prev_opt is None:
76
64
            completions = self.get_option_completions()
79
67
                completions.extend(list(filter_completions(iter, self.text)))
80
68
            else:
81
69
                iter = iter_file_completions(self.text)
82
 
                completions.extend(filter_completions(iter, self.text))
 
70
                completions.extend([f+" " for f in 
 
71
                                    filter_completions(iter, self.text)])
83
72
            return completions 
84
73
 
85
74
 
88
77
        cmd.Cmd.__init__(self)
89
78
        self.prompt = "bzr> "
90
79
        try:
91
 
            self.tree = WorkingTree.open_containing('.')[0]
 
80
            self.branch = Branch.open_containing('.')[0]
92
81
        except:
93
 
            self.tree = None
 
82
            self.branch = None
94
83
        self.set_title()
95
84
        self.set_prompt()
96
85
        self.identchars += '-'
120
109
        self.set_prompt()
121
110
 
122
111
    def set_prompt(self):
123
 
        if self.tree is not None:
 
112
        if self.branch is not None:
124
113
            try:
125
 
                prompt_data = (self.tree.branch.nick, self.tree.branch.revno(), 
126
 
                               self.tree.relpath('.'))
 
114
                prompt_data = (self.branch.nick, self.branch.revno(), 
 
115
                               self.branch.working_tree().relpath('.'))
127
116
                prompt = " %s:%d/%s" % prompt_data
128
117
            except:
129
118
                prompt = ""
156
145
        except Exception, e:
157
146
            print e
158
147
        try:
159
 
            self.tree = WorkingTree.open_containing(".")[0]
 
148
            self.branch = Branch.open_containing(".")[0]
160
149
        except:
161
 
            self.tree = None
 
150
            self.branch = None
162
151
 
163
152
    def do_help(self, line):
164
153
        self.default("help "+line)
165
154
 
166
155
    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)
171
 
            
 
156
        args = line.split()
172
157
        commandname = args.pop(0)
173
158
        for char in ('|', '<', '>'):
174
159
            commandname = commandname.split(char)[0]
185
170
            if too_complicated(line):
186
171
                return os.system("bzr "+line)
187
172
            else:
188
 
                return (cmd_obj.run_argv_aliases(args, alias_args) or 0)
 
173
                return (cmd_obj.run_argv(args) or 0)
189
174
        except BzrError, e:
190
175
            print e
191
176
        except KeyboardInterrupt, e:
215
200
            cmd = None
216
201
        return CompletionContext(text, command=cmd).get_completions()
217
202
 
218
 
 
219
203
def run_shell():
220
204
    try:
221
205
        prompt = PromptCmd()
226
210
    except StopIteration:
227
211
        pass
228
212
 
229
 
 
230
213
def iter_opt_completions(command_obj):
231
214
    for option_name, option in command_obj.options().items():
232
215
        yield "--" + option_name
234
217
        if short_name:
235
218
            yield "-" + short_name
236
219
 
237
 
 
238
220
def iter_file_completions(arg, only_dirs = False):
239
221
    """Generate an iterator that iterates through filename completions.
240
222
 
263
245
                userfile+='/'
264
246
                yield userfile
265
247
            elif not only_dirs:
266
 
                yield userfile + ' '
 
248
                yield userfile
267
249
 
268
250
 
269
251
def iter_dir_completions(arg):
274
256
    """
275
257
    return iter_file_completions(arg, True)
276
258
 
277
 
 
278
259
def iter_command_names(hidden=False):
279
260
    for real_cmd_name, cmd_class in get_all_cmds():
280
261
        if not hidden and cmd_class.hidden:
284
265
            if name == real_cmd_name or not real_cmd_name.startswith(name):
285
266
                yield name
286
267
 
287
 
 
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):
292
 
            continue
293
 
        fullpath = os.path.join(dirname, filename)
294
 
        mode=os.lstat(fullpath)[stat.ST_MODE]
295
 
        if stat.S_ISREG(mode) and 0111 & mode:
296
 
            yield fullpath + ' '
297
 
 
298
 
 
299
268
def filter_completions(iter, arg):
300
269
    return (c for c in iter if c.startswith(arg))
301
270
 
302
 
 
303
271
def iter_munged_completions(iter, arg, text):
304
272
    for completion in iter:
305
273
        completion = str(completion)
306
274
        if completion.startswith(arg):
307
275
            yield completion[len(arg)-len(text):]+" "
308
276
 
309
 
 
310
277
def too_complicated(line):
311
 
    for char in '|<>*?':
 
278
    for char in '|<>"\"*?':
312
279
        if char in line:
313
280
            return True
314
281
    return False