##// END OF EJS Templates
Fix hang-upon exit in terminal version, which was due to the history autosave thread not exiting.
Thomas Kluyver -
Show More
@@ -1,547 +1,554 b''
1 1 """ History related magics and functionality """
2 2 #-----------------------------------------------------------------------------
3 3 # Copyright (C) 2010 The IPython Development Team.
4 4 #
5 5 # Distributed under the terms of the BSD License.
6 6 #
7 7 # The full license is in the file COPYING.txt, distributed with this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13 from __future__ import print_function
14 14
15 15 # Stdlib imports
16 16 import fnmatch
17 17 import json
18 18 import os
19 19 import sys
20 20 import threading
21 21 import time
22 22
23 23 # Our own packages
24 24 import IPython.utils.io
25 25
26 26 from IPython.utils.pickleshare import PickleShareDB
27 27 from IPython.utils.io import ask_yes_no
28 28 from IPython.utils.warn import warn
29 29
30 30 #-----------------------------------------------------------------------------
31 31 # Classes and functions
32 32 #-----------------------------------------------------------------------------
33 33
34 34 class HistoryManager(object):
35 35 """A class to organize all history-related functionality in one place.
36 36 """
37 37 # Public interface
38 38
39 39 # An instance of the IPython shell we are attached to
40 40 shell = None
41 41 # A list to hold processed history
42 42 input_hist_parsed = None
43 43 # A list to hold raw history (as typed by user)
44 44 input_hist_raw = None
45 45 # A list of directories visited during session
46 46 dir_hist = None
47 47 # A dict of output history, keyed with ints from the shell's execution count
48 48 output_hist = None
49 49 # String with path to the history file
50 50 hist_file = None
51 51 # PickleShareDB instance holding the raw data for the shadow history
52 52 shadow_db = None
53 53 # ShadowHist instance with the actual shadow history
54 54 shadow_hist = None
55 55
56 56 # Private interface
57 57 # Variables used to store the three last inputs from the user. On each new
58 58 # history update, we populate the user's namespace with these, shifted as
59 59 # necessary.
60 60 _i00, _i, _ii, _iii = '','','',''
61 61
62 62 # A set with all forms of the exit command, so that we don't store them in
63 63 # the history (it's annoying to rewind the first entry and land on an exit
64 64 # call).
65 65 _exit_commands = None
66 66
67 67 def __init__(self, shell):
68 68 """Create a new history manager associated with a shell instance.
69 69 """
70 70 # We need a pointer back to the shell for various tasks.
71 71 self.shell = shell
72 72
73 73 # List of input with multi-line handling.
74 74 self.input_hist_parsed = []
75 75 # This one will hold the 'raw' input history, without any
76 76 # pre-processing. This will allow users to retrieve the input just as
77 77 # it was exactly typed in by the user, with %hist -r.
78 78 self.input_hist_raw = []
79 79
80 80 # list of visited directories
81 81 try:
82 82 self.dir_hist = [os.getcwd()]
83 83 except OSError:
84 84 self.dir_hist = []
85 85
86 86 # dict of output history
87 87 self.output_hist = {}
88 88
89 89 # Now the history file
90 90 if shell.profile:
91 91 histfname = 'history-%s' % shell.profile
92 92 else:
93 93 histfname = 'history'
94 94 self.hist_file = os.path.join(shell.ipython_dir, histfname + '.json')
95 95
96 96 # Objects related to shadow history management
97 97 self._init_shadow_hist()
98 98
99 99 self._i00, self._i, self._ii, self._iii = '','','',''
100 100
101 101 self._exit_commands = set(['Quit', 'quit', 'Exit', 'exit', '%Quit',
102 102 '%quit', '%Exit', '%exit'])
103 103
104 104 # Object is fully initialized, we can now call methods on it.
105 105
106 106 # Fill the history zero entry, user counter starts at 1
107 107 self.store_inputs('\n', '\n')
108 108
109 109 def _init_shadow_hist(self):
110 110 try:
111 111 self.shadow_db = PickleShareDB(os.path.join(
112 112 self.shell.ipython_dir, 'db'))
113 113 except UnicodeDecodeError:
114 114 print("Your ipython_dir can't be decoded to unicode!")
115 115 print("Please set HOME environment variable to something that")
116 116 print(r"only has ASCII characters, e.g. c:\home")
117 117 print("Now it is", self.ipython_dir)
118 118 sys.exit()
119 119 self.shadow_hist = ShadowHist(self.shadow_db, self.shell)
120 120
121 121 def populate_readline_history(self):
122 122 """Populate the readline history from the raw history.
123 123
124 124 We only store one copy of the raw history, which is persisted to a json
125 125 file on disk. The readline history is repopulated from the contents of
126 126 this file."""
127 127
128 128 try:
129 129 self.shell.readline.clear_history()
130 130 except AttributeError:
131 131 pass
132 132 else:
133 133 for h in self.input_hist_raw:
134 134 if not h.isspace():
135 135 for line in h.splitlines():
136 136 self.shell.readline.add_history(line)
137 137
138 138 def save_history(self):
139 139 """Save input history to a file (via readline library)."""
140 140 hist = dict(raw=self.input_hist_raw, #[-self.shell.history_length:],
141 141 parsed=self.input_hist_parsed) #[-self.shell.history_length:])
142 142 with open(self.hist_file,'wt') as hfile:
143 143 json.dump(hist, hfile,
144 144 sort_keys=True, indent=4)
145 145
146 146 def reload_history(self):
147 147 """Reload the input history from disk file."""
148 148
149 149 with open(self.hist_file,'rt') as hfile:
150 150 hist = json.load(hfile)
151 151 self.input_hist_parsed = hist['parsed']
152 152 self.input_hist_raw = hist['raw']
153 153 if self.shell.has_readline:
154 154 self.populate_readline_history()
155 155
156 156 def get_history(self, index=None, raw=False, output=True):
157 157 """Get the history list.
158 158
159 159 Get the input and output history.
160 160
161 161 Parameters
162 162 ----------
163 163 index : n or (n1, n2) or None
164 164 If n, then the last entries. If a tuple, then all in
165 165 range(n1, n2). If None, then all entries. Raises IndexError if
166 166 the format of index is incorrect.
167 167 raw : bool
168 168 If True, return the raw input.
169 169 output : bool
170 170 If True, then return the output as well.
171 171
172 172 Returns
173 173 -------
174 174 If output is True, then return a dict of tuples, keyed by the prompt
175 175 numbers and with values of (input, output). If output is False, then
176 176 a dict, keyed by the prompt number with the values of input. Raises
177 177 IndexError if no history is found.
178 178 """
179 179 if raw:
180 180 input_hist = self.input_hist_raw
181 181 else:
182 182 input_hist = self.input_hist_parsed
183 183 if output:
184 184 output_hist = self.output_hist
185 185 n = len(input_hist)
186 186 if index is None:
187 187 start=0; stop=n
188 188 elif isinstance(index, int):
189 189 start=n-index; stop=n
190 190 elif isinstance(index, tuple) and len(index) == 2:
191 191 start=index[0]; stop=index[1]
192 192 else:
193 193 raise IndexError('Not a valid index for the input history: %r'
194 194 % index)
195 195 hist = {}
196 196 for i in range(start, stop):
197 197 if output:
198 198 hist[i] = (input_hist[i], output_hist.get(i))
199 199 else:
200 200 hist[i] = input_hist[i]
201 201 if not hist:
202 202 raise IndexError('No history for range of indices: %r' % index)
203 203 return hist
204 204
205 205 def store_inputs(self, source, source_raw=None):
206 206 """Store source and raw input in history and create input cache
207 207 variables _i*.
208 208
209 209 Parameters
210 210 ----------
211 211 source : str
212 212 Python input.
213 213
214 214 source_raw : str, optional
215 215 If given, this is the raw input without any IPython transformations
216 216 applied to it. If not given, ``source`` is used.
217 217 """
218 218 if source_raw is None:
219 219 source_raw = source
220 220
221 221 # do not store exit/quit commands
222 222 if source_raw.strip() in self._exit_commands:
223 223 return
224 224
225 225 self.input_hist_parsed.append(source.rstrip())
226 226 self.input_hist_raw.append(source_raw.rstrip())
227 227 self.shadow_hist.add(source)
228 228
229 229 # update the auto _i variables
230 230 self._iii = self._ii
231 231 self._ii = self._i
232 232 self._i = self._i00
233 233 self._i00 = source_raw
234 234
235 235 # hackish access to user namespace to create _i1,_i2... dynamically
236 236 new_i = '_i%s' % self.shell.execution_count
237 237 to_main = {'_i': self._i,
238 238 '_ii': self._ii,
239 239 '_iii': self._iii,
240 240 new_i : self._i00 }
241 241 self.shell.user_ns.update(to_main)
242 242
243 243 def sync_inputs(self):
244 244 """Ensure raw and translated histories have same length."""
245 245 if len(self.input_hist_parsed) != len (self.input_hist_raw):
246 246 self.input_hist_raw[:] = self.input_hist_parsed
247 247
248 248 def reset(self):
249 249 """Clear all histories managed by this object."""
250 250 self.input_hist_parsed[:] = []
251 251 self.input_hist_raw[:] = []
252 252 self.output_hist.clear()
253 253 # The directory history can't be completely empty
254 254 self.dir_hist[:] = [os.getcwd()]
255 255
256 256 class HistorySaveThread(threading.Thread):
257 257 """Thread to save history periodically"""
258
258 daemon = True
259
259 260 def __init__(self, IPython_object, time_interval, exit_now):
260 261 threading.Thread.__init__(self)
261 262 self.IPython_object = IPython_object
262 263 self.time_interval = time_interval
263 264 self.exit_now = exit_now
264 265 self.cond = threading.Condition()
265 266
266 267 def run(self):
267 268 while 1:
268 269 self.cond.acquire()
269 270 self.cond.wait(self.time_interval)
270 271 self.cond.release()
271 272 if self.exit_now==True:
272 273 break
273 274 #printing for debug
274 275 #print("Saving...")
275 276 self.IPython_object.save_history()
277
278 def stop(self):
279 self.exit_now=True
280 self.cond.acquire()
281 self.cond.notify()
282 self.cond.release()
276 283
277 284 def magic_history(self, parameter_s = ''):
278 285 """Print input history (_i<n> variables), with most recent last.
279 286
280 287 %history -> print at most 40 inputs (some may be multi-line)\\
281 288 %history n -> print at most n inputs\\
282 289 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
283 290
284 291 By default, input history is printed without line numbers so it can be
285 292 directly pasted into an editor.
286 293
287 294 With -n, each input's number <n> is shown, and is accessible as the
288 295 automatically generated variable _i<n> as well as In[<n>]. Multi-line
289 296 statements are printed starting at a new line for easy copy/paste.
290 297
291 298 Options:
292 299
293 300 -n: print line numbers for each input.
294 301 This feature is only available if numbered prompts are in use.
295 302
296 303 -o: also print outputs for each input.
297 304
298 305 -p: print classic '>>>' python prompts before each input. This is useful
299 306 for making documentation, and in conjunction with -o, for producing
300 307 doctest-ready output.
301 308
302 309 -r: (default) print the 'raw' history, i.e. the actual commands you typed.
303 310
304 311 -t: print the 'translated' history, as IPython understands it. IPython
305 312 filters your input and converts it all into valid Python source before
306 313 executing it (things like magics or aliases are turned into function
307 314 calls, for example). With this option, you'll see the native history
308 315 instead of the user-entered version: '%cd /' will be seen as
309 316 'get_ipython().magic("%cd /")' instead of '%cd /'.
310 317
311 318 -g: treat the arg as a pattern to grep for in (full) history.
312 319 This includes the "shadow history" (almost all commands ever written).
313 320 Use '%hist -g' to show full shadow history (may be very long).
314 321 In shadow history, every index nuwber starts with 0.
315 322
316 323 -f FILENAME: instead of printing the output to the screen, redirect it to
317 324 the given file. The file is always overwritten, though IPython asks for
318 325 confirmation first if it already exists.
319 326 """
320 327
321 328 if not self.shell.displayhook.do_full_cache:
322 329 print('This feature is only available if numbered prompts are in use.')
323 330 return
324 331 opts,args = self.parse_options(parameter_s,'gnoptsrf:',mode='list')
325 332
326 333 # Check if output to specific file was requested.
327 334 try:
328 335 outfname = opts['f']
329 336 except KeyError:
330 337 outfile = IPython.utils.io.Term.cout # default
331 338 # We don't want to close stdout at the end!
332 339 close_at_end = False
333 340 else:
334 341 if os.path.exists(outfname):
335 342 if not ask_yes_no("File %r exists. Overwrite?" % outfname):
336 343 print('Aborting.')
337 344 return
338 345
339 346 outfile = open(outfname,'w')
340 347 close_at_end = True
341 348
342 349 if 't' in opts:
343 350 input_hist = self.shell.history_manager.input_hist_parsed
344 351 elif 'r' in opts:
345 352 input_hist = self.shell.history_manager.input_hist_raw
346 353 else:
347 354 # Raw history is the default
348 355 input_hist = self.shell.history_manager.input_hist_raw
349 356
350 357 default_length = 40
351 358 pattern = None
352 359 if 'g' in opts:
353 360 init = 1
354 361 final = len(input_hist)
355 362 parts = parameter_s.split(None, 1)
356 363 if len(parts) == 1:
357 364 parts += '*'
358 365 head, pattern = parts
359 366 pattern = "*" + pattern + "*"
360 367 elif len(args) == 0:
361 368 final = len(input_hist)-1
362 369 init = max(1,final-default_length)
363 370 elif len(args) == 1:
364 371 final = len(input_hist)
365 372 init = max(1, final-int(args[0]))
366 373 elif len(args) == 2:
367 374 init, final = map(int, args)
368 375 else:
369 376 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
370 377 print(self.magic_hist.__doc__, file=IPython.utils.io.Term.cout)
371 378 return
372 379
373 380 width = len(str(final))
374 381 line_sep = ['','\n']
375 382 print_nums = 'n' in opts
376 383 print_outputs = 'o' in opts
377 384 pyprompts = 'p' in opts
378 385
379 386 found = False
380 387 if pattern is not None:
381 388 sh = self.shell.history_manager.shadowhist.all()
382 389 for idx, s in sh:
383 390 if fnmatch.fnmatch(s, pattern):
384 391 print("0%d: %s" %(idx, s.expandtabs(4)), file=outfile)
385 392 found = True
386 393
387 394 if found:
388 395 print("===", file=outfile)
389 396 print("shadow history ends, fetch by %rep <number> (must start with 0)",
390 397 file=outfile)
391 398 print("=== start of normal history ===", file=outfile)
392 399
393 400 for in_num in range(init, final):
394 401 # Print user history with tabs expanded to 4 spaces. The GUI clients
395 402 # use hard tabs for easier usability in auto-indented code, but we want
396 403 # to produce PEP-8 compliant history for safe pasting into an editor.
397 404 inline = input_hist[in_num].expandtabs(4).rstrip()+'\n'
398 405
399 406 if pattern is not None and not fnmatch.fnmatch(inline, pattern):
400 407 continue
401 408
402 409 multiline = int(inline.count('\n') > 1)
403 410 if print_nums:
404 411 print('%s:%s' % (str(in_num).ljust(width), line_sep[multiline]),
405 412 file=outfile)
406 413 if pyprompts:
407 414 print('>>>', file=outfile)
408 415 if multiline:
409 416 lines = inline.splitlines()
410 417 print('\n... '.join(lines), file=outfile)
411 418 print('... ', file=outfile)
412 419 else:
413 420 print(inline, end='', file=outfile)
414 421 else:
415 422 print(inline, end='', file=outfile)
416 423 if print_outputs:
417 424 output = self.shell.history_manager.output_hist.get(in_num)
418 425 if output is not None:
419 426 print(repr(output), file=outfile)
420 427
421 428 if close_at_end:
422 429 outfile.close()
423 430
424 431
425 432 def magic_hist(self, parameter_s=''):
426 433 """Alternate name for %history."""
427 434 return self.magic_history(parameter_s)
428 435
429 436
430 437 def rep_f(self, arg):
431 438 r""" Repeat a command, or get command to input line for editing
432 439
433 440 - %rep (no arguments):
434 441
435 442 Place a string version of last computation result (stored in the special '_'
436 443 variable) to the next input prompt. Allows you to create elaborate command
437 444 lines without using copy-paste::
438 445
439 446 $ l = ["hei", "vaan"]
440 447 $ "".join(l)
441 448 ==> heivaan
442 449 $ %rep
443 450 $ heivaan_ <== cursor blinking
444 451
445 452 %rep 45
446 453
447 454 Place history line 45 to next input prompt. Use %hist to find out the
448 455 number.
449 456
450 457 %rep 1-4 6-7 3
451 458
452 459 Repeat the specified lines immediately. Input slice syntax is the same as
453 460 in %macro and %save.
454 461
455 462 %rep foo
456 463
457 464 Place the most recent line that has the substring "foo" to next input.
458 465 (e.g. 'svn ci -m foobar').
459 466 """
460 467
461 468 opts,args = self.parse_options(arg,'',mode='list')
462 469 if not args:
463 470 self.set_next_input(str(self.shell.user_ns["_"]))
464 471 return
465 472
466 473 if len(args) == 1 and not '-' in args[0]:
467 474 arg = args[0]
468 475 if len(arg) > 1 and arg.startswith('0'):
469 476 # get from shadow hist
470 477 num = int(arg[1:])
471 478 line = self.shell.shadowhist.get(num)
472 479 self.set_next_input(str(line))
473 480 return
474 481 try:
475 482 num = int(args[0])
476 483 self.set_next_input(str(self.shell.input_hist_raw[num]).rstrip())
477 484 return
478 485 except ValueError:
479 486 pass
480 487
481 488 for h in reversed(self.shell.input_hist_raw):
482 489 if 'rep' in h:
483 490 continue
484 491 if fnmatch.fnmatch(h,'*' + arg + '*'):
485 492 self.set_next_input(str(h).rstrip())
486 493 return
487 494
488 495 try:
489 496 lines = self.extract_input_slices(args, True)
490 497 print("lines", lines)
491 498 self.run_cell(lines)
492 499 except ValueError:
493 500 print("Not found in recent history:", args)
494 501
495 502
496 503 _sentinel = object()
497 504
498 505 class ShadowHist(object):
499 506 def __init__(self, db, shell):
500 507 # cmd => idx mapping
501 508 self.curidx = 0
502 509 self.db = db
503 510 self.disabled = False
504 511 self.shell = shell
505 512
506 513 def inc_idx(self):
507 514 idx = self.db.get('shadowhist_idx', 1)
508 515 self.db['shadowhist_idx'] = idx + 1
509 516 return idx
510 517
511 518 def add(self, ent):
512 519 if self.disabled:
513 520 return
514 521 try:
515 522 old = self.db.hget('shadowhist', ent, _sentinel)
516 523 if old is not _sentinel:
517 524 return
518 525 newidx = self.inc_idx()
519 526 #print("new", newidx) # dbg
520 527 self.db.hset('shadowhist',ent, newidx)
521 528 except:
522 529 self.shell.showtraceback()
523 530 print("WARNING: disabling shadow history")
524 531 self.disabled = True
525 532
526 533 def all(self):
527 534 d = self.db.hdict('shadowhist')
528 535 items = [(i,s) for (s,i) in d.iteritems()]
529 536 items.sort()
530 537 return items
531 538
532 539 def get(self, idx):
533 540 all = self.all()
534 541
535 542 for k, v in all:
536 543 if k == idx:
537 544 return v
538 545
539 546
540 547 def init_ipython(ip):
541 548 ip.define_magic("rep",rep_f)
542 549 ip.define_magic("hist",magic_hist)
543 550 ip.define_magic("history",magic_history)
544 551
545 552 # XXX - ipy_completers are in quarantine, need to be updated to new apis
546 553 #import ipy_completers
547 554 #ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
@@ -1,619 +1,615 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Subclass of InteractiveShell for terminal based frontends."""
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
7 7 # Copyright (C) 2008-2010 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 import __builtin__
18 18 import bdb
19 19 from contextlib import nested
20 20 import os
21 21 import re
22 22 import sys
23 23
24 24 from IPython.core.error import TryNext
25 25 from IPython.core.usage import interactive_usage, default_banner
26 26 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
27 27 from IPython.core.history import HistorySaveThread
28 28 from IPython.lib.inputhook import enable_gui
29 29 from IPython.lib.pylabtools import pylab_activate
30 30 from IPython.utils.terminal import toggle_set_term_title, set_term_title
31 31 from IPython.utils.process import abbrev_cwd
32 32 from IPython.utils.warn import warn
33 33 from IPython.utils.text import num_ini_spaces
34 34 from IPython.utils.traitlets import Int, Str, CBool
35 35
36 36
37 37 #-----------------------------------------------------------------------------
38 38 # Utilities
39 39 #-----------------------------------------------------------------------------
40 40
41 41
42 42 def get_default_editor():
43 43 try:
44 44 ed = os.environ['EDITOR']
45 45 except KeyError:
46 46 if os.name == 'posix':
47 47 ed = 'vi' # the only one guaranteed to be there!
48 48 else:
49 49 ed = 'notepad' # same in Windows!
50 50 return ed
51 51
52 52
53 53 # store the builtin raw_input globally, and use this always, in case user code
54 54 # overwrites it (like wx.py.PyShell does)
55 55 raw_input_original = raw_input
56 56
57 57
58 58 #-----------------------------------------------------------------------------
59 59 # Main class
60 60 #-----------------------------------------------------------------------------
61 61
62 62
63 63 class TerminalInteractiveShell(InteractiveShell):
64 64
65 65 autoedit_syntax = CBool(False, config=True)
66 66 banner = Str('')
67 67 banner1 = Str(default_banner, config=True)
68 68 banner2 = Str('', config=True)
69 69 confirm_exit = CBool(True, config=True)
70 70 # This display_banner only controls whether or not self.show_banner()
71 71 # is called when mainloop/interact are called. The default is False
72 72 # because for the terminal based application, the banner behavior
73 73 # is controlled by Global.display_banner, which IPythonApp looks at
74 74 # to determine if *it* should call show_banner() by hand or not.
75 75 display_banner = CBool(False) # This isn't configurable!
76 76 embedded = CBool(False)
77 77 embedded_active = CBool(False)
78 78 editor = Str(get_default_editor(), config=True)
79 79 pager = Str('less', config=True)
80 80
81 81 screen_length = Int(0, config=True)
82 82 term_title = CBool(False, config=True)
83 83
84 84 def __init__(self, config=None, ipython_dir=None, user_ns=None,
85 85 user_global_ns=None, custom_exceptions=((),None),
86 86 usage=None, banner1=None, banner2=None,
87 87 display_banner=None):
88 88
89 89 super(TerminalInteractiveShell, self).__init__(
90 90 config=config, ipython_dir=ipython_dir, user_ns=user_ns,
91 91 user_global_ns=user_global_ns, custom_exceptions=custom_exceptions
92 92 )
93 93 self.init_term_title()
94 94 self.init_usage(usage)
95 95 self.init_banner(banner1, banner2, display_banner)
96 96
97 97 #-------------------------------------------------------------------------
98 98 # Things related to the terminal
99 99 #-------------------------------------------------------------------------
100 100
101 101 @property
102 102 def usable_screen_length(self):
103 103 if self.screen_length == 0:
104 104 return 0
105 105 else:
106 106 num_lines_bot = self.separate_in.count('\n')+1
107 107 return self.screen_length - num_lines_bot
108 108
109 109 def init_term_title(self):
110 110 # Enable or disable the terminal title.
111 111 if self.term_title:
112 112 toggle_set_term_title(True)
113 113 set_term_title('IPython: ' + abbrev_cwd())
114 114 else:
115 115 toggle_set_term_title(False)
116 116
117 117 #-------------------------------------------------------------------------
118 118 # Things related to aliases
119 119 #-------------------------------------------------------------------------
120 120
121 121 def init_alias(self):
122 122 # The parent class defines aliases that can be safely used with any
123 123 # frontend.
124 124 super(TerminalInteractiveShell, self).init_alias()
125 125
126 126 # Now define aliases that only make sense on the terminal, because they
127 127 # need direct access to the console in a way that we can't emulate in
128 128 # GUI or web frontend
129 129 if os.name == 'posix':
130 130 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
131 131 ('man', 'man')]
132 132 elif os.name == 'nt':
133 133 aliases = [('cls', 'cls')]
134 134
135 135
136 136 for name, cmd in aliases:
137 137 self.alias_manager.define_alias(name, cmd)
138 138
139 139 #-------------------------------------------------------------------------
140 140 # Things related to the banner and usage
141 141 #-------------------------------------------------------------------------
142 142
143 143 def _banner1_changed(self):
144 144 self.compute_banner()
145 145
146 146 def _banner2_changed(self):
147 147 self.compute_banner()
148 148
149 149 def _term_title_changed(self, name, new_value):
150 150 self.init_term_title()
151 151
152 152 def init_banner(self, banner1, banner2, display_banner):
153 153 if banner1 is not None:
154 154 self.banner1 = banner1
155 155 if banner2 is not None:
156 156 self.banner2 = banner2
157 157 if display_banner is not None:
158 158 self.display_banner = display_banner
159 159 self.compute_banner()
160 160
161 161 def show_banner(self, banner=None):
162 162 if banner is None:
163 163 banner = self.banner
164 164 self.write(banner)
165 165
166 166 def compute_banner(self):
167 167 self.banner = self.banner1
168 168 if self.profile:
169 169 self.banner += '\nIPython profile: %s\n' % self.profile
170 170 if self.banner2:
171 171 self.banner += '\n' + self.banner2
172 172
173 173 def init_usage(self, usage=None):
174 174 if usage is None:
175 175 self.usage = interactive_usage
176 176 else:
177 177 self.usage = usage
178 178
179 179 #-------------------------------------------------------------------------
180 180 # Mainloop and code execution logic
181 181 #-------------------------------------------------------------------------
182 182
183 183 def mainloop(self, display_banner=None):
184 184 """Start the mainloop.
185 185
186 186 If an optional banner argument is given, it will override the
187 187 internally created default banner.
188 188 """
189 189
190 190 with nested(self.builtin_trap, self.display_trap):
191 191
192 192 # if you run stuff with -c <cmd>, raw hist is not updated
193 193 # ensure that it's in sync
194 194 self.history_manager.sync_inputs()
195 195
196 196 while 1:
197 197 try:
198 198 self.interact(display_banner=display_banner)
199 199 #self.interact_with_readline()
200 200 # XXX for testing of a readline-decoupled repl loop, call
201 201 # interact_with_readline above
202 202 break
203 203 except KeyboardInterrupt:
204 204 # this should not be necessary, but KeyboardInterrupt
205 205 # handling seems rather unpredictable...
206 206 self.write("\nKeyboardInterrupt in interact()\n")
207 207
208 208 def interact(self, display_banner=None):
209 209 """Closely emulate the interactive Python console."""
210 210
211 211 # batch run -> do not interact
212 212 if self.exit_now:
213 213 return
214 214
215 215 if display_banner is None:
216 216 display_banner = self.display_banner
217 217 if display_banner:
218 218 self.show_banner()
219 219
220 220 more = False
221 221
222 222 # Mark activity in the builtins
223 223 __builtin__.__dict__['__IPYTHON__active'] += 1
224 224
225 225 if self.has_readline:
226 226 self.readline_startup_hook(self.pre_readline)
227 227 # exit_now is set by a call to %Exit or %Quit, through the
228 228 # ask_exit callback.
229 229
230 230 while not self.exit_now:
231 231 self.hooks.pre_prompt_hook()
232 232 if more:
233 233 try:
234 234 prompt = self.hooks.generate_prompt(True)
235 235 except:
236 236 self.showtraceback()
237 237 if self.autoindent:
238 238 self.rl_do_indent = True
239 239
240 240 else:
241 241 try:
242 242 prompt = self.hooks.generate_prompt(False)
243 243 except:
244 244 self.showtraceback()
245 245 try:
246 246 line = self.raw_input(prompt)
247 247 if self.exit_now:
248 248 # quick exit on sys.std[in|out] close
249 249 break
250 250 if self.autoindent:
251 251 self.rl_do_indent = False
252 252
253 253 except KeyboardInterrupt:
254 254 #double-guard against keyboardinterrupts during kbdint handling
255 255 try:
256 256 self.write('\nKeyboardInterrupt\n')
257 257 self.resetbuffer()
258 258 more = False
259 259 except KeyboardInterrupt:
260 260 pass
261 261 except EOFError:
262 262 if self.autoindent:
263 263 self.rl_do_indent = False
264 264 if self.has_readline:
265 265 self.readline_startup_hook(None)
266 266 self.write('\n')
267 267 self.exit()
268 268 except bdb.BdbQuit:
269 269 warn('The Python debugger has exited with a BdbQuit exception.\n'
270 270 'Because of how pdb handles the stack, it is impossible\n'
271 271 'for IPython to properly format this particular exception.\n'
272 272 'IPython will resume normal operation.')
273 273 except:
274 274 # exceptions here are VERY RARE, but they can be triggered
275 275 # asynchronously by signal handlers, for example.
276 276 self.showtraceback()
277 277 else:
278 278 self.input_splitter.push(line)
279 279 more = self.input_splitter.push_accepts_more()
280 280 if (self.SyntaxTB.last_syntax_error and
281 281 self.autoedit_syntax):
282 282 self.edit_syntax_error()
283 283 if not more:
284 284 source_raw = self.input_splitter.source_raw_reset()[1]
285 285 self.run_cell(source_raw)
286 286
287 287 # We are off again...
288 288 __builtin__.__dict__['__IPYTHON__active'] -= 1
289 289
290 290 # Turn off the exit flag, so the mainloop can be restarted if desired
291 291 self.exit_now = False
292 292
293 293 def raw_input(self, prompt='', continue_prompt=False):
294 294 """Write a prompt and read a line.
295 295
296 296 The returned line does not include the trailing newline.
297 297 When the user enters the EOF key sequence, EOFError is raised.
298 298
299 299 Optional inputs:
300 300
301 301 - prompt(''): a string to be printed to prompt the user.
302 302
303 303 - continue_prompt(False): whether this line is the first one or a
304 304 continuation in a sequence of inputs.
305 305 """
306 306 # Code run by the user may have modified the readline completer state.
307 307 # We must ensure that our completer is back in place.
308 308
309 309 if self.has_readline:
310 310 self.set_readline_completer()
311 311
312 312 try:
313 313 line = raw_input_original(prompt).decode(self.stdin_encoding)
314 314 except ValueError:
315 315 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
316 316 " or sys.stdout.close()!\nExiting IPython!")
317 317 self.ask_exit()
318 318 return ""
319 319
320 320 # Try to be reasonably smart about not re-indenting pasted input more
321 321 # than necessary. We do this by trimming out the auto-indent initial
322 322 # spaces, if the user's actual input started itself with whitespace.
323 323 if self.autoindent:
324 324 if num_ini_spaces(line) > self.indent_current_nsp:
325 325 line = line[self.indent_current_nsp:]
326 326 self.indent_current_nsp = 0
327 327
328 328 # store the unfiltered input before the user has any chance to modify
329 329 # it.
330 330 if line.strip():
331 331 if continue_prompt:
332 332 if self.has_readline and self.readline_use:
333 333 histlen = self.readline.get_current_history_length()
334 334 if histlen > 1:
335 335 newhist = self.history_manager.input_hist_raw[-1].rstrip()
336 336 self.readline.remove_history_item(histlen-1)
337 337 self.readline.replace_history_item(histlen-2,
338 338 newhist.encode(self.stdin_encoding))
339 339 else:
340 340 self.history_manager.input_hist_raw.append('%s\n' % line)
341 341 elif not continue_prompt:
342 342 self.history_manager.input_hist_raw.append('\n')
343 343 try:
344 344 lineout = self.prefilter_manager.prefilter_lines(line,continue_prompt)
345 345 except:
346 346 # blanket except, in case a user-defined prefilter crashes, so it
347 347 # can't take all of ipython with it.
348 348 self.showtraceback()
349 349 return ''
350 350 else:
351 351 return lineout
352 352
353 353
354 354 def raw_input(self, prompt=''):
355 355 """Write a prompt and read a line.
356 356
357 357 The returned line does not include the trailing newline.
358 358 When the user enters the EOF key sequence, EOFError is raised.
359 359
360 360 Optional inputs:
361 361
362 362 - prompt(''): a string to be printed to prompt the user.
363 363
364 364 - continue_prompt(False): whether this line is the first one or a
365 365 continuation in a sequence of inputs.
366 366 """
367 367 # Code run by the user may have modified the readline completer state.
368 368 # We must ensure that our completer is back in place.
369 369
370 370 if self.has_readline:
371 371 self.set_readline_completer()
372 372
373 373 try:
374 374 line = raw_input_original(prompt).decode(self.stdin_encoding)
375 375 except ValueError:
376 376 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
377 377 " or sys.stdout.close()!\nExiting IPython!")
378 378 self.ask_exit()
379 379 return ""
380 380
381 381 # Try to be reasonably smart about not re-indenting pasted input more
382 382 # than necessary. We do this by trimming out the auto-indent initial
383 383 # spaces, if the user's actual input started itself with whitespace.
384 384 if self.autoindent:
385 385 if num_ini_spaces(line) > self.indent_current_nsp:
386 386 line = line[self.indent_current_nsp:]
387 387 self.indent_current_nsp = 0
388 388
389 389 return line
390 390
391 391 #-------------------------------------------------------------------------
392 392 # Methods to support auto-editing of SyntaxErrors.
393 393 #-------------------------------------------------------------------------
394 394
395 395 def edit_syntax_error(self):
396 396 """The bottom half of the syntax error handler called in the main loop.
397 397
398 398 Loop until syntax error is fixed or user cancels.
399 399 """
400 400
401 401 while self.SyntaxTB.last_syntax_error:
402 402 # copy and clear last_syntax_error
403 403 err = self.SyntaxTB.clear_err_state()
404 404 if not self._should_recompile(err):
405 405 return
406 406 try:
407 407 # may set last_syntax_error again if a SyntaxError is raised
408 408 self.safe_execfile(err.filename,self.user_ns)
409 409 except:
410 410 self.showtraceback()
411 411 else:
412 412 try:
413 413 f = file(err.filename)
414 414 try:
415 415 # This should be inside a display_trap block and I
416 416 # think it is.
417 417 sys.displayhook(f.read())
418 418 finally:
419 419 f.close()
420 420 except:
421 421 self.showtraceback()
422 422
423 423 def _should_recompile(self,e):
424 424 """Utility routine for edit_syntax_error"""
425 425
426 426 if e.filename in ('<ipython console>','<input>','<string>',
427 427 '<console>','<BackgroundJob compilation>',
428 428 None):
429 429
430 430 return False
431 431 try:
432 432 if (self.autoedit_syntax and
433 433 not self.ask_yes_no('Return to editor to correct syntax error? '
434 434 '[Y/n] ','y')):
435 435 return False
436 436 except EOFError:
437 437 return False
438 438
439 439 def int0(x):
440 440 try:
441 441 return int(x)
442 442 except TypeError:
443 443 return 0
444 444 # always pass integer line and offset values to editor hook
445 445 try:
446 446 self.hooks.fix_error_editor(e.filename,
447 447 int0(e.lineno),int0(e.offset),e.msg)
448 448 except TryNext:
449 449 warn('Could not open editor')
450 450 return False
451 451 return True
452 452
453 453 #-------------------------------------------------------------------------
454 454 # Things related to GUI support and pylab
455 455 #-------------------------------------------------------------------------
456 456
457 457 def enable_pylab(self, gui=None):
458 458 """Activate pylab support at runtime.
459 459
460 460 This turns on support for matplotlib, preloads into the interactive
461 461 namespace all of numpy and pylab, and configures IPython to correcdtly
462 462 interact with the GUI event loop. The GUI backend to be used can be
463 463 optionally selected with the optional :param:`gui` argument.
464 464
465 465 Parameters
466 466 ----------
467 467 gui : optional, string
468 468
469 469 If given, dictates the choice of matplotlib GUI backend to use
470 470 (should be one of IPython's supported backends, 'tk', 'qt', 'wx' or
471 471 'gtk'), otherwise we use the default chosen by matplotlib (as
472 472 dictated by the matplotlib build-time options plus the user's
473 473 matplotlibrc configuration file).
474 474 """
475 475 # We want to prevent the loading of pylab to pollute the user's
476 476 # namespace as shown by the %who* magics, so we execute the activation
477 477 # code in an empty namespace, and we update *both* user_ns and
478 478 # user_ns_hidden with this information.
479 479 ns = {}
480 480 gui = pylab_activate(ns, gui)
481 481 self.user_ns.update(ns)
482 482 self.user_ns_hidden.update(ns)
483 483 # Now we must activate the gui pylab wants to use, and fix %run to take
484 484 # plot updates into account
485 485 enable_gui(gui)
486 486 self.magic_run = self._pylab_magic_run
487 487
488 488 #-------------------------------------------------------------------------
489 489 # Things related to exiting
490 490 #-------------------------------------------------------------------------
491 491
492 492 def ask_exit(self):
493 493 """ Ask the shell to exit. Can be overiden and used as a callback. """
494 494 self.exit_now = True
495 495
496 496 def exit(self):
497 497 """Handle interactive exit.
498 498
499 499 This method calls the ask_exit callback."""
500 500 if self.confirm_exit:
501 501 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
502 self.shell.history_thread.exit_now=True
503 self.shell.history_thread.cond.acquire()
504 self.shell.history_thread.cond.notify()
505 self.shell.history_thread.cond.release()
506 502 self.ask_exit()
507 503 else:
508 504 self.ask_exit()
509 505
510 506 #------------------------------------------------------------------------
511 507 # Magic overrides
512 508 #------------------------------------------------------------------------
513 509 # Once the base class stops inheriting from magic, this code needs to be
514 510 # moved into a separate machinery as well. For now, at least isolate here
515 511 # the magics which this class needs to implement differently from the base
516 512 # class, or that are unique to it.
517 513
518 514 def magic_autoindent(self, parameter_s = ''):
519 515 """Toggle autoindent on/off (if available)."""
520 516
521 517 self.shell.set_autoindent()
522 518 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
523 519
524 520 def magic_cpaste(self, parameter_s=''):
525 521 """Paste & execute a pre-formatted code block from clipboard.
526 522
527 523 You must terminate the block with '--' (two minus-signs) alone on the
528 524 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
529 525 is the new sentinel for this operation)
530 526
531 527 The block is dedented prior to execution to enable execution of method
532 528 definitions. '>' and '+' characters at the beginning of a line are
533 529 ignored, to allow pasting directly from e-mails, diff files and
534 530 doctests (the '...' continuation prompt is also stripped). The
535 531 executed block is also assigned to variable named 'pasted_block' for
536 532 later editing with '%edit pasted_block'.
537 533
538 534 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
539 535 This assigns the pasted block to variable 'foo' as string, without
540 536 dedenting or executing it (preceding >>> and + is still stripped)
541 537
542 538 '%cpaste -r' re-executes the block previously entered by cpaste.
543 539
544 540 Do not be alarmed by garbled output on Windows (it's a readline bug).
545 541 Just press enter and type -- (and press enter again) and the block
546 542 will be what was just pasted.
547 543
548 544 IPython statements (magics, shell escapes) are not supported (yet).
549 545
550 546 See also
551 547 --------
552 548 paste: automatically pull code from clipboard.
553 549 """
554 550
555 551 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
556 552 par = args.strip()
557 553 if opts.has_key('r'):
558 554 self._rerun_pasted()
559 555 return
560 556
561 557 sentinel = opts.get('s','--')
562 558
563 559 block = self._strip_pasted_lines_for_code(
564 560 self._get_pasted_lines(sentinel))
565 561
566 562 self._execute_block(block, par)
567 563
568 564 def magic_paste(self, parameter_s=''):
569 565 """Paste & execute a pre-formatted code block from clipboard.
570 566
571 567 The text is pulled directly from the clipboard without user
572 568 intervention and printed back on the screen before execution (unless
573 569 the -q flag is given to force quiet mode).
574 570
575 571 The block is dedented prior to execution to enable execution of method
576 572 definitions. '>' and '+' characters at the beginning of a line are
577 573 ignored, to allow pasting directly from e-mails, diff files and
578 574 doctests (the '...' continuation prompt is also stripped). The
579 575 executed block is also assigned to variable named 'pasted_block' for
580 576 later editing with '%edit pasted_block'.
581 577
582 578 You can also pass a variable name as an argument, e.g. '%paste foo'.
583 579 This assigns the pasted block to variable 'foo' as string, without
584 580 dedenting or executing it (preceding >>> and + is still stripped)
585 581
586 582 Options
587 583 -------
588 584
589 585 -r: re-executes the block previously entered by cpaste.
590 586
591 587 -q: quiet mode: do not echo the pasted text back to the terminal.
592 588
593 589 IPython statements (magics, shell escapes) are not supported (yet).
594 590
595 591 See also
596 592 --------
597 593 cpaste: manually paste code into terminal until you mark its end.
598 594 """
599 595 opts,args = self.parse_options(parameter_s,'rq',mode='string')
600 596 par = args.strip()
601 597 if opts.has_key('r'):
602 598 self._rerun_pasted()
603 599 return
604 600
605 601 text = self.shell.hooks.clipboard_get()
606 602 block = self._strip_pasted_lines_for_code(text.splitlines())
607 603
608 604 # By default, echo back to terminal unless quiet mode is requested
609 605 if not opts.has_key('q'):
610 606 write = self.shell.write
611 607 write(self.shell.pycolorize(block))
612 608 if not block.endswith('\n'):
613 609 write('\n')
614 610 write("## -- End pasted text --\n")
615 611
616 612 self._execute_block(block, par)
617 613
618 614
619 615 InteractiveShellABC.register(TerminalInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now