~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to shell.py

  • Committer: Aaron Bentley
  • Date: 2007-03-09 18:25:10 UTC
  • mto: This revision was merged to the branch mainline in revision 520.
  • Revision ID: abentley@panoramicfeedback.com-20070309182510-fkj1j6t119d1cj5q
Handle broken python tar implementations

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
 
17
18
import cmd
18
 
import sys
 
19
from itertools import chain
19
20
import os
20
 
import terminal
21
21
import readline
 
22
import shlex
 
23
import stat
22
24
import string
23
 
from itertools import chain
 
25
import sys
 
26
 
 
27
from bzrlib.branch import Branch
 
28
from bzrlib.commands import get_cmd_object, get_all_cmds, get_alias
24
29
from bzrlib.errors import BzrError
25
 
from bzrlib.commands import get_cmd_object, get_all_cmds, get_alias
26
 
from bzrlib.branch import Branch
 
30
from bzrlib.workingtree import WorkingTree
 
31
 
 
32
import terminal
 
33
 
27
34
 
28
35
SHELL_BLACKLIST = set(['rm', 'ls'])
29
36
COMPLETION_BLACKLIST = set(['shell'])
30
37
 
 
38
 
31
39
class BlackListedCommand(BzrError):
32
40
    def __init__(self, command):
33
41
        BzrError.__init__(self, "The command %s is blacklisted for shell use" %
34
42
                          command)
35
43
 
 
44
 
36
45
class CompletionContext(object):
37
46
    def __init__(self, text, command=None, prev_opt=None, arg_pos=None):
38
47
        self.text = text
57
66
 
58
67
    def get_completions_or_raise(self):
59
68
        if self.command is None:
60
 
            iter = (c+" " for c in iter_command_names() if
61
 
                    c not in COMPLETION_BLACKLIST)
 
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)
62
74
            return list(filter_completions(iter, self.text))
63
75
        if self.prev_opt is None:
64
76
            completions = self.get_option_completions()
67
79
                completions.extend(list(filter_completions(iter, self.text)))
68
80
            else:
69
81
                iter = iter_file_completions(self.text)
70
 
                completions.extend([f+" " for f in 
71
 
                                    filter_completions(iter, self.text)])
 
82
                completions.extend(filter_completions(iter, self.text))
72
83
            return completions 
73
84
 
74
85
 
112
123
        if self.tree is not None:
113
124
            try:
114
125
                prompt_data = (self.tree.branch.nick, self.tree.branch.revno(), 
115
 
                               self.tree.branch.relpath('.'))
 
126
                               self.tree.relpath('.'))
116
127
                prompt = " %s:%d/%s" % prompt_data
117
128
            except:
118
129
                prompt = ""
153
164
        self.default("help "+line)
154
165
 
155
166
    def default(self, line):
156
 
        args = line.split()
 
167
        args = shlex.split(line)
157
168
        alias_args = get_alias(args[0])
158
169
        if alias_args is not None:
159
170
            args[0] = alias_args.pop(0)
204
215
            cmd = None
205
216
        return CompletionContext(text, command=cmd).get_completions()
206
217
 
 
218
 
207
219
def run_shell():
208
220
    try:
209
221
        prompt = PromptCmd()
214
226
    except StopIteration:
215
227
        pass
216
228
 
 
229
 
217
230
def iter_opt_completions(command_obj):
218
231
    for option_name, option in command_obj.options().items():
219
232
        yield "--" + option_name
221
234
        if short_name:
222
235
            yield "-" + short_name
223
236
 
 
237
 
224
238
def iter_file_completions(arg, only_dirs = False):
225
239
    """Generate an iterator that iterates through filename completions.
226
240
 
249
263
                userfile+='/'
250
264
                yield userfile
251
265
            elif not only_dirs:
252
 
                yield userfile
 
266
                yield userfile + ' '
253
267
 
254
268
 
255
269
def iter_dir_completions(arg):
260
274
    """
261
275
    return iter_file_completions(arg, True)
262
276
 
 
277
 
263
278
def iter_command_names(hidden=False):
264
279
    for real_cmd_name, cmd_class in get_all_cmds():
265
280
        if not hidden and cmd_class.hidden:
269
284
            if name == real_cmd_name or not real_cmd_name.startswith(name):
270
285
                yield name
271
286
 
 
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
 
272
299
def filter_completions(iter, arg):
273
300
    return (c for c in iter if c.startswith(arg))
274
301
 
 
302
 
275
303
def iter_munged_completions(iter, arg, text):
276
304
    for completion in iter:
277
305
        completion = str(completion)
278
306
        if completion.startswith(arg):
279
307
            yield completion[len(arg)-len(text):]+" "
280
308
 
 
309
 
281
310
def too_complicated(line):
282
 
    for char in '|<>"\"*?':
 
311
    for char in '|<>*?':
283
312
        if char in line:
284
313
            return True
285
314
    return False