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