From 78e030815d794bd2bcab7490d8d0de6a6d77791c 2011-03-21 20:23:08 From: Thomas Kluyver Date: 2011-03-21 20:23:08 Subject: [PATCH] Further refinements to history interfaces. --- diff --git a/IPython/core/history.py b/IPython/core/history.py index 784bb8e..90b2b67 100644 --- a/IPython/core/history.py +++ b/IPython/core/history.py @@ -195,17 +195,26 @@ class HistoryManager(Configurable): return cur - def get_hist_tail(self, n=10, raw=True, output=False): - """Get the last n lines from the history database.""" + def get_hist_tail(self, n=10, raw=True, output=False, include_latest=False): + """Get the last n lines from the history database. + + If include_latest is False (default), n+1 lines are fetched, and + the latest one is discarded. This is intended to be used where + the function is called by a user command, which it should not + return.""" self.writeout_cache() + if not include_latest: + n += 1 cur = self._get_hist_sql("ORDER BY session DESC, line DESC LIMIT ?", (n,), raw=raw, output=output) + if not include_latest: + return reversed(list(cur)[1:]) return reversed(list(cur)) def get_hist_search(self, pattern="*", raw=True, search_raw=True, output=False): - """Search the database using unix glob-style matching (wildcards * and - ?, escape using \). + """Search the database using unix glob-style matching (wildcards + * and ?). Returns ------- @@ -620,19 +629,20 @@ def magic_rerun(self, parameter_s=''): """ opts, args = self.parse_options(parameter_s, 'l:g:', mode='string') if "l" in opts: # Last n lines - n = int(opts['l']) + 1 + n = int(opts['l']) hist = self.history_manager.get_hist_tail(n, raw=False) elif "g" in opts: # Search p = "*"+opts['g']+"*" hist = self.history_manager.get_hist_search(p, raw=False) - hist = list(hist)[-2:] + hist = list(hist) + if 'magic("rerun' in hist[-1][2]: + hist = hist[:-1] # We can ignore the current line + hist = hist[-1:] # Just get the last match elif args: # Specify history ranges hist = self.history_manager.get_hist_from_rangestr(args) else: # Last line - hist = self.history_manager.get_hist_tail(2, raw=False) + hist = self.history_manager.get_hist_tail(1, raw=False) hist = [x[2] for x in hist] - if hist and parameter_s in hist[-1]: - hist = hist[:-1] if not hist: print("No lines in history match specification") return @@ -647,7 +657,6 @@ def init_ipython(ip): ip.define_magic("rep", magic_rep) ip.define_magic("recall", magic_rep) ip.define_magic("rerun", magic_rerun) - ip.define_magic("r", magic_rerun) ip.define_magic("hist",magic_history) # Alternative name ip.define_magic("history",magic_history) diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index dce5c39..84d7707 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -1550,7 +1550,8 @@ class InteractiveShell(Configurable, Magic): readline.set_history_length(self.history_length) # Load the last 1000 lines from history - for _, _, cell in self.history_manager.get_hist_tail(1000): + for _, _, cell in self.history_manager.get_hist_tail(1000, + include_latest=True): if cell.strip(): # Ignore blank lines for line in cell.splitlines(): readline.add_history(line) diff --git a/IPython/core/tests/test_history.py b/IPython/core/tests/test_history.py index 456b505..c3cf716 100644 --- a/IPython/core/tests/test_history.py +++ b/IPython/core/tests/test_history.py @@ -59,13 +59,19 @@ def test_history(): nt.assert_equal(list(gothist), zip([1,1,1],[1,2,3], hist)) # Check get_hist_tail - gothist = ip.history_manager.get_hist_tail(4, output=True) + gothist = ip.history_manager.get_hist_tail(4, output=True, + include_latest=True) expected = [(1, 3, (hist[-1], ["spam"])), (2, 1, (newcmds[0], None)), (2, 2, (newcmds[1], None)), (2, 3, (newcmds[2], None)),] nt.assert_equal(list(gothist), expected) + gothist = ip.history_manager.get_hist_tail(2) + expected = [(2, 1, newcmds[0]), + (2, 2, newcmds[1])] + nt.assert_equal(list(gothist), expected) + # Check get_hist_search gothist = ip.history_manager.get_hist_search("*test*") nt.assert_equal(list(gothist), [(1,2,hist[1])] ) @@ -92,3 +98,12 @@ def test_extract_hist_ranges(): (-7, 1, 6)] actual = list(extract_hist_ranges(instr)) nt.assert_equal(actual, expected) + +def test_magic_rerun(): + """Simple test for %rerun (no args -> rerun last line)""" + ip = get_ipython() + ip.run_cell("a = 10") + ip.run_cell("a += 1") + nt.assert_equal(ip.user_ns["a"], 11) + ip.run_cell("%rerun") + nt.assert_equal(ip.user_ns["a"], 12)