##// END OF EJS Templates
Create new core.magics package and start populating with history.
Fernando Perez -
Show More
@@ -0,0 +1,14 b''
1 """Implementation of all the magic functions built into IPython.
2 """
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012, IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14 from history import (HistoryMagics)
@@ -0,0 +1,294 b''
1 """Implementation of magic functions related to History.
2 """
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012, IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
15
16 # Stdlib
17 import os
18 from io import open as io_open
19
20 # Our own packages
21 from IPython.core.error import StdinNotImplementedError
22 from IPython.core.magic import Magics, register_magics, line_magic
23 from IPython.testing.skipdoctest import skip_doctest
24 from IPython.utils import io
25
26 #-----------------------------------------------------------------------------
27 # Magics class implementation
28 #-----------------------------------------------------------------------------
29
30 @register_magics
31 class HistoryMagics(Magics):
32
33 @skip_doctest
34 @line_magic
35 def history(self, parameter_s = ''):
36 """Print input history (_i<n> variables), with most recent last.
37
38 %history [-o -p -t -n] [-f filename] [range | -g pattern | -l number]
39
40 By default, input history is printed without line numbers so it can be
41 directly pasted into an editor. Use -n to show them.
42
43 By default, all input history from the current session is displayed.
44 Ranges of history can be indicated using the syntax:
45 4 : Line 4, current session
46 4-6 : Lines 4-6, current session
47 243/1-5: Lines 1-5, session 243
48 ~2/7 : Line 7, session 2 before current
49 ~8/1-~6/5 : From the first line of 8 sessions ago, to the fifth line
50 of 6 sessions ago.
51 Multiple ranges can be entered, separated by spaces
52
53 The same syntax is used by %macro, %save, %edit, %rerun
54
55 Options:
56
57 -n: print line numbers for each input.
58 This feature is only available if numbered prompts are in use.
59
60 -o: also print outputs for each input.
61
62 -p: print classic '>>>' python prompts before each input. This is
63 useful for making documentation, and in conjunction with -o, for
64 producing doctest-ready output.
65
66 -r: (default) print the 'raw' history, i.e. the actual commands you
67 typed.
68
69 -t: print the 'translated' history, as IPython understands it.
70 IPython filters your input and converts it all into valid Python
71 source before executing it (things like magics or aliases are turned
72 into function calls, for example). With this option, you'll see the
73 native history instead of the user-entered version: '%cd /' will be
74 seen as 'get_ipython().magic("%cd /")' instead of '%cd /'.
75
76 -g: treat the arg as a pattern to grep for in (full) history.
77 This includes the saved history (almost all commands ever written).
78 Use '%hist -g' to show full saved history (may be very long).
79
80 -l: get the last n lines from all sessions. Specify n as a single
81 arg, or the default is the last 10 lines.
82
83 -f FILENAME: instead of printing the output to the screen, redirect
84 it to the given file. The file is always overwritten, though *when
85 it can*, IPython asks for confirmation first. In particular, running
86 the command 'history -f FILENAME' from the IPython Notebook
87 interface will replace FILENAME even if it already exists *without*
88 confirmation.
89
90 Examples
91 --------
92 ::
93
94 In [6]: %hist -n 4-6
95 4:a = 12
96 5:print a**2
97 6:%hist -n 4-6
98
99 """
100
101 if not self.shell.displayhook.do_full_cache:
102 print('This feature is only available if numbered prompts '
103 'are in use.')
104 return
105 opts,args = self.parse_options(parameter_s,'noprtglf:',mode='string')
106
107 # For brevity
108 history_manager = self.shell.history_manager
109
110 def _format_lineno(session, line):
111 """Helper function to format line numbers properly."""
112 if session in (0, history_manager.session_number):
113 return str(line)
114 return "%s/%s" % (session, line)
115
116 # Check if output to specific file was requested.
117 try:
118 outfname = opts['f']
119 except KeyError:
120 outfile = io.stdout # default
121 # We don't want to close stdout at the end!
122 close_at_end = False
123 else:
124 if os.path.exists(outfname):
125 try:
126 ans = io.ask_yes_no("File %r exists. Overwrite?" % outfname)
127 except StdinNotImplementedError:
128 ans = True
129 if not ans:
130 print('Aborting.')
131 return
132 print("Overwriting file.")
133 outfile = io_open(outfname, 'w', encoding='utf-8')
134 close_at_end = True
135
136 print_nums = 'n' in opts
137 get_output = 'o' in opts
138 pyprompts = 'p' in opts
139 # Raw history is the default
140 raw = not('t' in opts)
141
142 pattern = None
143
144 if 'g' in opts: # Glob search
145 pattern = "*" + args + "*" if args else "*"
146 hist = history_manager.search(pattern, raw=raw, output=get_output)
147 print_nums = True
148 elif 'l' in opts: # Get 'tail'
149 try:
150 n = int(args)
151 except (ValueError, IndexError):
152 n = 10
153 hist = history_manager.get_tail(n, raw=raw, output=get_output)
154 else:
155 if args: # Get history by ranges
156 hist = history_manager.get_range_by_str(args, raw, get_output)
157 else: # Just get history for the current session
158 hist = history_manager.get_range(raw=raw, output=get_output)
159
160 # We could be displaying the entire history, so let's not try to pull
161 # it into a list in memory. Anything that needs more space will just
162 # misalign.
163 width = 4
164
165 for session, lineno, inline in hist:
166 # Print user history with tabs expanded to 4 spaces. The GUI
167 # clients use hard tabs for easier usability in auto-indented code,
168 # but we want to produce PEP-8 compliant history for safe pasting
169 # into an editor.
170 if get_output:
171 inline, output = inline
172 inline = inline.expandtabs(4).rstrip()
173
174 multiline = "\n" in inline
175 line_sep = '\n' if multiline else ' '
176 if print_nums:
177 print(u'%s:%s' % (_format_lineno(session, lineno).rjust(width),
178 line_sep), file=outfile, end=u'')
179 if pyprompts:
180 print(u">>> ", end=u"", file=outfile)
181 if multiline:
182 inline = "\n... ".join(inline.splitlines()) + "\n..."
183 print(inline, file=outfile)
184 if get_output and output:
185 print(output, file=outfile)
186
187 if close_at_end:
188 outfile.close()
189
190 # For a long time we've had %hist as well as %history
191 @line_magic
192 def hist(self, arg):
193 return self.history(arg)
194
195 hist.__doc__ = history.__doc__
196
197 @line_magic
198 def rep(self, arg):
199 r"""Repeat a command, or get command to input line for editing.
200
201 %recall and %rep are equivalent.
202
203 - %recall (no arguments):
204
205 Place a string version of last computation result (stored in the
206 special '_' variable) to the next input prompt. Allows you to create
207 elaborate command lines without using copy-paste::
208
209 In[1]: l = ["hei", "vaan"]
210 In[2]: "".join(l)
211 Out[2]: heivaan
212 In[3]: %rep
213 In[4]: heivaan_ <== cursor blinking
214
215 %recall 45
216
217 Place history line 45 on the next input prompt. Use %hist to find
218 out the number.
219
220 %recall 1-4
221
222 Combine the specified lines into one cell, and place it on the next
223 input prompt. See %history for the slice syntax.
224
225 %recall foo+bar
226
227 If foo+bar can be evaluated in the user namespace, the result is
228 placed at the next input prompt. Otherwise, the history is searched
229 for lines which contain that substring, and the most recent one is
230 placed at the next input prompt.
231 """
232 if not arg: # Last output
233 self.shell.set_next_input(str(self.shell.user_ns["_"]))
234 return
235 # Get history range
236 histlines = self.shell.history_manager.get_range_by_str(arg)
237 cmd = "\n".join(x[2] for x in histlines)
238 if cmd:
239 self.shell.set_next_input(cmd.rstrip())
240 return
241
242 try: # Variable in user namespace
243 cmd = str(eval(arg, self.shell.user_ns))
244 except Exception: # Search for term in history
245 histlines = self.shell.history_manager.search("*"+arg+"*")
246 for h in reversed([x[2] for x in histlines]):
247 if 'rep' in h:
248 continue
249 self.shell.set_next_input(h.rstrip())
250 return
251 else:
252 self.shell.set_next_input(cmd.rstrip())
253 print("Couldn't evaluate or find in history:", arg)
254
255 @line_magic
256 def rerun(self, parameter_s=''):
257 """Re-run previous input
258
259 By default, you can specify ranges of input history to be repeated
260 (as with %history). With no arguments, it will repeat the last line.
261
262 Options:
263
264 -l <n> : Repeat the last n lines of input, not including the
265 current command.
266
267 -g foo : Repeat the most recent line which contains foo
268 """
269 opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
270 if "l" in opts: # Last n lines
271 n = int(opts['l'])
272 hist = self.shell.history_manager.get_tail(n)
273 elif "g" in opts: # Search
274 p = "*"+opts['g']+"*"
275 hist = list(self.shell.history_manager.search(p))
276 for l in reversed(hist):
277 if "rerun" not in l[2]:
278 hist = [l] # The last match which isn't a %rerun
279 break
280 else:
281 hist = [] # No matches except %rerun
282 elif args: # Specify history ranges
283 hist = self.shell.history_manager.get_range_by_str(args)
284 else: # Last line
285 hist = self.shell.history_manager.get_tail(1)
286 hist = [x[2] for x in hist]
287 if not hist:
288 print("No lines in history match specification")
289 return
290 histlines = "\n".join(hist)
291 print("=== Executing: ===")
292 print(histlines)
293 print("=== Output: ===")
294 self.shell.run_cell("\n".join(hist), store_history=False)
@@ -15,7 +15,6 b' from __future__ import print_function'
15 # Stdlib imports
15 # Stdlib imports
16 import atexit
16 import atexit
17 import datetime
17 import datetime
18 from io import open as io_open
19 import os
18 import os
20 import re
19 import re
21 try:
20 try:
@@ -25,12 +24,8 b' except ImportError:'
25 import threading
24 import threading
26
25
27 # Our own packages
26 # Our own packages
28 from IPython.core.error import StdinNotImplementedError
29 from IPython.core.magic import Magics, register_magics, line_magic
30 from IPython.config.configurable import Configurable
27 from IPython.config.configurable import Configurable
31 from IPython.external.decorator import decorator
28 from IPython.external.decorator import decorator
32 from IPython.testing.skipdoctest import skip_doctest
33 from IPython.utils import io
34 from IPython.utils.path import locate_profile
29 from IPython.utils.path import locate_profile
35 from IPython.utils.traitlets import Bool, Dict, Instance, Integer, List, Unicode
30 from IPython.utils.traitlets import Bool, Dict, Instance, Integer, List, Unicode
36 from IPython.utils.warn import warn
31 from IPython.utils.warn import warn
@@ -724,275 +719,3 b' def _format_lineno(session, line):'
724 return "%s#%s" % (session, line)
719 return "%s#%s" % (session, line)
725
720
726
721
727 @register_magics
728 class HistoryMagics(Magics):
729
730 @skip_doctest
731 @line_magic
732 def history(self, parameter_s = ''):
733 """Print input history (_i<n> variables), with most recent last.
734
735 %history [-o -p -t -n] [-f filename] [range | -g pattern | -l number]
736
737 By default, input history is printed without line numbers so it can be
738 directly pasted into an editor. Use -n to show them.
739
740 By default, all input history from the current session is displayed.
741 Ranges of history can be indicated using the syntax:
742 4 : Line 4, current session
743 4-6 : Lines 4-6, current session
744 243/1-5: Lines 1-5, session 243
745 ~2/7 : Line 7, session 2 before current
746 ~8/1-~6/5 : From the first line of 8 sessions ago, to the fifth line
747 of 6 sessions ago.
748 Multiple ranges can be entered, separated by spaces
749
750 The same syntax is used by %macro, %save, %edit, %rerun
751
752 Options:
753
754 -n: print line numbers for each input.
755 This feature is only available if numbered prompts are in use.
756
757 -o: also print outputs for each input.
758
759 -p: print classic '>>>' python prompts before each input. This is
760 useful for making documentation, and in conjunction with -o, for
761 producing doctest-ready output.
762
763 -r: (default) print the 'raw' history, i.e. the actual commands you
764 typed.
765
766 -t: print the 'translated' history, as IPython understands it.
767 IPython filters your input and converts it all into valid Python
768 source before executing it (things like magics or aliases are turned
769 into function calls, for example). With this option, you'll see the
770 native history instead of the user-entered version: '%cd /' will be
771 seen as 'get_ipython().magic("%cd /")' instead of '%cd /'.
772
773 -g: treat the arg as a pattern to grep for in (full) history.
774 This includes the saved history (almost all commands ever written).
775 Use '%hist -g' to show full saved history (may be very long).
776
777 -l: get the last n lines from all sessions. Specify n as a single
778 arg, or the default is the last 10 lines.
779
780 -f FILENAME: instead of printing the output to the screen, redirect
781 it to the given file. The file is always overwritten, though *when
782 it can*, IPython asks for confirmation first. In particular, running
783 the command 'history -f FILENAME' from the IPython Notebook
784 interface will replace FILENAME even if it already exists *without*
785 confirmation.
786
787 Examples
788 --------
789 ::
790
791 In [6]: %hist -n 4-6
792 4:a = 12
793 5:print a**2
794 6:%hist -n 4-6
795
796 """
797
798 if not self.shell.displayhook.do_full_cache:
799 print('This feature is only available if numbered prompts '
800 'are in use.')
801 return
802 opts,args = self.parse_options(parameter_s,'noprtglf:',mode='string')
803
804 # For brevity
805 history_manager = self.shell.history_manager
806
807 def _format_lineno(session, line):
808 """Helper function to format line numbers properly."""
809 if session in (0, history_manager.session_number):
810 return str(line)
811 return "%s/%s" % (session, line)
812
813 # Check if output to specific file was requested.
814 try:
815 outfname = opts['f']
816 except KeyError:
817 outfile = io.stdout # default
818 # We don't want to close stdout at the end!
819 close_at_end = False
820 else:
821 if os.path.exists(outfname):
822 try:
823 ans = io.ask_yes_no("File %r exists. Overwrite?" % outfname)
824 except StdinNotImplementedError:
825 ans = True
826 if not ans:
827 print('Aborting.')
828 return
829 print("Overwriting file.")
830 outfile = io_open(outfname, 'w', encoding='utf-8')
831 close_at_end = True
832
833 print_nums = 'n' in opts
834 get_output = 'o' in opts
835 pyprompts = 'p' in opts
836 # Raw history is the default
837 raw = not('t' in opts)
838
839 pattern = None
840
841 if 'g' in opts: # Glob search
842 pattern = "*" + args + "*" if args else "*"
843 hist = history_manager.search(pattern, raw=raw, output=get_output)
844 print_nums = True
845 elif 'l' in opts: # Get 'tail'
846 try:
847 n = int(args)
848 except (ValueError, IndexError):
849 n = 10
850 hist = history_manager.get_tail(n, raw=raw, output=get_output)
851 else:
852 if args: # Get history by ranges
853 hist = history_manager.get_range_by_str(args, raw, get_output)
854 else: # Just get history for the current session
855 hist = history_manager.get_range(raw=raw, output=get_output)
856
857 # We could be displaying the entire history, so let's not try to pull
858 # it into a list in memory. Anything that needs more space will just
859 # misalign.
860 width = 4
861
862 for session, lineno, inline in hist:
863 # Print user history with tabs expanded to 4 spaces. The GUI
864 # clients use hard tabs for easier usability in auto-indented code,
865 # but we want to produce PEP-8 compliant history for safe pasting
866 # into an editor.
867 if get_output:
868 inline, output = inline
869 inline = inline.expandtabs(4).rstrip()
870
871 multiline = "\n" in inline
872 line_sep = '\n' if multiline else ' '
873 if print_nums:
874 print(u'%s:%s' % (_format_lineno(session, lineno).rjust(width),
875 line_sep), file=outfile, end=u'')
876 if pyprompts:
877 print(u">>> ", end=u"", file=outfile)
878 if multiline:
879 inline = "\n... ".join(inline.splitlines()) + "\n..."
880 print(inline, file=outfile)
881 if get_output and output:
882 print(output, file=outfile)
883
884 if close_at_end:
885 outfile.close()
886
887 # For a long time we've had %hist as well as %history
888 @line_magic
889 def hist(self, arg):
890 return self.history(arg)
891
892 hist.__doc__ = history.__doc__
893
894 @line_magic
895 def rep(self, arg):
896 r"""Repeat a command, or get command to input line for editing.
897
898 %recall and %rep are equivalent.
899
900 - %recall (no arguments):
901
902 Place a string version of last computation result (stored in the
903 special '_' variable) to the next input prompt. Allows you to create
904 elaborate command lines without using copy-paste::
905
906 In[1]: l = ["hei", "vaan"]
907 In[2]: "".join(l)
908 Out[2]: heivaan
909 In[3]: %rep
910 In[4]: heivaan_ <== cursor blinking
911
912 %recall 45
913
914 Place history line 45 on the next input prompt. Use %hist to find
915 out the number.
916
917 %recall 1-4
918
919 Combine the specified lines into one cell, and place it on the next
920 input prompt. See %history for the slice syntax.
921
922 %recall foo+bar
923
924 If foo+bar can be evaluated in the user namespace, the result is
925 placed at the next input prompt. Otherwise, the history is searched
926 for lines which contain that substring, and the most recent one is
927 placed at the next input prompt.
928 """
929 if not arg: # Last output
930 self.shell.set_next_input(str(self.shell.user_ns["_"]))
931 return
932 # Get history range
933 histlines = self.shell.history_manager.get_range_by_str(arg)
934 cmd = "\n".join(x[2] for x in histlines)
935 if cmd:
936 self.shell.set_next_input(cmd.rstrip())
937 return
938
939 try: # Variable in user namespace
940 cmd = str(eval(arg, self.shell.user_ns))
941 except Exception: # Search for term in history
942 histlines = self.shell.history_manager.search("*"+arg+"*")
943 for h in reversed([x[2] for x in histlines]):
944 if 'rep' in h:
945 continue
946 self.shell.set_next_input(h.rstrip())
947 return
948 else:
949 self.shell.set_next_input(cmd.rstrip())
950 print("Couldn't evaluate or find in history:", arg)
951
952 @line_magic
953 def rerun(self, parameter_s=''):
954 """Re-run previous input
955
956 By default, you can specify ranges of input history to be repeated
957 (as with %history). With no arguments, it will repeat the last line.
958
959 Options:
960
961 -l <n> : Repeat the last n lines of input, not including the
962 current command.
963
964 -g foo : Repeat the most recent line which contains foo
965 """
966 opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
967 if "l" in opts: # Last n lines
968 n = int(opts['l'])
969 hist = self.shell.history_manager.get_tail(n)
970 elif "g" in opts: # Search
971 p = "*"+opts['g']+"*"
972 hist = list(self.shell.history_manager.search(p))
973 for l in reversed(hist):
974 if "rerun" not in l[2]:
975 hist = [l] # The last match which isn't a %rerun
976 break
977 else:
978 hist = [] # No matches except %rerun
979 elif args: # Specify history ranges
980 hist = self.shell.history_manager.get_range_by_str(args)
981 else: # Last line
982 hist = self.shell.history_manager.get_tail(1)
983 hist = [x[2] for x in hist]
984 if not hist:
985 print("No lines in history match specification")
986 return
987 histlines = "\n".join(hist)
988 print("=== Executing: ===")
989 print(histlines)
990 print("=== Output: ===")
991 self.shell.run_cell("\n".join(hist), store_history=False)
992
993
994 def init_ipython(ip):
995 ip.register_magics(HistoryMagics)
996 # XXX - ipy_completers are in quarantine, need to be updated to new apis
997 #import ipy_completers
998 #ipy_completers.quick_completer('%hist' ,'-g -t -r -n')
@@ -1994,6 +1994,7 b' class InteractiveShell(SingletonConfigurable):'
1994
1994
1995 def init_magics(self):
1995 def init_magics(self):
1996 from IPython.core import magic_functions as mf
1996 from IPython.core import magic_functions as mf
1997 from IPython.core import magics as m
1997 self.magics_manager = magic.MagicsManager(shell=self,
1998 self.magics_manager = magic.MagicsManager(shell=self,
1998 confg=self.config,
1999 confg=self.config,
1999 user_magics=mf.UserMagics(self))
2000 user_magics=mf.UserMagics(self))
@@ -2007,15 +2008,12 b' class InteractiveShell(SingletonConfigurable):'
2007 self.register_magics(mf.BasicMagics, mf.CodeMagics, mf.ConfigMagics,
2008 self.register_magics(mf.BasicMagics, mf.CodeMagics, mf.ConfigMagics,
2008 mf.ExecutionMagics, mf.NamespaceMagics, mf.AutoMagics,
2009 mf.ExecutionMagics, mf.NamespaceMagics, mf.AutoMagics,
2009 mf.OSMagics, mf.LoggingMagics, mf.ExtensionsMagics,
2010 mf.OSMagics, mf.LoggingMagics, mf.ExtensionsMagics,
2010 mf.PylabMagics, mf.DeprecatedMagics)
2011 mf.PylabMagics, m.HistoryMagics, mf.DeprecatedMagics)
2011
2012
2012 # FIXME: Move the color initialization to the DisplayHook, which
2013 # FIXME: Move the color initialization to the DisplayHook, which
2013 # should be split into a prompt manager and displayhook. We probably
2014 # should be split into a prompt manager and displayhook. We probably
2014 # even need a centralize colors management object.
2015 # even need a centralize colors management object.
2015 self.magic('colors %s' % self.colors)
2016 self.magic('colors %s' % self.colors)
2016 # History was moved to a separate module
2017 from IPython.core import history
2018 history.init_ipython(self)
2019
2017
2020 def line_magic(self, magic_name, line, next_input=None):
2018 def line_magic(self, magic_name, line, next_input=None):
2021 """Execute the given line magic.
2019 """Execute the given line magic.
General Comments 0
You need to be logged in to leave comments. Login now