~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to shell.py

  • Committer: Aaron Bentley
  • Date: 2012-01-20 02:07:15 UTC
  • Revision ID: aaron@aaronbentley.com-20120120020715-ar6jbqnrjcuebggz
Tags: release-2.5
Update for 2.5 release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2004, 2005 Aaron Bentley
2
 
# <aaron.bentley@utoronto.ca>
 
2
# <aaron@aaronbentley.com>
3
3
#
4
4
#    This program is free software; you can redistribute it and/or modify
5
5
#    it under the terms of the GNU General Public License as published by
18
18
import cmd
19
19
from itertools import chain
20
20
import os
21
 
import readline
 
21
try:
 
22
    import readline
 
23
except ImportError:
 
24
    _has_readline = False
 
25
else:
 
26
    _has_readline = True
22
27
import shlex
23
28
import stat
24
29
import string
25
30
import sys
26
31
 
 
32
from bzrlib import osutils, trace
27
33
from bzrlib.branch import Branch
28
 
from bzrlib.commands import get_cmd_object, get_all_cmds, get_alias
 
34
from bzrlib.config import config_dir, ensure_config_dir_exists
 
35
from bzrlib.commands import get_cmd_object, all_command_names, get_alias
29
36
from bzrlib.errors import BzrError
30
37
from bzrlib.workingtree import WorkingTree
31
38
 
80
87
            else:
81
88
                iter = iter_file_completions(self.text)
82
89
                completions.extend(filter_completions(iter, self.text))
83
 
            return completions 
 
90
            return completions
84
91
 
85
92
 
86
93
class PromptCmd(cmd.Cmd):
 
94
 
87
95
    def __init__(self):
88
96
        cmd.Cmd.__init__(self)
89
97
        self.prompt = "bzr> "
94
102
        self.set_title()
95
103
        self.set_prompt()
96
104
        self.identchars += '-'
97
 
        self.history_file = os.path.expanduser("~/.bazaar/shell-history")
98
 
        readline.set_completer_delims(string.whitespace)
99
 
        if os.access(self.history_file, os.R_OK) and \
100
 
            os.path.isfile(self.history_file):
101
 
            readline.read_history_file(self.history_file)
 
105
        ensure_config_dir_exists()
 
106
        self.history_file = osutils.pathjoin(config_dir(), 'shell-history')
 
107
        whitespace = ''.join(c for c in string.whitespace if c < chr(127))
 
108
        if _has_readline:
 
109
            readline.set_completer_delims(whitespace)
 
110
            if os.access(self.history_file, os.R_OK) and \
 
111
                os.path.isfile(self.history_file):
 
112
                readline.read_history_file(self.history_file)
102
113
        self.cwd = os.getcwd()
103
114
 
104
115
    def write_history(self):
105
 
        readline.write_history_file(self.history_file)
 
116
        if _has_readline:
 
117
            readline.write_history_file(self.history_file)
106
118
 
107
119
    def do_quit(self, args):
108
120
        self.write_history()
122
134
    def set_prompt(self):
123
135
        if self.tree is not None:
124
136
            try:
125
 
                prompt_data = (self.tree.branch.nick, self.tree.branch.revno(), 
 
137
                prompt_data = (self.tree.branch.nick, self.tree.branch.revno(),
126
138
                               self.tree.relpath('.'))
127
139
                prompt = " %s:%d/%s" % prompt_data
128
140
            except:
164
176
        self.default("help "+line)
165
177
 
166
178
    def default(self, line):
167
 
        args = shlex.split(line)
 
179
        try:
 
180
            args = shlex.split(line)
 
181
        except ValueError, e:
 
182
            print 'Parse error:', e
 
183
            return
 
184
 
168
185
        alias_args = get_alias(args[0])
169
186
        if alias_args is not None:
170
187
            args[0] = alias_args.pop(0)
171
 
            
 
188
 
172
189
        commandname = args.pop(0)
173
190
        for char in ('|', '<', '>'):
174
191
            commandname = commandname.split(char)[0]
182
199
            return os.system(line)
183
200
 
184
201
        try:
185
 
            if too_complicated(line):
 
202
            is_qbzr = cmd_obj.__module__.startswith('bzrlib.plugins.qbzr.')
 
203
            if too_complicated(line) or is_qbzr:
186
204
                return os.system("bzr "+line)
187
205
            else:
188
206
                return (cmd_obj.run_argv_aliases(args, alias_args) or 0)
189
207
        except BzrError, e:
 
208
            trace.log_exception_quietly()
190
209
            print e
191
210
        except KeyboardInterrupt, e:
192
211
            print "Interrupted"
193
212
        except Exception, e:
194
 
#            print "Unhandled error:\n%s" % errors.exception_str(e)
 
213
            trace.log_exception_quietly()
195
214
            print "Unhandled error:\n%s" % (e)
196
215
 
197
216
 
200
219
 
201
220
    def completedefault(self, text, line, begidx, endidx):
202
221
        """Perform completion for native commands.
203
 
        
 
222
 
204
223
        :param text: The text to complete
205
224
        :type text: str
206
225
        :param line: The entire line to complete
216
235
        return CompletionContext(text, command=cmd).get_completions()
217
236
 
218
237
 
219
 
def run_shell():
 
238
def run_shell(directory=None):
220
239
    try:
 
240
        if not directory is None:
 
241
            os.chdir(directory)
221
242
        prompt = PromptCmd()
222
 
        try:
223
 
            prompt.cmdloop()
224
 
        finally:
225
 
            prompt.write_history()
 
243
        while True:
 
244
            try:
 
245
                try:
 
246
                    prompt.cmdloop()
 
247
                except KeyboardInterrupt:
 
248
                    print
 
249
            finally:
 
250
                prompt.write_history()
226
251
    except StopIteration:
227
252
        pass
228
253
 
276
301
 
277
302
 
278
303
def iter_command_names(hidden=False):
279
 
    for real_cmd_name, cmd_class in get_all_cmds():
280
 
        if not hidden and cmd_class.hidden:
 
304
    for real_cmd_name in all_command_names():
 
305
        cmd_obj = get_cmd_object(real_cmd_name)
 
306
        if not hidden and cmd_obj.hidden:
281
307
            continue
282
 
        for name in [real_cmd_name] + cmd_class.aliases:
 
308
        for name in [real_cmd_name] + cmd_obj.aliases:
283
309
            # Don't complete on aliases that are prefixes of the canonical name
284
310
            if name == real_cmd_name or not real_cmd_name.startswith(name):
285
311
                yield name