]> git.phdru.name Git - dotfiles.git/blob - lib/python/init.py
lib/python/init.py: Call parse_and_bind for libedit and readline
[dotfiles.git] / lib / python / init.py
1 # This is startup file for interactive python.
2 # It is not automatically loaded by python interpreter.
3 # To instruct the interpreter to load it insert the following commands
4 # into your .profile (use whatever syntax and initialization file
5 # is appropriate for your shell):
6 #
7 # PYTHONSTARTUP=$HOME/init.py  # or where you really put it
8 # export PYTHONSTARTUP
9
10
11 def init():
12     try:
13         import __builtin__ as builtins
14     except ImportError:
15         import builtins
16     import os
17     import sys
18
19     # readline/pyreadline
20
21     pyreadlinew32_startup = os.path.join(
22         sys.prefix, 'lib', 'site-packages',
23         'pyreadline', 'configuration', 'startup.py')
24
25     if os.path.exists(pyreadlinew32_startup):
26         execfile(pyreadlinew32_startup)
27
28     else:
29         # From Bruce Edge:
30         # https://mail.python.org/pipermail/python-list/2001-March/062888.html
31
32         try:
33             import rlcompleter  # noqa: need for completion
34             import readline
35             initfile = os.environ.get('INPUTRC') \
36                 or os.path.expanduser('~/.inputrc')
37             readline.read_init_file(initfile)
38
39             #if 'libedit' in readline.__doc__:
40             #    readline.parse_and_bind("bind ^I rl_complete")
41             #else:
42             #    readline.parse_and_bind("tab: complete")
43
44             histfile = os.path.expanduser('~/.python_history')
45             try:
46                 readline.read_history_file(histfile)
47             except IOError:
48                 pass  # No such file
49
50             def savehist():
51                 histsize = os.environ.get('HISTSIZE')
52                 if histsize:
53                     try:
54                         histsize = int(histsize)
55                     except ValueError:
56                         pass
57                     else:
58                         readline.set_history_length(histsize)
59                 readline.write_history_file(histfile)
60
61             import atexit
62             atexit.register(savehist)
63
64         except (ImportError, AttributeError):
65             # no readline or atexit, or readline doesn't have
66             # {read,write}_history_file - ignore the error
67             pass
68
69     # terminal
70
71     term = os.environ.get('TERM', '')
72     if 'linux' in term:
73         background = 'dark'
74     else:
75         background = os.environ.get('BACKGROUND', 'light').lower()
76
77     # From Randall Hopper:
78     # https://mail.python.org/pipermail/python-list/2001-March/112696.html
79
80     for _term in ['linux', 'rxvt', 'screen', 'term', 'vt100']:
81         if _term not in term:
82             continue
83
84         if background == 'dark':
85             ps1_color = '3'  # yellow
86             stdout_color = '7'  # bold white
87         else:
88             ps1_color = '4'  # blue
89             stdout_color = '0'  # bold black
90
91         sys.ps1 = '\001\033[3%sm\002>>>\001\033[0m\002 ' % ps1_color
92         sys.ps2 = '\001\033[1;32m\002...\001\033[0m\002 '  # bold green
93
94         # From Denis Otkidach
95
96         class ColoredFile:
97             def __init__(self, fp, begin,
98                          end='\033[0m'):  # reset all attributes
99                 self.__fp = fp
100                 self.__begin = begin
101                 self.__end = end
102
103             def write(self, s):
104                 self.__fp.write(self.__begin+s+self.__end)
105
106             def writelines(self, lines):
107                 map(self.write, lines)
108
109             def __getattr__(self, attr):
110                 return getattr(self.__fp, attr)
111
112         sys.stdout = ColoredFile(sys.stdout, '\033[1;3%sm' % stdout_color)
113         sys.stderr = ColoredFile(sys.stderr, '\033[31m')  # red
114
115         def myinput(prompt=None):
116             save_stdout = sys.stdout
117             sys.stdout = sys.__stdout__
118             result = builtin_input(prompt)
119             sys.stdout = save_stdout
120             return result
121
122         try:
123             builtins.raw_input
124         except AttributeError: # PY3
125             builtin_input = builtins.input
126             builtins.input = myinput
127         else:
128             builtin_input = builtins.raw_input
129             builtins.raw_input = myinput
130
131         break
132
133     try:
134         import locale
135     except ImportError:
136         pass  # locale was not compiled
137     else:
138         try:
139             locale.setlocale(locale.LC_ALL, '')
140         except (ImportError, locale.Error):
141             pass  # no locale support or unsupported locale
142
143     # set displayhook and excepthook
144
145     from pprint import pprint
146     from traceback import format_exception, print_exc
147
148     pager = os.environ.get("PAGER") or 'more'
149
150     # if your pager is 'less', options '-F' and '-R' must be passed to it,
151     # and option '-X' is very much recommended
152     if pager == 'less':
153         less = os.environ.get("LESS") or ''
154         for opt in 'X', 'R', 'F':
155             if opt not in less:
156                 less = opt + less
157         os.environ["LESS"] = less
158
159     class BasePager:
160         def write(self, value):
161             self.stdout.write(value)
162
163         def pprint(self, value):
164             pprint(value,
165                    stream=ColoredFile(self.stdout,
166                                       '\033[1;3%sm' % stdout_color))
167
168         def close(self):
169             self.stdout.close()
170
171     try:
172         from subprocess import Popen, PIPE
173     except ImportError:
174         class Pager(BasePager):
175             def __init__(self):
176                 self.stdout = os.popen(pager, 'w')
177     else:
178         class Pager(BasePager):
179             def __init__(self):
180                 self.pipe = Popen(pager, shell=True, stdin=PIPE,
181                                   universal_newlines=True)
182                 self.stdout = self.pipe.stdin
183
184             def close(self):
185                 BasePager.close(self)
186                 self.pipe.wait()
187
188     def displayhook(value):
189         if value is not None:
190             builtins._ = value
191         pager = Pager()
192         try:
193             pager.pprint(value)
194         except:
195             pager.stdout = ColoredFile(pager.stdout, '\033[31m')  # red
196             print_exc(file=pager)
197         pager.close()
198
199     sys.displayhook = displayhook
200
201     def excepthook(etype, evalue, etraceback):
202         lines = format_exception(etype, evalue, etraceback)
203         pager = Pager()
204         pager.stdout = ColoredFile(pager.stdout, '\033[31m')  # red
205         for line in lines:
206             pager.write(line)
207         pager.close()
208
209     sys.excepthook = excepthook
210
211     #try:
212     #    import cgitb
213     #except ImportError:
214     #    pass
215     #else:
216     #    # cgitb.enable() overrides sys.excepthook
217     #    cgitb.enable(format='text')
218
219     # From Thomas Heller:
220     # https://mail.python.org/pipermail/python-list/2001-April/099020.html
221
222     # import pdb
223     #
224     # def info(*args):
225     #    pdb.pm()
226     # sys.excepthook = info
227
228     # utilities
229
230     # From: Paul Magwene:
231     # https://mail.python.org/pipermail/python-list/2001-March/086191.html
232     # With a lot of my fixes:
233
234     class DirLister:
235         def __getitem__(self, key):
236             s = os.listdir(os.curdir)
237             return s[key]
238
239         def __getslice__(self, i, j):
240             s = os.listdir(os.curdir)
241             return s[i:j]
242
243         def __repr__(self):
244             return str(os.listdir(os.curdir))
245
246         def __call__(self, path=None):
247             if path:
248                 path = os.path.expanduser(os.path.expandvars(path))
249             else:
250                 path = os.curdir
251             return os.listdir(path)
252
253     class DirChanger:
254         def __repr__(self):
255             self()
256             return os.getcwd()
257
258         def __call__(self, path=None):
259             path = os.path.expanduser(os.path.expandvars(path or '~'))
260             os.chdir(path)
261
262     builtins.ls = DirLister()
263     builtins.cd = DirChanger()
264
265     # print working directory
266
267     class Pwd:
268         def __repr__(self):
269             return os.getcwd()
270
271         def __call__(self):
272             return repr(self)
273
274     builtins.pwd = Pwd()
275
276     # exit REPL with 'exit', 'quit' or simple 'x'
277
278     class _Exit:
279         def __repr__(self):
280             sys.exit()
281
282         def __call__(self, msg=None):
283             sys.exit(msg)
284
285     builtins.x = _Exit()
286
287     # print conten of a file
288
289     class _Cat:
290         def __repr__(self):
291             return "Usage: cat('filename')"
292
293         def __call__(self, filename):
294             fp = open(filename, 'rU')
295             text = fp.read()
296             fp.close()
297             print(text)
298
299     builtins.cat = _Cat()
300
301     # call shell
302
303     class _Sh:
304         def __repr__(self):
305             os.system(os.environ["SHELL"])
306             return ''
307
308         def __call__(self, cmdline):
309             os.system(cmdline)
310
311     builtins.sh = _Sh()
312
313     # paginate a file
314
315     class _Pager:
316         def __repr__(self):
317             return "Usage: pager('filename')"
318
319         def __call__(self, filename):
320             os.system("%s '%s'" % (pager, filename.replace("'", '"\'"')))
321
322     builtins.pager = _Pager()
323
324     # edit a file
325
326     class _Editor:
327         def __repr__(self):
328             return "Usage: edit('filename')"
329
330         def __call__(self, filename):
331             editor = os.environ.get("VISUAL") \
332                 or os.environ.get("EDITOR") or 'vi'
333             os.system("%s '%s'" % (editor, filename.replace("'", '"\'"')))
334
335     builtins.edit = builtins.editor = _Editor()
336
337
338 init()
339 del init