Show More
@@ -26,6 +26,7 b' import threading' | |||
|
26 | 26 | |
|
27 | 27 | # Our own packages |
|
28 | 28 | from IPython.core.error import StdinNotImplementedError |
|
29 | from IPython.core.magic import Magics, register_magics, line_magic | |
|
29 | 30 | from IPython.config.configurable import Configurable |
|
30 | 31 | from IPython.external.decorator import decorator |
|
31 | 32 | from IPython.testing.skipdoctest import skip_doctest |
@@ -74,13 +75,13 b' class HistoryAccessor(Configurable):' | |||
|
74 | 75 | hist_file = Unicode(config=True, |
|
75 | 76 | help="""Path to file to use for SQLite history database. |
|
76 | 77 | |
|
77 |
By default, IPython will put the history database in the IPython |
|
|
78 |
directory. If you would rather share one history among |
|
|
79 | you ca set this value in each, so that they are consistent. | |
|
78 | By default, IPython will put the history database in the IPython | |
|
79 | profile directory. If you would rather share one history among | |
|
80 | profiles, you ca set this value in each, so that they are consistent. | |
|
80 | 81 | |
|
81 |
Due to an issue with fcntl, SQLite is known to misbehave on some NFS |
|
|
82 |
If you see IPython hanging, try setting this to something on a |
|
|
83 | e.g:: | |
|
82 | Due to an issue with fcntl, SQLite is known to misbehave on some NFS | |
|
83 | mounts. If you see IPython hanging, try setting this to something on a | |
|
84 | local disk, e.g:: | |
|
84 | 85 | |
|
85 | 86 | ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite |
|
86 | 87 | |
@@ -153,7 +154,8 b' class HistoryAccessor(Configurable):' | |||
|
153 | 154 | def init_db(self): |
|
154 | 155 | """Connect to the database, and create tables if necessary.""" |
|
155 | 156 | # use detect_types so that timestamps return datetime objects |
|
156 |
self.db = sqlite3.connect(self.hist_file, |
|
|
157 | self.db = sqlite3.connect(self.hist_file, | |
|
158 | detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) | |
|
157 | 159 | self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer |
|
158 | 160 | primary key autoincrement, start timestamp, |
|
159 | 161 | end timestamp, num_cmds integer, remark text)""") |
@@ -216,7 +218,8 b' class HistoryAccessor(Configurable):' | |||
|
216 | 218 | Returns |
|
217 | 219 | ------- |
|
218 | 220 | |
|
219 |
(session_id [int], start [datetime], end [datetime], num_cmds [int], |
|
|
221 | (session_id [int], start [datetime], end [datetime], num_cmds [int], | |
|
222 | remark [unicode]) | |
|
220 | 223 | |
|
221 | 224 | Sessions that are running or did not exit cleanly will have `end=None` |
|
222 | 225 | and `num_cmds=None`. |
@@ -512,7 +515,8 b' class HistoryManager(HistoryAccessor):' | |||
|
512 | 515 | session += self.session_number |
|
513 | 516 | if session==self.session_number: # Current session |
|
514 | 517 | return self._get_range_session(start, stop, raw, output) |
|
515 |
return super(HistoryManager, self).get_range(session, start, stop, raw, |
|
|
518 | return super(HistoryManager, self).get_range(session, start, stop, raw, | |
|
519 | output) | |
|
516 | 520 | |
|
517 | 521 | ## ---------------------------- |
|
518 | 522 | ## Methods for storing history: |
@@ -611,7 +615,9 b' class HistoryManager(HistoryAccessor):' | |||
|
611 | 615 | print("ERROR! Session/line number was not unique in", |
|
612 | 616 | "database. History logging moved to new session", |
|
613 | 617 | self.session_number) |
|
614 | try: # Try writing to the new session. If this fails, don't recurse | |
|
618 | try: | |
|
619 | # Try writing to the new session. If this fails, don't | |
|
620 | # recurse | |
|
615 | 621 | self._writeout_input_cache(conn) |
|
616 | 622 | except sqlite3.IntegrityError: |
|
617 | 623 | pass |
@@ -718,264 +724,270 b' def _format_lineno(session, line):' | |||
|
718 | 724 | return "%s#%s" % (session, line) |
|
719 | 725 | |
|
720 | 726 | |
|
721 | @skip_doctest | |
|
722 | def magic_history(self, parameter_s = ''): | |
|
723 | """Print input history (_i<n> variables), with most recent last. | |
|
727 | @register_magics | |
|
728 | class HistoryMagics(Magics): | |
|
724 | 729 | |
|
725 | %history [-o -p -t -n] [-f filename] [range | -g pattern | -l number] | |
|
730 | @skip_doctest | |
|
731 | @line_magic | |
|
732 | def history(self, parameter_s = ''): | |
|
733 | """Print input history (_i<n> variables), with most recent last. | |
|
726 | 734 | |
|
727 | By default, input history is printed without line numbers so it can be | |
|
728 | directly pasted into an editor. Use -n to show them. | |
|
735 | %history [-o -p -t -n] [-f filename] [range | -g pattern | -l number] | |
|
729 | 736 | |
|
730 | By default, all input history from the current session is displayed. | |
|
731 | Ranges of history can be indicated using the syntax: | |
|
732 | 4 : Line 4, current session | |
|
733 | 4-6 : Lines 4-6, current session | |
|
734 | 243/1-5: Lines 1-5, session 243 | |
|
735 | ~2/7 : Line 7, session 2 before current | |
|
736 | ~8/1-~6/5 : From the first line of 8 sessions ago, to the fifth line | |
|
737 | of 6 sessions ago. | |
|
738 | Multiple ranges can be entered, separated by spaces | |
|
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 | 739 | |
|
740 | The same syntax is used by %macro, %save, %edit, %rerun | |
|
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 | |
|
741 | 749 | |
|
742 | Options: | |
|
750 | The same syntax is used by %macro, %save, %edit, %rerun | |
|
743 | 751 | |
|
744 | -n: print line numbers for each input. | |
|
745 | This feature is only available if numbered prompts are in use. | |
|
752 | Options: | |
|
746 | 753 | |
|
747 |
|
|
|
754 | -n: print line numbers for each input. | |
|
755 | This feature is only available if numbered prompts are in use. | |
|
748 | 756 | |
|
749 | -p: print classic '>>>' python prompts before each input. This is useful | |
|
750 | for making documentation, and in conjunction with -o, for producing | |
|
751 | doctest-ready output. | |
|
757 | -o: also print outputs for each input. | |
|
752 | 758 | |
|
753 | -r: (default) print the 'raw' history, i.e. the actual commands you typed. | |
|
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. | |
|
754 | 762 | |
|
755 | -t: print the 'translated' history, as IPython understands it. IPython | |
|
756 | filters your input and converts it all into valid Python source before | |
|
757 | executing it (things like magics or aliases are turned into function | |
|
758 | calls, for example). With this option, you'll see the native history | |
|
759 | instead of the user-entered version: '%cd /' will be seen as | |
|
760 | 'get_ipython().magic("%cd /")' instead of '%cd /'. | |
|
763 | -r: (default) print the 'raw' history, i.e. the actual commands you | |
|
764 | typed. | |
|
761 | 765 | |
|
762 | -g: treat the arg as a pattern to grep for in (full) history. | |
|
763 | This includes the saved history (almost all commands ever written). | |
|
764 | Use '%hist -g' to show full saved history (may be very long). | |
|
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 /'. | |
|
765 | 772 | |
|
766 | -l: get the last n lines from all sessions. Specify n as a single arg, or | |
|
767 | the default is the last 10 lines. | |
|
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). | |
|
768 | 776 | |
|
769 | -f FILENAME: instead of printing the output to the screen, redirect it to | |
|
770 | the given file. The file is always overwritten, though *when it can*, | |
|
771 | IPython asks for confirmation first. In particular, running the command | |
|
772 | "history -f FILENAME" from the IPython Notebook interface will replace | |
|
773 | FILENAME even if it already exists *without* confirmation. | |
|
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. | |
|
774 | 779 | |
|
775 | Examples | |
|
776 | -------- | |
|
777 | :: | |
|
778 | ||
|
779 | In [6]: %hist -n 4-6 | |
|
780 | 4:a = 12 | |
|
781 | 5:print a**2 | |
|
782 | 6:%hist -n 4-6 | |
|
783 | ||
|
784 | """ | |
|
785 | ||
|
786 | if not self.shell.displayhook.do_full_cache: | |
|
787 | print('This feature is only available if numbered prompts are in use.') | |
|
788 | return | |
|
789 | opts,args = self.parse_options(parameter_s,'noprtglf:',mode='string') | |
|
790 | ||
|
791 | # For brevity | |
|
792 | history_manager = self.shell.history_manager | |
|
793 | ||
|
794 | def _format_lineno(session, line): | |
|
795 | """Helper function to format line numbers properly.""" | |
|
796 | if session in (0, history_manager.session_number): | |
|
797 | return str(line) | |
|
798 | return "%s/%s" % (session, line) | |
|
799 | ||
|
800 | # Check if output to specific file was requested. | |
|
801 | try: | |
|
802 | outfname = opts['f'] | |
|
803 | except KeyError: | |
|
804 | outfile = io.stdout # default | |
|
805 | # We don't want to close stdout at the end! | |
|
806 | close_at_end = False | |
|
807 | else: | |
|
808 | if os.path.exists(outfname): | |
|
809 | try: | |
|
810 | ans = io.ask_yes_no("File %r exists. Overwrite?" % outfname) | |
|
811 | except StdinNotImplementedError: | |
|
812 | ans = True | |
|
813 | if not ans: | |
|
814 | print('Aborting.') | |
|
815 | return | |
|
816 | print("Overwriting file.") | |
|
817 | outfile = io_open(outfname, 'w', encoding='utf-8') | |
|
818 | close_at_end = True | |
|
819 | ||
|
820 | print_nums = 'n' in opts | |
|
821 | get_output = 'o' in opts | |
|
822 | pyprompts = 'p' in opts | |
|
823 | # Raw history is the default | |
|
824 | raw = not('t' in opts) | |
|
825 | ||
|
826 | default_length = 40 | |
|
827 | pattern = None | |
|
828 | ||
|
829 | if 'g' in opts: # Glob search | |
|
830 | pattern = "*" + args + "*" if args else "*" | |
|
831 | hist = history_manager.search(pattern, raw=raw, output=get_output) | |
|
832 | print_nums = True | |
|
833 | elif 'l' in opts: # Get 'tail' | |
|
834 | try: | |
|
835 | n = int(args) | |
|
836 | except ValueError, IndexError: | |
|
837 | n = 10 | |
|
838 | hist = history_manager.get_tail(n, raw=raw, output=get_output) | |
|
839 | else: | |
|
840 | if args: # Get history by ranges | |
|
841 | hist = history_manager.get_range_by_str(args, raw, get_output) | |
|
842 | else: # Just get history for the current session | |
|
843 | hist = history_manager.get_range(raw=raw, output=get_output) | |
|
844 | ||
|
845 | # We could be displaying the entire history, so let's not try to pull it | |
|
846 | # into a list in memory. Anything that needs more space will just misalign. | |
|
847 | width = 4 | |
|
848 | ||
|
849 | for session, lineno, inline in hist: | |
|
850 | # Print user history with tabs expanded to 4 spaces. The GUI clients | |
|
851 | # use hard tabs for easier usability in auto-indented code, but we want | |
|
852 | # to produce PEP-8 compliant history for safe pasting into an editor. | |
|
853 | if get_output: | |
|
854 | inline, output = inline | |
|
855 | inline = inline.expandtabs(4).rstrip() | |
|
856 | ||
|
857 | multiline = "\n" in inline | |
|
858 | line_sep = '\n' if multiline else ' ' | |
|
859 | if print_nums: | |
|
860 | print(u'%s:%s' % (_format_lineno(session, lineno).rjust(width), | |
|
861 | line_sep), file=outfile, end=u'') | |
|
862 | if pyprompts: | |
|
863 | print(u">>> ", end=u"", file=outfile) | |
|
864 | if multiline: | |
|
865 | inline = "\n... ".join(inline.splitlines()) + "\n..." | |
|
866 | print(inline, file=outfile) | |
|
867 | if get_output and output: | |
|
868 | print(output, file=outfile) | |
|
869 | ||
|
870 | if close_at_end: | |
|
871 | outfile.close() | |
|
872 | ||
|
873 | ||
|
874 | def magic_rep(self, arg): | |
|
875 | r"""Repeat a command, or get command to input line for editing. | |
|
876 | ||
|
877 | %recall and %rep are equivalent. | |
|
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. | |
|
878 | 786 | |
|
879 | - %recall (no arguments): | |
|
787 | Examples | |
|
788 | -------- | |
|
789 | :: | |
|
880 | 790 | |
|
881 | Place a string version of last computation result (stored in the special '_' | |
|
882 | variable) to the next input prompt. Allows you to create elaborate command | |
|
883 | lines without using copy-paste:: | |
|
791 | In [6]: %hist -n 4-6 | |
|
792 | 4:a = 12 | |
|
793 | 5:print a**2 | |
|
794 | 6:%hist -n 4-6 | |
|
884 | 795 | |
|
885 | In[1]: l = ["hei", "vaan"] | |
|
886 | In[2]: "".join(l) | |
|
887 | Out[2]: heivaan | |
|
888 | In[3]: %rep | |
|
889 | In[4]: heivaan_ <== cursor blinking | |
|
890 | ||
|
891 | %recall 45 | |
|
892 | ||
|
893 | Place history line 45 on the next input prompt. Use %hist to find | |
|
894 | out the number. | |
|
796 | """ | |
|
895 | 797 | |
|
896 | %recall 1-4 | |
|
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') | |
|
897 | 803 | |
|
898 | Combine the specified lines into one cell, and place it on the next | |
|
899 | input prompt. See %history for the slice syntax. | |
|
804 | # For brevity | |
|
805 | history_manager = self.shell.history_manager | |
|
900 | 806 | |
|
901 | %recall foo+bar | |
|
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) | |
|
902 | 812 | |
|
903 | If foo+bar can be evaluated in the user namespace, the result is | |
|
904 | placed at the next input prompt. Otherwise, the history is searched | |
|
905 | for lines which contain that substring, and the most recent one is | |
|
906 | placed at the next input prompt. | |
|
907 | """ | |
|
908 | if not arg: # Last output | |
|
909 | self.shell.set_next_input(str(self.shell.user_ns["_"])) | |
|
910 |
|
|
|
911 | # Get history range | |
|
912 | histlines = self.shell.history_manager.get_range_by_str(arg) | |
|
913 | cmd = "\n".join(x[2] for x in histlines) | |
|
914 | if cmd: | |
|
915 | self.shell.set_next_input(cmd.rstrip()) | |
|
916 | return | |
|
917 | ||
|
918 | try: # Variable in user namespace | |
|
919 | cmd = str(eval(arg, self.shell.user_ns)) | |
|
920 | except Exception: # Search for term in history | |
|
921 | histlines = self.shell.history_manager.search("*"+arg+"*") | |
|
922 | for h in reversed([x[2] for x in histlines]): | |
|
923 | if 'rep' in h: | |
|
924 | continue | |
|
925 | self.shell.set_next_input(h.rstrip()) | |
|
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 | @line_magic | |
|
888 | def rep(self, arg): | |
|
889 | r"""Repeat a command, or get command to input line for editing. | |
|
890 | ||
|
891 | %recall and %rep are equivalent. | |
|
892 | ||
|
893 | - %recall (no arguments): | |
|
894 | ||
|
895 | Place a string version of last computation result (stored in the | |
|
896 | special '_' variable) to the next input prompt. Allows you to create | |
|
897 | elaborate command lines without using copy-paste:: | |
|
898 | ||
|
899 | In[1]: l = ["hei", "vaan"] | |
|
900 | In[2]: "".join(l) | |
|
901 | Out[2]: heivaan | |
|
902 | In[3]: %rep | |
|
903 | In[4]: heivaan_ <== cursor blinking | |
|
904 | ||
|
905 | %recall 45 | |
|
906 | ||
|
907 | Place history line 45 on the next input prompt. Use %hist to find | |
|
908 | out the number. | |
|
909 | ||
|
910 | %recall 1-4 | |
|
911 | ||
|
912 | Combine the specified lines into one cell, and place it on the next | |
|
913 | input prompt. See %history for the slice syntax. | |
|
914 | ||
|
915 | %recall foo+bar | |
|
916 | ||
|
917 | If foo+bar can be evaluated in the user namespace, the result is | |
|
918 | placed at the next input prompt. Otherwise, the history is searched | |
|
919 | for lines which contain that substring, and the most recent one is | |
|
920 | placed at the next input prompt. | |
|
921 | """ | |
|
922 | if not arg: # Last output | |
|
923 | self.shell.set_next_input(str(self.shell.user_ns["_"])) | |
|
924 | return | |
|
925 | # Get history range | |
|
926 | histlines = self.shell.history_manager.get_range_by_str(arg) | |
|
927 | cmd = "\n".join(x[2] for x in histlines) | |
|
928 | if cmd: | |
|
929 | self.shell.set_next_input(cmd.rstrip()) | |
|
926 | 930 | return |
|
927 | else: | |
|
928 | self.shell.set_next_input(cmd.rstrip()) | |
|
929 | print("Couldn't evaluate or find in history:", arg) | |
|
930 | 931 | |
|
932 | try: # Variable in user namespace | |
|
933 | cmd = str(eval(arg, self.shell.user_ns)) | |
|
934 | except Exception: # Search for term in history | |
|
935 | histlines = self.shell.history_manager.search("*"+arg+"*") | |
|
936 | for h in reversed([x[2] for x in histlines]): | |
|
937 | if 'rep' in h: | |
|
938 | continue | |
|
939 | self.shell.set_next_input(h.rstrip()) | |
|
940 | return | |
|
941 | else: | |
|
942 | self.shell.set_next_input(cmd.rstrip()) | |
|
943 | print("Couldn't evaluate or find in history:", arg) | |
|
931 | 944 | |
|
932 | def magic_rerun(self, parameter_s=''): | |
|
933 | """Re-run previous input | |
|
945 | @line_magic | |
|
946 | def rerun(self, parameter_s=''): | |
|
947 | """Re-run previous input | |
|
934 | 948 | |
|
935 | By default, you can specify ranges of input history to be repeated | |
|
936 | (as with %history). With no arguments, it will repeat the last line. | |
|
949 | By default, you can specify ranges of input history to be repeated | |
|
950 | (as with %history). With no arguments, it will repeat the last line. | |
|
937 | 951 | |
|
938 | Options: | |
|
952 | Options: | |
|
939 | 953 | |
|
940 | -l <n> : Repeat the last n lines of input, not including the | |
|
941 | current command. | |
|
954 | -l <n> : Repeat the last n lines of input, not including the | |
|
955 | current command. | |
|
942 | 956 | |
|
943 | -g foo : Repeat the most recent line which contains foo | |
|
944 | """ | |
|
945 | opts, args = self.parse_options(parameter_s, 'l:g:', mode='string') | |
|
946 | if "l" in opts: # Last n lines | |
|
947 | n = int(opts['l']) | |
|
948 | hist = self.shell.history_manager.get_tail(n) | |
|
949 | elif "g" in opts: # Search | |
|
950 | p = "*"+opts['g']+"*" | |
|
951 | hist = list(self.shell.history_manager.search(p)) | |
|
952 | for l in reversed(hist): | |
|
953 | if "rerun" not in l[2]: | |
|
954 | hist = [l] # The last match which isn't a %rerun | |
|
955 | break | |
|
956 | else: | |
|
957 | hist = [] # No matches except %rerun | |
|
958 | elif args: # Specify history ranges | |
|
959 | hist = self.shell.history_manager.get_range_by_str(args) | |
|
960 | else: # Last line | |
|
961 | hist = self.shell.history_manager.get_tail(1) | |
|
962 | hist = [x[2] for x in hist] | |
|
963 | if not hist: | |
|
964 | print("No lines in history match specification") | |
|
965 | return | |
|
966 | histlines = "\n".join(hist) | |
|
967 | print("=== Executing: ===") | |
|
968 | print(histlines) | |
|
969 | print("=== Output: ===") | |
|
970 | self.shell.run_cell("\n".join(hist), store_history=False) | |
|
957 | -g foo : Repeat the most recent line which contains foo | |
|
958 | """ | |
|
959 | opts, args = self.parse_options(parameter_s, 'l:g:', mode='string') | |
|
960 | if "l" in opts: # Last n lines | |
|
961 | n = int(opts['l']) | |
|
962 | hist = self.shell.history_manager.get_tail(n) | |
|
963 | elif "g" in opts: # Search | |
|
964 | p = "*"+opts['g']+"*" | |
|
965 | hist = list(self.shell.history_manager.search(p)) | |
|
966 | for l in reversed(hist): | |
|
967 | if "rerun" not in l[2]: | |
|
968 | hist = [l] # The last match which isn't a %rerun | |
|
969 | break | |
|
970 | else: | |
|
971 | hist = [] # No matches except %rerun | |
|
972 | elif args: # Specify history ranges | |
|
973 | hist = self.shell.history_manager.get_range_by_str(args) | |
|
974 | else: # Last line | |
|
975 | hist = self.shell.history_manager.get_tail(1) | |
|
976 | hist = [x[2] for x in hist] | |
|
977 | if not hist: | |
|
978 | print("No lines in history match specification") | |
|
979 | return | |
|
980 | histlines = "\n".join(hist) | |
|
981 | print("=== Executing: ===") | |
|
982 | print(histlines) | |
|
983 | print("=== Output: ===") | |
|
984 | self.shell.run_cell("\n".join(hist), store_history=False) | |
|
971 | 985 | |
|
972 | 986 | |
|
973 | 987 | def init_ipython(ip): |
|
974 | ip.define_magic("rep", magic_rep) | |
|
975 |
ip.define_magic( |
|
|
976 |
ip.define_magic( |
|
|
977 | ip.define_magic("hist", magic_history) # Alternative name | |
|
978 | ip.define_magic("history", magic_history) | |
|
988 | ip.magics_manager.register(HistoryMagics) | |
|
989 | #ip.define_magic('hist', HistoryMagics.history) | |
|
990 | #ip.define_magic('recall', HistoryMagics.rep) | |
|
979 | 991 | |
|
980 | 992 | # XXX - ipy_completers are in quarantine, need to be updated to new apis |
|
981 | 993 | #import ipy_completers |
General Comments 0
You need to be logged in to leave comments.
Login now