##// END OF EJS Templates
Periodic Autosave added in background thread...
Mani chandra -
Show More
@@ -1,547 +1,547 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
259 259 def __init__(self, IPython_object, time_interval, exit_now):
260 260 threading.Thread.__init__(self)
261 261 self.IPython_object = IPython_object
262 262 self.time_interval = time_interval
263 263 self.exit_now = exit_now
264 264 self.cond = threading.Condition()
265 265
266 266 def run(self):
267 267 while 1:
268 268 self.cond.acquire()
269 269 self.cond.wait(self.time_interval)
270 270 self.cond.release()
271 271 if self.exit_now==True:
272 272 break
273 273 #printing for debug
274 print("Saving...")
274 #print("Saving...")
275 275 self.IPython_object.save_history()
276 276
277 277 def magic_history(self, parameter_s = ''):
278 278 """Print input history (_i<n> variables), with most recent last.
279 279
280 280 %history -> print at most 40 inputs (some may be multi-line)\\
281 281 %history n -> print at most n inputs\\
282 282 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
283 283
284 284 By default, input history is printed without line numbers so it can be
285 285 directly pasted into an editor.
286 286
287 287 With -n, each input's number <n> is shown, and is accessible as the
288 288 automatically generated variable _i<n> as well as In[<n>]. Multi-line
289 289 statements are printed starting at a new line for easy copy/paste.
290 290
291 291 Options:
292 292
293 293 -n: print line numbers for each input.
294 294 This feature is only available if numbered prompts are in use.
295 295
296 296 -o: also print outputs for each input.
297 297
298 298 -p: print classic '>>>' python prompts before each input. This is useful
299 299 for making documentation, and in conjunction with -o, for producing
300 300 doctest-ready output.
301 301
302 302 -r: (default) print the 'raw' history, i.e. the actual commands you typed.
303 303
304 304 -t: print the 'translated' history, as IPython understands it. IPython
305 305 filters your input and converts it all into valid Python source before
306 306 executing it (things like magics or aliases are turned into function
307 307 calls, for example). With this option, you'll see the native history
308 308 instead of the user-entered version: '%cd /' will be seen as
309 309 'get_ipython().magic("%cd /")' instead of '%cd /'.
310 310
311 311 -g: treat the arg as a pattern to grep for in (full) history.
312 312 This includes the "shadow history" (almost all commands ever written).
313 313 Use '%hist -g' to show full shadow history (may be very long).
314 314 In shadow history, every index nuwber starts with 0.
315 315
316 316 -f FILENAME: instead of printing the output to the screen, redirect it to
317 317 the given file. The file is always overwritten, though IPython asks for
318 318 confirmation first if it already exists.
319 319 """
320 320
321 321 if not self.shell.displayhook.do_full_cache:
322 322 print('This feature is only available if numbered prompts are in use.')
323 323 return
324 324 opts,args = self.parse_options(parameter_s,'gnoptsrf:',mode='list')
325 325
326 326 # Check if output to specific file was requested.
327 327 try:
328 328 outfname = opts['f']
329 329 except KeyError:
330 330 outfile = IPython.utils.io.Term.cout # default
331 331 # We don't want to close stdout at the end!
332 332 close_at_end = False
333 333 else:
334 334 if os.path.exists(outfname):
335 335 if not ask_yes_no("File %r exists. Overwrite?" % outfname):
336 336 print('Aborting.')
337 337 return
338 338
339 339 outfile = open(outfname,'w')
340 340 close_at_end = True
341 341
342 342 if 't' in opts:
343 343 input_hist = self.shell.history_manager.input_hist_parsed
344 344 elif 'r' in opts:
345 345 input_hist = self.shell.history_manager.input_hist_raw
346 346 else:
347 347 # Raw history is the default
348 348 input_hist = self.shell.history_manager.input_hist_raw
349 349
350 350 default_length = 40
351 351 pattern = None
352 352 if 'g' in opts:
353 353 init = 1
354 354 final = len(input_hist)
355 355 parts = parameter_s.split(None, 1)
356 356 if len(parts) == 1:
357 357 parts += '*'
358 358 head, pattern = parts
359 359 pattern = "*" + pattern + "*"
360 360 elif len(args) == 0:
361 361 final = len(input_hist)-1
362 362 init = max(1,final-default_length)
363 363 elif len(args) == 1:
364 364 final = len(input_hist)
365 365 init = max(1, final-int(args[0]))
366 366 elif len(args) == 2:
367 367 init, final = map(int, args)
368 368 else:
369 369 warn('%hist takes 0, 1 or 2 arguments separated by spaces.')
370 370 print(self.magic_hist.__doc__, file=IPython.utils.io.Term.cout)
371 371 return
372 372
373 373 width = len(str(final))
374 374 line_sep = ['','\n']
375 375 print_nums = 'n' in opts
376 376 print_outputs = 'o' in opts
377 377 pyprompts = 'p' in opts
378 378
379 379 found = False
380 380 if pattern is not None:
381 381 sh = self.shell.history_manager.shadowhist.all()
382 382 for idx, s in sh:
383 383 if fnmatch.fnmatch(s, pattern):
384 384 print("0%d: %s" %(idx, s.expandtabs(4)), file=outfile)
385 385 found = True
386 386
387 387 if found:
388 388 print("===", file=outfile)
389 389 print("shadow history ends, fetch by %rep <number> (must start with 0)",
390 390 file=outfile)
391 391 print("=== start of normal history ===", file=outfile)
392 392
393 393 for in_num in range(init, final):
394 394 # Print user history with tabs expanded to 4 spaces. The GUI clients
395 395 # use hard tabs for easier usability in auto-indented code, but we want
396 396 # to produce PEP-8 compliant history for safe pasting into an editor.
397 397 inline = input_hist[in_num].expandtabs(4).rstrip()+'\n'
398 398
399 399 if pattern is not None and not fnmatch.fnmatch(inline, pattern):
400 400 continue
401 401
402 402 multiline = int(inline.count('\n') > 1)
403 403 if print_nums:
404 404 print('%s:%s' % (str(in_num).ljust(width), line_sep[multiline]),
405 405 file=outfile)
406 406 if pyprompts:
407 407 print('>>>', file=outfile)
408 408 if multiline:
409 409 lines = inline.splitlines()
410 410 print('\n... '.join(lines), file=outfile)
411 411 print('... ', file=outfile)
412 412 else:
413 413 print(inline, end='', file=outfile)
414 414 else:
415 415 print(inline, end='', file=outfile)
416 416 if print_outputs:
417 417 output = self.shell.history_manager.output_hist.get(in_num)
418 418 if output is not None:
419 419 print(repr(output), file=outfile)
420 420
421 421 if close_at_end:
422 422 outfile.close()
423 423
424 424
425 425 def magic_hist(self, parameter_s=''):
426 426 """Alternate name for %history."""
427 427 return self.magic_history(parameter_s)
428 428
429 429
430 430 def rep_f(self, arg):
431 431 r""" Repeat a command, or get command to input line for editing
432 432
433 433 - %rep (no arguments):
434 434
435 435 Place a string version of last computation result (stored in the special '_'
436 436 variable) to the next input prompt. Allows you to create elaborate command
437 437 lines without using copy-paste::
438 438
439 439 $ l = ["hei", "vaan"]
440 440 $ "".join(l)
441 441 ==> heivaan
442 442 $ %rep
443 443 $ heivaan_ <== cursor blinking
444 444
445 445 %rep 45
446 446
447 447 Place history line 45 to next input prompt. Use %hist to find out the
448 448 number.
449 449
450 450 %rep 1-4 6-7 3
451 451
452 452 Repeat the specified lines immediately. Input slice syntax is the same as
453 453 in %macro and %save.
454 454
455 455 %rep foo
456 456
457 457 Place the most recent line that has the substring "foo" to next input.
458 458 (e.g. 'svn ci -m foobar').
459 459 """
460 460
461 461 opts,args = self.parse_options(arg,'',mode='list')
462 462 if not args:
463 463 self.set_next_input(str(self.shell.user_ns["_"]))
464 464 return
465 465
466 466 if len(args) == 1 and not '-' in args[0]:
467 467 arg = args[0]
468 468 if len(arg) > 1 and arg.startswith('0'):
469 469 # get from shadow hist
470 470 num = int(arg[1:])
471 471 line = self.shell.shadowhist.get(num)
472 472 self.set_next_input(str(line))
473 473 return
474 474 try:
475 475 num = int(args[0])
476 476 self.set_next_input(str(self.shell.input_hist_raw[num]).rstrip())
477 477 return
478 478 except ValueError:
479 479 pass
480 480
481 481 for h in reversed(self.shell.input_hist_raw):
482 482 if 'rep' in h:
483 483 continue
484 484 if fnmatch.fnmatch(h,'*' + arg + '*'):
485 485 self.set_next_input(str(h).rstrip())
486 486 return
487 487
488 488 try:
489 489 lines = self.extract_input_slices(args, True)
490 490 print("lines", lines)
491 491 self.run_cell(lines)
492 492 except ValueError:
493 493 print("Not found in recent history:", args)
494 494
495 495
496 496 _sentinel = object()
497 497
498 498 class ShadowHist(object):
499 499 def __init__(self, db, shell):
500 500 # cmd => idx mapping
501 501 self.curidx = 0
502 502 self.db = db
503 503 self.disabled = False
504 504 self.shell = shell
505 505
506 506 def inc_idx(self):
507 507 idx = self.db.get('shadowhist_idx', 1)
508 508 self.db['shadowhist_idx'] = idx + 1
509 509 return idx
510 510
511 511 def add(self, ent):
512 512 if self.disabled:
513 513 return
514 514 try:
515 515 old = self.db.hget('shadowhist', ent, _sentinel)
516 516 if old is not _sentinel:
517 517 return
518 518 newidx = self.inc_idx()
519 519 #print("new", newidx) # dbg
520 520 self.db.hset('shadowhist',ent, newidx)
521 521 except:
522 522 self.shell.showtraceback()
523 523 print("WARNING: disabling shadow history")
524 524 self.disabled = True
525 525
526 526 def all(self):
527 527 d = self.db.hdict('shadowhist')
528 528 items = [(i,s) for (s,i) in d.iteritems()]
529 529 items.sort()
530 530 return items
531 531
532 532 def get(self, idx):
533 533 all = self.all()
534 534
535 535 for k, v in all:
536 536 if k == idx:
537 537 return v
538 538
539 539
540 540 def init_ipython(ip):
541 541 ip.define_magic("rep",rep_f)
542 542 ip.define_magic("hist",magic_hist)
543 543 ip.define_magic("history",magic_history)
544 544
545 545 # XXX - ipy_completers are in quarantine, need to be updated to new apis
546 546 #import ipy_completers
547 547 #ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
@@ -1,621 +1,619 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 502 self.shell.history_thread.exit_now=True
503 503 self.shell.history_thread.cond.acquire()
504 504 self.shell.history_thread.cond.notify()
505 505 self.shell.history_thread.cond.release()
506 506 self.ask_exit()
507 507 else:
508 self.shell.history_thread = HistorySaveThread(self.shell, 60, False)
509 self.shell.history_thread.start()
510 508 self.ask_exit()
511 509
512 510 #------------------------------------------------------------------------
513 511 # Magic overrides
514 512 #------------------------------------------------------------------------
515 513 # Once the base class stops inheriting from magic, this code needs to be
516 514 # moved into a separate machinery as well. For now, at least isolate here
517 515 # the magics which this class needs to implement differently from the base
518 516 # class, or that are unique to it.
519 517
520 518 def magic_autoindent(self, parameter_s = ''):
521 519 """Toggle autoindent on/off (if available)."""
522 520
523 521 self.shell.set_autoindent()
524 522 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
525 523
526 524 def magic_cpaste(self, parameter_s=''):
527 525 """Paste & execute a pre-formatted code block from clipboard.
528 526
529 527 You must terminate the block with '--' (two minus-signs) alone on the
530 528 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
531 529 is the new sentinel for this operation)
532 530
533 531 The block is dedented prior to execution to enable execution of method
534 532 definitions. '>' and '+' characters at the beginning of a line are
535 533 ignored, to allow pasting directly from e-mails, diff files and
536 534 doctests (the '...' continuation prompt is also stripped). The
537 535 executed block is also assigned to variable named 'pasted_block' for
538 536 later editing with '%edit pasted_block'.
539 537
540 538 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
541 539 This assigns the pasted block to variable 'foo' as string, without
542 540 dedenting or executing it (preceding >>> and + is still stripped)
543 541
544 542 '%cpaste -r' re-executes the block previously entered by cpaste.
545 543
546 544 Do not be alarmed by garbled output on Windows (it's a readline bug).
547 545 Just press enter and type -- (and press enter again) and the block
548 546 will be what was just pasted.
549 547
550 548 IPython statements (magics, shell escapes) are not supported (yet).
551 549
552 550 See also
553 551 --------
554 552 paste: automatically pull code from clipboard.
555 553 """
556 554
557 555 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
558 556 par = args.strip()
559 557 if opts.has_key('r'):
560 558 self._rerun_pasted()
561 559 return
562 560
563 561 sentinel = opts.get('s','--')
564 562
565 563 block = self._strip_pasted_lines_for_code(
566 564 self._get_pasted_lines(sentinel))
567 565
568 566 self._execute_block(block, par)
569 567
570 568 def magic_paste(self, parameter_s=''):
571 569 """Paste & execute a pre-formatted code block from clipboard.
572 570
573 571 The text is pulled directly from the clipboard without user
574 572 intervention and printed back on the screen before execution (unless
575 573 the -q flag is given to force quiet mode).
576 574
577 575 The block is dedented prior to execution to enable execution of method
578 576 definitions. '>' and '+' characters at the beginning of a line are
579 577 ignored, to allow pasting directly from e-mails, diff files and
580 578 doctests (the '...' continuation prompt is also stripped). The
581 579 executed block is also assigned to variable named 'pasted_block' for
582 580 later editing with '%edit pasted_block'.
583 581
584 582 You can also pass a variable name as an argument, e.g. '%paste foo'.
585 583 This assigns the pasted block to variable 'foo' as string, without
586 584 dedenting or executing it (preceding >>> and + is still stripped)
587 585
588 586 Options
589 587 -------
590 588
591 589 -r: re-executes the block previously entered by cpaste.
592 590
593 591 -q: quiet mode: do not echo the pasted text back to the terminal.
594 592
595 593 IPython statements (magics, shell escapes) are not supported (yet).
596 594
597 595 See also
598 596 --------
599 597 cpaste: manually paste code into terminal until you mark its end.
600 598 """
601 599 opts,args = self.parse_options(parameter_s,'rq',mode='string')
602 600 par = args.strip()
603 601 if opts.has_key('r'):
604 602 self._rerun_pasted()
605 603 return
606 604
607 605 text = self.shell.hooks.clipboard_get()
608 606 block = self._strip_pasted_lines_for_code(text.splitlines())
609 607
610 608 # By default, echo back to terminal unless quiet mode is requested
611 609 if not opts.has_key('q'):
612 610 write = self.shell.write
613 611 write(self.shell.pycolorize(block))
614 612 if not block.endswith('\n'):
615 613 write('\n')
616 614 write("## -- End pasted text --\n")
617 615
618 616 self._execute_block(block, par)
619 617
620 618
621 619 InteractiveShellABC.register(TerminalInteractiveShell)
General Comments 0
You need to be logged in to leave comments. Login now