diff --git a/IPython/core/history.py b/IPython/core/history.py index 558e517..e386cf2 100644 --- a/IPython/core/history.py +++ b/IPython/core/history.py @@ -307,7 +307,7 @@ class HistoryAccessor(Configurable): @catch_corrupt_db def search(self, pattern="*", raw=True, search_raw=True, - output=False, n=None): + output=False, n=None, unique=False): """Search the database using unix glob-style matching (wildcards * and ?). @@ -322,6 +322,8 @@ class HistoryAccessor(Configurable): n : None or int If an integer is given, it defines the limit of returned entries. + unique : bool + When it is true, return only unique entries. Returns ------- @@ -333,9 +335,13 @@ class HistoryAccessor(Configurable): self.writeout_cache() sqlform = "WHERE %s GLOB ?" % tosearch params = (pattern,) + if unique: + sqlform += ' GROUP BY {0}'.format(tosearch) if n is not None: sqlform += " ORDER BY session DESC, line DESC LIMIT ?" params += (n,) + elif unique: + sqlform += " ORDER BY session, line" cur = self._run_sql(sqlform, params, raw=raw, output=output) if n is not None: return reversed(list(cur)) diff --git a/IPython/core/magics/history.py b/IPython/core/magics/history.py index 3d9884d..63bb4fa 100644 --- a/IPython/core/magics/history.py +++ b/IPython/core/magics/history.py @@ -89,6 +89,11 @@ class HistoryMagics(Magics): get the last n lines from all sessions. Specify n as a single arg, or the default is the last 10 lines. """) + @argument( + '-u', dest='unique', action='store_true', + help=""" + when searching history using `-g`, show only unique history. + """) @argument('range', nargs='*') @skip_doctest @line_magic @@ -165,7 +170,7 @@ class HistoryMagics(Magics): else: pattern = "*" hist = history_manager.search(pattern, raw=raw, output=get_output, - n=limit) + n=limit, unique=args.unique) print_nums = True elif args.limit is not _unspecified: n = 10 if limit is None else limit diff --git a/IPython/core/tests/test_history.py b/IPython/core/tests/test_history.py index 5474da9..8797c8b 100644 --- a/IPython/core/tests/test_history.py +++ b/IPython/core/tests/test_history.py @@ -61,7 +61,10 @@ def test_history(): # New session ip.history_manager.reset() - newcmds = ["z=5","class X(object):\n pass", "k='p'"] + newcmds = [u"z=5", + u"class X(object):\n pass", + u"k='p'", + u"z=5"] for i, cmd in enumerate(newcmds, start=1): ip.history_manager.store_inputs(i, cmd) gothist = ip.history_manager.get_range(start=1, stop=4) @@ -70,35 +73,53 @@ def test_history(): gothist = ip.history_manager.get_range(-1, 1, 4) nt.assert_equal(list(gothist), zip([1,1,1],[1,2,3], hist)) + newhist = [(2, i, c) for (i, c) in enumerate(newcmds, 1)] + # Check get_hist_tail - gothist = ip.history_manager.get_tail(4, output=True, + gothist = ip.history_manager.get_tail(5, 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)),] + expected = [(1, 3, (hist[-1], "spam"))] \ + + [(s, n, (c, None)) for (s, n, c) in newhist] nt.assert_equal(list(gothist), expected) gothist = ip.history_manager.get_tail(2) - expected = [(2, 1, newcmds[0]), - (2, 2, newcmds[1])] + expected = newhist[-3:-1] nt.assert_equal(list(gothist), expected) # Check get_hist_search gothist = ip.history_manager.search("*test*") nt.assert_equal(list(gothist), [(1,2,hist[1])] ) + gothist = ip.history_manager.search("*=*") nt.assert_equal(list(gothist), [(1, 1, hist[0]), (1, 2, hist[1]), (1, 3, hist[2]), - (2, 1, newcmds[0]), - (2, 3, newcmds[2])]) - gothist = ip.history_manager.search("*=*", n=3) + newhist[0], + newhist[2], + newhist[3]]) + + gothist = ip.history_manager.search("*=*", n=4) + nt.assert_equal(list(gothist), + [(1, 3, hist[2]), + newhist[0], + newhist[2], + newhist[3]]) + + gothist = ip.history_manager.search("*=*", unique=True) + nt.assert_equal(list(gothist), + [(1, 1, hist[0]), + (1, 2, hist[1]), + (1, 3, hist[2]), + newhist[2], + newhist[3]]) + + gothist = ip.history_manager.search("*=*", unique=True, n=3) nt.assert_equal(list(gothist), [(1, 3, hist[2]), - (2, 1, newcmds[0]), - (2, 3, newcmds[2])]) + newhist[2], + newhist[3]]) + gothist = ip.history_manager.search("b*", output=True) nt.assert_equal(list(gothist), [(1,3,(hist[2],"spam"))] )