##// END OF EJS Templates
Tweak to history_manager.store_inputs to pass tests.
Thomas Kluyver -
Show More
@@ -1,656 +1,656 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 datetime
17 17 import json
18 18 import os
19 19 import re
20 20 import sqlite3
21 21
22 22 from collections import defaultdict
23 23
24 24 # Our own packages
25 25 from IPython.config.configurable import Configurable
26 26 import IPython.utils.io
27 27
28 28 from IPython.testing import decorators as testdec
29 29 from IPython.utils.io import ask_yes_no
30 30 from IPython.utils.traitlets import Bool, Dict, Instance, Int, List, Unicode
31 31 from IPython.utils.warn import warn
32 32
33 33 #-----------------------------------------------------------------------------
34 34 # Classes and functions
35 35 #-----------------------------------------------------------------------------
36 36
37 37 class HistoryManager(Configurable):
38 38 """A class to organize all history-related functionality in one place.
39 39 """
40 40 # Public interface
41 41
42 42 # An instance of the IPython shell we are attached to
43 43 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
44 44 # Lists to hold processed and raw history. These start with a blank entry
45 45 # so that we can index them starting from 1
46 46 input_hist_parsed = List([""])
47 47 input_hist_raw = List([""])
48 48 # A list of directories visited during session
49 49 dir_hist = List()
50 50 # A dict of output history, keyed with ints from the shell's
51 51 # execution count. If there are several outputs from one command,
52 52 # only the last one is stored.
53 53 output_hist = Dict()
54 54 # Contains all outputs, in lists of reprs.
55 55 output_hist_reprs = Instance(defaultdict)
56 56
57 57 # String holding the path to the history file
58 58 hist_file = Unicode()
59 59 # The SQLite database
60 60 db = Instance(sqlite3.Connection)
61 61 # The number of the current session in the history database
62 62 session_number = Int()
63 63 # Should we log output to the database? (default no)
64 64 db_log_output = Bool(False, config=True)
65 65 # Write to database every x commands (higher values save disk access & power)
66 66 # Values of 1 or less effectively disable caching.
67 67 db_cache_size = Int(0, config=True)
68 68 # The input and output caches
69 69 db_input_cache = List()
70 70 db_output_cache = List()
71 71
72 72 # Private interface
73 73 # Variables used to store the three last inputs from the user. On each new
74 74 # history update, we populate the user's namespace with these, shifted as
75 75 # necessary.
76 76 _i00, _i, _ii, _iii = '','','',''
77 77
78 78 # A set with all forms of the exit command, so that we don't store them in
79 79 # the history (it's annoying to rewind the first entry and land on an exit
80 80 # call).
81 81 _exit_commands = None
82 82
83 83 def __init__(self, shell, config=None):
84 84 """Create a new history manager associated with a shell instance.
85 85 """
86 86 # We need a pointer back to the shell for various tasks.
87 87 super(HistoryManager, self).__init__(shell=shell, config=config)
88 88
89 89 # list of visited directories
90 90 try:
91 91 self.dir_hist = [os.getcwd()]
92 92 except OSError:
93 93 self.dir_hist = []
94 94
95 95 # Now the history file
96 96 if shell.profile:
97 97 histfname = 'history-%s' % shell.profile
98 98 else:
99 99 histfname = 'history'
100 100 self.hist_file = os.path.join(shell.ipython_dir, histfname + '.sqlite')
101 101 self.init_db()
102 102 self.new_session()
103 103
104 104 self._i00, self._i, self._ii, self._iii = '','','',''
105 105 self.output_hist_reprs = defaultdict(list)
106 106
107 107 self._exit_commands = set(['Quit', 'quit', 'Exit', 'exit', '%Quit',
108 108 '%quit', '%Exit', '%exit'])
109 109
110 110 def init_db(self):
111 111 """Connect to the database, and create tables if necessary."""
112 112 self.db = sqlite3.connect(self.hist_file)
113 113 self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
114 114 primary key autoincrement, start timestamp,
115 115 end timestamp, num_cmds integer, remark text)""")
116 116 self.db.execute("""CREATE TABLE IF NOT EXISTS history
117 117 (session integer, line integer, source text, source_raw text,
118 118 PRIMARY KEY (session, line))""")
119 119 # Output history is optional, but ensure the table's there so it can be
120 120 # enabled later.
121 121 self.db.execute("""CREATE TABLE IF NOT EXISTS output_history
122 122 (session integer, line integer, output text,
123 123 PRIMARY KEY (session, line))""")
124 124 self.db.commit()
125 125
126 126 def new_session(self):
127 127 """Get a new session number."""
128 128 with self.db:
129 129 cur = self.db.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL,
130 130 NULL, "") """, (datetime.datetime.now(),))
131 131 self.session_number = cur.lastrowid
132 132
133 133 def end_session(self):
134 134 """Close the database session, filling in the end time and line count."""
135 135 self.writeout_cache()
136 136 with self.db:
137 137 self.db.execute("""UPDATE sessions SET end=?, num_cmds=? WHERE
138 138 session==?""", (datetime.datetime.now(),
139 139 len(self.input_hist_parsed)-1, self.session_number))
140 140 self.session_number = 0
141 141
142 142 def name_session(self, name):
143 143 """Give the current session a name in the history database."""
144 144 with self.db:
145 145 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
146 146 (name, self.session_number))
147 147
148 148 def reset(self, new_session=True):
149 149 """Clear the session history, releasing all object references, and
150 150 optionally open a new session."""
151 151 if self.session_number:
152 152 self.end_session()
153 153 self.input_hist_parsed[:] = [""]
154 154 self.input_hist_raw[:] = [""]
155 155 self.output_hist.clear()
156 156 # The directory history can't be completely empty
157 157 self.dir_hist[:] = [os.getcwd()]
158 158
159 159 if new_session:
160 160 self.new_session()
161 161
162 162 ## -------------------------------
163 163 ## Methods for retrieving history:
164 164 ## -------------------------------
165 165 def _get_hist_sql(self, sql, params, raw=True, output=False):
166 166 """Prepares and runs an SQL query for the history database.
167 167
168 168 Parameters
169 169 ----------
170 170 sql : str
171 171 Any filtering expressions to go after SELECT ... FROM ...
172 172 params : tuple
173 173 Parameters passed to the SQL query (to replace "?")
174 174 raw : bool
175 175 If True, get raw input.
176 176 output : bool
177 177 If True, include output where available.
178 178
179 179 Returns
180 180 -------
181 181 An iterator over 3-tuples: (session, line_number, command), or if output
182 182 is True, (session, line_number, (command, output)).
183 183 """
184 184 toget = 'source_raw' if raw else 'source'
185 185 sqlfrom = "history"
186 186 if output:
187 187 sqlfrom = "history LEFT JOIN output_history USING (session, line)"
188 188 toget = "history.%s, output_history.output" % toget
189 189 cur = self.db.execute("SELECT session, line, %s FROM %s " %\
190 190 (toget, sqlfrom) + sql, params)
191 191 if output: # Regroup into 3-tuples, and parse JSON
192 192 loads = lambda out: json.loads(out) if out else None
193 193 return ((ses, lin, (inp, loads(out))) \
194 194 for ses, lin, inp, out in cur)
195 195 return cur
196 196
197 197
198 198 def get_hist_tail(self, n=10, raw=True, output=False):
199 199 """Get the last n lines from the history database."""
200 200 self.writeout_cache()
201 201 cur = self._get_hist_sql("ORDER BY session DESC, line DESC LIMIT ?",
202 202 (n,), raw=raw, output=output)
203 203 return reversed(list(cur))
204 204
205 205 def get_hist_search(self, pattern="*", raw=True, search_raw=True,
206 206 output=False):
207 207 """Search the database using unix glob-style matching (wildcards * and
208 208 ?, escape using \).
209 209
210 210 Returns
211 211 -------
212 212 An iterator over tuples: (session, line_number, command)
213 213 """
214 214 tosearch = "source_raw" if search_raw else "source"
215 215 if output:
216 216 tosearch = "history." + tosearch
217 217 self.writeout_cache()
218 218 return self._get_hist_sql("WHERE %s GLOB ?" % tosearch, (pattern,),
219 219 raw=raw, output=output)
220 220
221 221 def _get_hist_session(self, start=1, stop=None, raw=True, output=False):
222 222 """Get input and output history from the current session. Called by
223 223 get_history, and takes similar parameters."""
224 224 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
225 225
226 226 n = len(input_hist)
227 227 if start < 0:
228 228 start += n
229 229 if not stop:
230 230 stop = n
231 231 elif stop < 0:
232 232 stop += n
233 233
234 234 for i in range(start, stop):
235 235 if output:
236 236 line = (input_hist[i], self.output_hist_reprs.get(i))
237 237 else:
238 238 line = input_hist[i]
239 239 yield (0, i, line)
240 240
241 241 def get_history(self, session=0, start=1, stop=None, raw=True,output=False):
242 242 """Retrieve input by session.
243 243
244 244 Parameters
245 245 ----------
246 246 session : int
247 247 Session number to retrieve. The current session is 0, and negative
248 248 numbers count back from current session, so -1 is previous session.
249 249 start : int
250 250 First line to retrieve.
251 251 stop : int
252 252 End of line range (excluded from output itself). If None, retrieve
253 253 to the end of the session.
254 254 raw : bool
255 255 If True, return untranslated input
256 256 output : bool
257 257 If True, attempt to include output. This will be 'real' Python
258 258 objects for the current session, or text reprs from previous
259 259 sessions if db_log_output was enabled at the time. Where no output
260 260 is found, None is used.
261 261
262 262 Returns
263 263 -------
264 264 An iterator over the desired lines. Each line is a 3-tuple, either
265 265 (session, line, input) if output is False, or
266 266 (session, line, (input, output)) if output is True.
267 267 """
268 268 if session == 0 or session==self.session_number: # Current session
269 269 return self._get_hist_session(start, stop, raw, output)
270 270 if session < 0:
271 271 session += self.session_number
272 272
273 273 if stop:
274 274 lineclause = "line >= ? AND line < ?"
275 275 params = (session, start, stop)
276 276 else:
277 277 lineclause = "line>=?"
278 278 params = (session, start)
279 279
280 280 return self._get_hist_sql("WHERE session==? AND %s""" % lineclause,
281 281 params, raw=raw, output=output)
282 282
283 283 def get_hist_from_rangestr(self, rangestr, raw=True, output=False):
284 284 """Get lines of history from a string of ranges, as used by magic
285 285 commands %hist, %save, %macro, etc."""
286 286 for sess, s, e in extract_hist_ranges(rangestr):
287 287 for line in self.get_history(sess, s, e, raw=raw, output=output):
288 288 yield line
289 289
290 290 ## ----------------------------
291 291 ## Methods for storing history:
292 292 ## ----------------------------
293 293 def store_inputs(self, line_num, source, source_raw=None):
294 294 """Store source and raw input in history and create input cache
295 295 variables _i*.
296 296
297 297 Parameters
298 298 ----------
299 299 line_num : int
300 300 The prompt number of this input.
301 301
302 302 source : str
303 303 Python input.
304 304
305 305 source_raw : str, optional
306 306 If given, this is the raw input without any IPython transformations
307 307 applied to it. If not given, ``source`` is used.
308 308 """
309 309 if source_raw is None:
310 310 source_raw = source
311 source = source.rstrip()
312 source_raw = source_raw.rstrip()
311 source = source.rstrip('\n')
312 source_raw = source_raw.rstrip('\n')
313 313
314 314 # do not store exit/quit commands
315 315 if source_raw.strip() in self._exit_commands:
316 316 return
317 317
318 318 self.input_hist_parsed.append(source)
319 319 self.input_hist_raw.append(source_raw)
320 320
321 321 self.db_input_cache.append((self.session_number, line_num,
322 322 source, source_raw))
323 323 # Trigger to flush cache and write to DB.
324 324 if len(self.db_input_cache) >= self.db_cache_size:
325 325 self.writeout_cache()
326 326
327 327 # update the auto _i variables
328 328 self._iii = self._ii
329 329 self._ii = self._i
330 330 self._i = self._i00
331 331 self._i00 = source_raw
332 332
333 333 # hackish access to user namespace to create _i1,_i2... dynamically
334 334 new_i = '_i%s' % line_num
335 335 to_main = {'_i': self._i,
336 336 '_ii': self._ii,
337 337 '_iii': self._iii,
338 338 new_i : self._i00 }
339 339 self.shell.user_ns.update(to_main)
340 340
341 341 def store_output(self, line_num):
342 342 """If database output logging is enabled, this saves all the
343 343 outputs from the indicated prompt number to the database. It's
344 344 called by run_cell after code has been executed."""
345 345 if (not self.db_log_output) or not self.output_hist_reprs[line_num]:
346 346 return
347 347 output = json.dumps(self.output_hist_reprs[line_num])
348 348 db_row = (self.session_number, line_num, output)
349 349 if self.db_cache_size > 1:
350 350 self.db_output_cache.append(db_row)
351 351 else:
352 352 with self.db:
353 353 self.db.execute("INSERT INTO output_history VALUES (?,?,?)", db_row)
354 354
355 355 def writeout_cache(self):
356 356 #print(self.db_input_cache)
357 357 with self.db:
358 358 self.db.executemany("INSERT INTO history VALUES (?, ?, ?, ?)",
359 359 self.db_input_cache)
360 360 self.db.executemany("INSERT INTO output_history VALUES (?, ?, ?)",
361 361 self.db_output_cache)
362 362 self.db_input_cache = []
363 363 self.db_output_cache = []
364 364
365 365
366 366 # To match, e.g. ~5/8-~2/3
367 367 range_re = re.compile(r"""
368 368 ((?P<startsess>~?\d+)/)?
369 369 (?P<start>\d+) # Only the start line num is compulsory
370 370 ((?P<sep>[\-:])
371 371 ((?P<endsess>~?\d+)/)?
372 372 (?P<end>\d+))?
373 373 """, re.VERBOSE)
374 374
375 375 def extract_hist_ranges(ranges_str):
376 376 """Turn a string of history ranges into 3-tuples of (session, start, stop).
377 377
378 378 Examples
379 379 --------
380 380 list(extract_input_ranges("~8/5-~7/4 2"))
381 381 [(-8, 5, None), (-7, 1, 4), (0, 2, 3)]
382 382 """
383 383 for range_str in ranges_str.split():
384 384 rmatch = range_re.match(range_str)
385 385 if not rmatch:
386 386 continue
387 387 start = int(rmatch.group("start"))
388 388 end = rmatch.group("end")
389 389 end = int(end) if end else start+1 # If no end specified, get (a, a+1)
390 390 if rmatch.group("sep") == "-": # 1-3 == 1:4 --> [1, 2, 3]
391 391 end += 1
392 392 startsess = rmatch.group("startsess") or "0"
393 393 endsess = rmatch.group("endsess") or startsess
394 394 startsess = int(startsess.replace("~","-"))
395 395 endsess = int(endsess.replace("~","-"))
396 396 assert endsess >= startsess
397 397
398 398 if endsess == startsess:
399 399 yield (startsess, start, end)
400 400 continue
401 401 # Multiple sessions in one range:
402 402 yield (startsess, start, None)
403 403 for sess in range(startsess+1, endsess):
404 404 yield (sess, 1, None)
405 405 yield (endsess, 1, end)
406 406
407 407 def _format_lineno(session, line):
408 408 """Helper function to format line numbers properly."""
409 409 if session == 0:
410 410 return str(line)
411 411 return "%s#%s" % (session, line)
412 412
413 413 @testdec.skip_doctest
414 414 def magic_history(self, parameter_s = ''):
415 415 """Print input history (_i<n> variables), with most recent last.
416 416
417 417 %history -> print at most 40 inputs (some may be multi-line)\\
418 418 %history n -> print at most n inputs\\
419 419 %history n1 n2 -> print inputs between n1 and n2 (n2 not included)\\
420 420
421 421 By default, input history is printed without line numbers so it can be
422 422 directly pasted into an editor.
423 423
424 424 With -n, each input's number <n> is shown, and is accessible as the
425 425 automatically generated variable _i<n> as well as In[<n>]. Multi-line
426 426 statements are printed starting at a new line for easy copy/paste.
427 427
428 428 Options:
429 429
430 430 -n: print line numbers for each input.
431 431 This feature is only available if numbered prompts are in use.
432 432
433 433 -o: also print outputs for each input.
434 434
435 435 -p: print classic '>>>' python prompts before each input. This is useful
436 436 for making documentation, and in conjunction with -o, for producing
437 437 doctest-ready output.
438 438
439 439 -r: (default) print the 'raw' history, i.e. the actual commands you typed.
440 440
441 441 -t: print the 'translated' history, as IPython understands it. IPython
442 442 filters your input and converts it all into valid Python source before
443 443 executing it (things like magics or aliases are turned into function
444 444 calls, for example). With this option, you'll see the native history
445 445 instead of the user-entered version: '%cd /' will be seen as
446 446 'get_ipython().magic("%cd /")' instead of '%cd /'.
447 447
448 448 -g: treat the arg as a pattern to grep for in (full) history.
449 449 This includes the saved history (almost all commands ever written).
450 450 Use '%hist -g' to show full saved history (may be very long).
451 451
452 452 -l: get the last n lines from all sessions. Specify n as a single arg, or
453 453 the default is the last 10 lines.
454 454
455 455 -f FILENAME: instead of printing the output to the screen, redirect it to
456 456 the given file. The file is always overwritten, though IPython asks for
457 457 confirmation first if it already exists.
458 458
459 459 Examples
460 460 --------
461 461 ::
462 462
463 463 In [6]: %hist -n 4 6
464 464 4:a = 12
465 465 5:print a**2
466 466
467 467 """
468 468
469 469 if not self.shell.displayhook.do_full_cache:
470 470 print('This feature is only available if numbered prompts are in use.')
471 471 return
472 472 opts,args = self.parse_options(parameter_s,'noprtglf:',mode='string')
473 473
474 474 # For brevity
475 475 history_manager = self.shell.history_manager
476 476
477 477 def _format_lineno(session, line):
478 478 """Helper function to format line numbers properly."""
479 479 if session in (0, history_manager.session_number):
480 480 return str(line)
481 481 return "%s/%s" % (session, line)
482 482
483 483 # Check if output to specific file was requested.
484 484 try:
485 485 outfname = opts['f']
486 486 except KeyError:
487 487 outfile = IPython.utils.io.Term.cout # default
488 488 # We don't want to close stdout at the end!
489 489 close_at_end = False
490 490 else:
491 491 if os.path.exists(outfname):
492 492 if not ask_yes_no("File %r exists. Overwrite?" % outfname):
493 493 print('Aborting.')
494 494 return
495 495
496 496 outfile = open(outfname,'w')
497 497 close_at_end = True
498 498
499 499 print_nums = 'n' in opts
500 500 get_output = 'o' in opts
501 501 pyprompts = 'p' in opts
502 502 # Raw history is the default
503 503 raw = not('t' in opts)
504 504
505 505 default_length = 40
506 506 pattern = None
507 507
508 508 if 'g' in opts: # Glob search
509 509 pattern = "*" + args + "*" if args else "*"
510 510 hist = history_manager.get_hist_search(pattern, raw=raw,
511 511 output=get_output)
512 512 elif 'l' in opts: # Get 'tail'
513 513 try:
514 514 n = int(args)
515 515 except ValueError, IndexError:
516 516 n = 10
517 517 hist = history_manager.get_hist_tail(n, raw=raw, output=get_output)
518 518 else:
519 519 if args: # Get history by ranges
520 520 hist = history_manager.get_hist_from_rangestr(args, raw, get_output)
521 521 else: # Just get history for the current session
522 522 hist = history_manager.get_history(raw=raw, output=get_output)
523 523
524 524 # We could be displaying the entire history, so let's not try to pull it
525 525 # into a list in memory. Anything that needs more space will just misalign.
526 526 width = 4
527 527
528 528 for session, lineno, inline in hist:
529 529 # Print user history with tabs expanded to 4 spaces. The GUI clients
530 530 # use hard tabs for easier usability in auto-indented code, but we want
531 531 # to produce PEP-8 compliant history for safe pasting into an editor.
532 532 if get_output:
533 533 inline, output = inline
534 534 inline = inline.expandtabs(4).rstrip()
535 535
536 536 multiline = "\n" in inline
537 537 line_sep = '\n' if multiline else ' '
538 538 if print_nums:
539 539 print('%s:%s' % (_format_lineno(session, lineno).rjust(width),
540 540 line_sep), file=outfile, end='')
541 541 if pyprompts:
542 542 print(">>> ", end="", file=outfile)
543 543 if multiline:
544 544 inline = "\n... ".join(inline.splitlines()) + "\n..."
545 545 print(inline, file=outfile)
546 546 if get_output and output:
547 547 print("\n".join(output), file=outfile)
548 548
549 549 if close_at_end:
550 550 outfile.close()
551 551
552 552
553 553 def magic_rep(self, arg):
554 554 r""" Repeat a command, or get command to input line for editing
555 555
556 556 - %rep (no arguments):
557 557
558 558 Place a string version of last computation result (stored in the special '_'
559 559 variable) to the next input prompt. Allows you to create elaborate command
560 560 lines without using copy-paste::
561 561
562 562 In[1]: l = ["hei", "vaan"]
563 563 In[2]: "".join(l)
564 564 Out[2]: heivaan
565 565 In[3]: %rep
566 566 In[4]: heivaan_ <== cursor blinking
567 567
568 568 %rep 45
569 569
570 570 Place history line 45 on the next input prompt. Use %hist to find
571 571 out the number.
572 572
573 573 %rep 1-4 6-7 3
574 574
575 575 Combine the specified lines into one cell, and place it on the next
576 576 input prompt. History slice syntax is the same as in %macro and %save.
577 577
578 578 %rep foo+bar
579 579
580 580 If foo+bar can be evaluated in the user namespace, the result is
581 581 placed at the next input prompt. Otherwise, the history is searched
582 582 for lines which contain that substring, and the most recent one is
583 583 placed at the next input prompt.
584 584 """
585 585 if not arg: # Last output
586 586 self.set_next_input(str(self.shell.user_ns["_"]))
587 587 return
588 588 # Get history range
589 589 histlines = self.history_manager.get_hist_from_rangestr(arg)
590 590 cmd = "\n".join(x[2] for x in histlines)
591 591 if cmd:
592 592 self.set_next_input(cmd.rstrip())
593 593 return
594 594
595 595 try: # Variable in user namespace
596 596 cmd = str(eval(arg, self.shell.user_ns))
597 597 except Exception: # Search for term in history
598 598 histlines = self.history_manager.get_hist_search("*"+arg+"*")
599 599 for h in reversed([x[2] for x in histlines]):
600 600 if 'rep' in h:
601 601 continue
602 602 self.set_next_input(h.rstrip())
603 603 return
604 604 else:
605 605 self.set_next_input(cmd.rstrip())
606 606 print("Couldn't evaluate or find in history:", arg)
607 607
608 608 def magic_rerun(self, parameter_s=''):
609 609 """Re-run previous input
610 610
611 611 By default, you can specify ranges of input history to be repeated
612 612 (as with %hist). With no arguments, it will repeat the last line.
613 613
614 614 Options:
615 615
616 616 -l <n> : Repeat the last n lines of input, not including the
617 617 current command.
618 618
619 619 -g foo : Repeat the most recent line which contains foo
620 620 """
621 621 opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
622 622 if "l" in opts: # Last n lines
623 623 n = int(opts['l']) + 1
624 624 hist = self.history_manager.get_hist_tail(n, raw=False)
625 625 elif "g" in opts: # Search
626 626 p = "*"+opts['g']+"*"
627 627 hist = self.history_manager.get_hist_search(p, raw=False)
628 628 hist = list(hist)[-2:]
629 629 elif args: # Specify history ranges
630 630 hist = self.history_manager.get_hist_from_rangestr(args)
631 631 else: # Last line
632 632 hist = self.history_manager.get_hist_tail(2, raw=False)
633 633 hist = [x[2] for x in hist]
634 634 if hist and parameter_s in hist[-1]:
635 635 hist = hist[:-1]
636 636 if not hist:
637 637 print("No lines in history match specification")
638 638 return
639 639 histlines = "\n".join(hist)
640 640 print("=== Executing: ===")
641 641 print(histlines)
642 642 print("=== Output: ===")
643 643 self.run_source("\n".join(hist), symbol="exec")
644 644
645 645
646 646 def init_ipython(ip):
647 647 ip.define_magic("rep", magic_rep)
648 648 ip.define_magic("recall", magic_rep)
649 649 ip.define_magic("rerun", magic_rerun)
650 650 ip.define_magic("r", magic_rerun)
651 651 ip.define_magic("hist",magic_history) # Alternative name
652 652 ip.define_magic("history",magic_history)
653 653
654 654 # XXX - ipy_completers are in quarantine, need to be updated to new apis
655 655 #import ipy_completers
656 656 #ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
General Comments 0
You need to be logged in to leave comments. Login now