Show More
@@ -13,6 +13,7 b'' | |||
|
13 | 13 | from __future__ import print_function |
|
14 | 14 | |
|
15 | 15 | # Stdlib imports |
|
16 | import atexit | |
|
16 | 17 | import fnmatch |
|
17 | 18 | import json |
|
18 | 19 | import os |
@@ -105,6 +106,13 b' class HistoryManager(object):' | |||
|
105 | 106 | |
|
106 | 107 | # Fill the history zero entry, user counter starts at 1 |
|
107 | 108 | self.store_inputs('\n', '\n') |
|
109 | ||
|
110 | # Autosave every 60 seconds: | |
|
111 | self.autosave_flag = threading.Event() | |
|
112 | self.autosave_timer = HistorySaveThread(self.autosave_flag, 60) | |
|
113 | self.autosave_timer.start() | |
|
114 | self.shell.register_post_execute(self.autosave_if_due) | |
|
115 | # Ensure that any autosave thread we start is stopped tidily. | |
|
108 | 116 | |
|
109 | 117 | def _init_shadow_hist(self): |
|
110 | 118 | try: |
@@ -142,6 +150,13 b' class HistoryManager(object):' | |||
|
142 | 150 | with open(self.hist_file,'wt') as hfile: |
|
143 | 151 | json.dump(hist, hfile, |
|
144 | 152 | sort_keys=True, indent=4) |
|
153 | ||
|
154 | def autosave_if_due(self): | |
|
155 | """Check if the autosave event is set; if so, save history. We do it | |
|
156 | this way so that the save takes place in the main thread.""" | |
|
157 | if self.autosave_flag.is_set(): | |
|
158 | self.save_history() | |
|
159 | self.autosave_flag.clear() | |
|
145 | 160 | |
|
146 | 161 | def reload_history(self): |
|
147 | 162 | """Reload the input history from disk file.""" |
@@ -257,29 +272,34 b' class HistoryManager(object):' | |||
|
257 | 272 | self.dir_hist[:] = [os.getcwd()] |
|
258 | 273 | |
|
259 | 274 | class HistorySaveThread(threading.Thread): |
|
260 |
"""This thread save |
|
|
261 |
minute), so that it is not lost in the event of a crash. It also |
|
|
262 |
commands in the current IPython shell to be accessed in a newly |
|
|
263 |
instance. |
|
|
275 | """This thread makes IPython save history periodically (the current default | |
|
276 | is once per minute), so that it is not lost in the event of a crash. It also | |
|
277 | allows the commands in the current IPython shell to be accessed in a newly | |
|
278 | started instance. | |
|
279 | ||
|
280 | This simply sets an event to indicate that history should be saved. The | |
|
281 | actual save is carried out after executing a user command, to avoid | |
|
282 | thread issues.""" | |
|
264 | 283 | daemon = True |
|
265 | 284 | |
|
266 |
def __init__(self, |
|
|
285 | def __init__(self, autosave_flag, time_interval=60): | |
|
267 | 286 | threading.Thread.__init__(self) |
|
268 | self.IPython_object = IPython_object | |
|
269 | 287 | self.time_interval = time_interval |
|
288 | self.autosave_flag = autosave_flag | |
|
270 | 289 | self.exit_now = threading.Event() |
|
290 | # Ensure the thread is stopped tidily when exiting normally | |
|
291 | atexit.register(self.stop) | |
|
271 | 292 | |
|
272 | 293 | def run(self): |
|
273 | 294 | while True: |
|
274 | 295 | self.exit_now.wait(self.time_interval) |
|
275 | 296 | if self.exit_now.is_set(): |
|
276 | 297 | break |
|
277 |
#print(" |
|
|
278 |
self. |
|
|
298 | #print("Setting flag for autosaving history...") # DEBUG | |
|
299 | self.autosave_flag.set() | |
|
279 | 300 | |
|
280 | 301 | def stop(self): |
|
281 |
"""Safely and quickly stop the autosave thread. |
|
|
282 | history to be saved before stopping.""" | |
|
302 | """Safely and quickly stop the autosave timer thread.""" | |
|
283 | 303 | self.exit_now.set() |
|
284 | 304 | self.join() |
|
285 | 305 |
@@ -45,7 +45,6 b' from IPython.core.error import TryNext, UsageError' | |||
|
45 | 45 | from IPython.core.extensions import ExtensionManager |
|
46 | 46 | from IPython.core.fakemodule import FakeModule, init_fakemod_dict |
|
47 | 47 | from IPython.core.history import HistoryManager |
|
48 | from IPython.core.history import HistorySaveThread | |
|
49 | 48 | from IPython.core.inputsplitter import IPythonInputSplitter |
|
50 | 49 | from IPython.core.logger import Logger |
|
51 | 50 | from IPython.core.magic import Magic |
@@ -1238,8 +1237,6 b' class InteractiveShell(Configurable, Magic):' | |||
|
1238 | 1237 | def init_history(self): |
|
1239 | 1238 | """Sets up the command history, and starts regular autosaves.""" |
|
1240 | 1239 | self.history_manager = HistoryManager(shell=self) |
|
1241 | self.history_thread = HistorySaveThread(self, time_interval=60) | |
|
1242 | self.history_thread.start() | |
|
1243 | 1240 | |
|
1244 | 1241 | def save_history(self): |
|
1245 | 1242 | """Save input history to a file (via readline library).""" |
@@ -2527,7 +2524,6 b' class InteractiveShell(Configurable, Magic):' | |||
|
2527 | 2524 | except OSError: |
|
2528 | 2525 | pass |
|
2529 | 2526 | |
|
2530 | self.history_thread.stop() | |
|
2531 | 2527 | self.save_history() |
|
2532 | 2528 | |
|
2533 | 2529 | # Clear all user namespaces to release all references cleanly. |
@@ -24,7 +24,6 b' import sys' | |||
|
24 | 24 | from IPython.core.error import TryNext |
|
25 | 25 | from IPython.core.usage import interactive_usage, default_banner |
|
26 | 26 | from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC |
|
27 | from IPython.core.history import HistorySaveThread | |
|
28 | 27 | from IPython.lib.inputhook import enable_gui |
|
29 | 28 | from IPython.lib.pylabtools import pylab_activate |
|
30 | 29 | from IPython.utils.terminal import toggle_set_term_title, set_term_title |
General Comments 0
You need to be logged in to leave comments.
Login now