11import code
22import contextlib
33import errno
4+ import functools
45import greenlet
56import logging
67import os
3839from bpython .curtsiesfrontend import sitefix ; sitefix .monkeypatch_quit ()
3940import bpython .curtsiesfrontend .replpainter as paint
4041from bpython .curtsiesfrontend .coderunner import CodeRunner , FakeOutput
42+ from bpython .curtsiesfrontend .filewatch import ModuleChangedEventHandler
4143
4244#TODO other autocomplete modes (also fix in other bpython implementations)
4345
@@ -174,10 +176,10 @@ class Repl(BpythonRepl):
174176 """
175177
176178 ## initialization, cleanup
177- def __init__ (self , locals_ = None , config = None ,
178- request_refresh = lambda : None , get_term_hw = lambda :(50 , 10 ),
179- get_cursor_vertical_diff = lambda : 0 , banner = None , interp = None , interactive = True ,
180- orig_tcattrs = None ):
179+ def __init__ (self , locals_ = None , config = None , request_refresh = lambda : None ,
180+ request_reload = lambda desc : None , get_term_hw = lambda :(50 , 10 ),
181+ get_cursor_vertical_diff = lambda : 0 , banner = None , interp = None ,
182+ interactive = True , orig_tcattrs = None ):
181183 """
182184 locals_ is a mapping of locals to pass into the interpreter
183185 config is a bpython config.Struct with config attributes
@@ -217,6 +219,12 @@ def smarter_request_refresh(when='now'):
217219 else :
218220 request_refresh (when = when )
219221 self .request_refresh = smarter_request_refresh
222+ def smarter_request_reload (desc ):
223+ if self .watching_files :
224+ request_reload (desc )
225+ else :
226+ pass
227+ self .request_reload = smarter_request_reload
220228 self .get_term_hw = get_term_hw
221229 self .get_cursor_vertical_diff = get_cursor_vertical_diff
222230
@@ -271,6 +279,8 @@ def smarter_request_refresh(when='now'):
271279 self .width = None # will both be set by a window resize event
272280 self .height = None
273281
282+ self .watcher = ModuleChangedEventHandler ([], smarter_request_reload )
283+
274284 def __enter__ (self ):
275285 self .orig_stdout = sys .stdout
276286 self .orig_stderr = sys .stderr
@@ -280,13 +290,24 @@ def __enter__(self):
280290 sys .stdin = self .stdin
281291 self .orig_sigwinch_handler = signal .getsignal (signal .SIGWINCH )
282292 signal .signal (signal .SIGWINCH , self .sigwinch_handler )
293+
294+ self .orig_import = __builtins__ ['__import__' ]
295+ @functools .wraps (self .orig_import )
296+ def new_import (name , globals = {}, locals = {}, fromlist = [], level = - 1 ):
297+ m = self .orig_import (name , globals = globals , locals = locals , fromlist = fromlist )
298+ if hasattr (m , "__file__" ):
299+ self .watcher .add_module (m .__file__ )
300+ return m
301+ __builtins__ ['__import__' ] = new_import
302+
283303 return self
284304
285305 def __exit__ (self , * args ):
286306 sys .stdin = self .orig_stdin
287307 sys .stdout = self .orig_stdout
288308 sys .stderr = self .orig_stderr
289309 signal .signal (signal .SIGWINCH , self .orig_sigwinch_handler )
310+ __builtins__ ['__import__' ] = self .orig_import
290311
291312 def sigwinch_handler (self , signum , frame ):
292313 old_rows , old_columns = self .height , self .width
@@ -373,6 +394,7 @@ def process_event(self, e):
373394 elif e in key_dispatch [self .config .toggle_file_watch_key ]:
374395 msg = "Auto-reloading active, watching for file changes..."
375396 if self .watching_files :
397+ self .watcher .reset ()
376398 self .watching_files = False
377399 self .status_bar .pop_permanent_message (msg )
378400 else :
0 commit comments