Show More
@@ -1432,6 +1432,7 b' class SyntaxTB(ListTB):' | |||||
1432 | newtext = ulinecache.getline(value.filename, value.lineno) |
|
1432 | newtext = ulinecache.getline(value.filename, value.lineno) | |
1433 | if newtext: |
|
1433 | if newtext: | |
1434 | value.text = newtext |
|
1434 | value.text = newtext | |
|
1435 | self.last_syntax_error = value | |||
1435 | return super(SyntaxTB, self).structured_traceback(etype, value, elist, |
|
1436 | return super(SyntaxTB, self).structured_traceback(etype, value, elist, | |
1436 | tb_offset=tb_offset, context=context) |
|
1437 | tb_offset=tb_offset, context=context) | |
1437 |
|
1438 |
@@ -4,7 +4,9 b' from __future__ import print_function' | |||||
4 | import os |
|
4 | import os | |
5 | import sys |
|
5 | import sys | |
6 | import signal |
|
6 | import signal | |
|
7 | from warnings import warn | |||
7 |
|
8 | |||
|
9 | from IPython.core.error import TryNext | |||
8 | from IPython.core.interactiveshell import InteractiveShell |
|
10 | from IPython.core.interactiveshell import InteractiveShell | |
9 | from IPython.utils.py3compat import PY3, cast_unicode_py2, input |
|
11 | from IPython.utils.py3compat import PY3, cast_unicode_py2, input | |
10 | from IPython.utils.terminal import toggle_set_term_title, set_term_title |
|
12 | from IPython.utils.terminal import toggle_set_term_title, set_term_title | |
@@ -72,6 +74,9 b' class TerminalInteractiveShell(InteractiveShell):' | |||||
72 |
|
74 | |||
73 | pt_cli = None |
|
75 | pt_cli = None | |
74 |
|
76 | |||
|
77 | autoedit_syntax = CBool(False, config=True, | |||
|
78 | help="auto editing of files with syntax errors.") | |||
|
79 | ||||
75 | confirm_exit = CBool(True, config=True, |
|
80 | confirm_exit = CBool(True, config=True, | |
76 | help=""" |
|
81 | help=""" | |
77 | Set to confirm when you try to exit IPython with an EOF (Control-D |
|
82 | Set to confirm when you try to exit IPython with an EOF (Control-D | |
@@ -295,6 +300,8 b' class TerminalInteractiveShell(InteractiveShell):' | |||||
295 | else: |
|
300 | else: | |
296 | if code: |
|
301 | if code: | |
297 | self.run_cell(code, store_history=True) |
|
302 | self.run_cell(code, store_history=True) | |
|
303 | if self.autoedit_syntax and self.SyntaxTB.last_syntax_error: | |||
|
304 | self.edit_syntax_error() | |||
298 |
|
305 | |||
299 | def mainloop(self): |
|
306 | def mainloop(self): | |
300 | # An extra layer of protection in case someone mashing Ctrl-C breaks |
|
307 | # An extra layer of protection in case someone mashing Ctrl-C breaks | |
@@ -317,5 +324,67 b' class TerminalInteractiveShell(InteractiveShell):' | |||||
317 | else: |
|
324 | else: | |
318 | self._inputhook = None |
|
325 | self._inputhook = None | |
319 |
|
326 | |||
|
327 | # Methods to support auto-editing of SyntaxErrors: | |||
|
328 | ||||
|
329 | def edit_syntax_error(self): | |||
|
330 | """The bottom half of the syntax error handler called in the main loop. | |||
|
331 | ||||
|
332 | Loop until syntax error is fixed or user cancels. | |||
|
333 | """ | |||
|
334 | ||||
|
335 | while self.SyntaxTB.last_syntax_error: | |||
|
336 | # copy and clear last_syntax_error | |||
|
337 | err = self.SyntaxTB.clear_err_state() | |||
|
338 | if not self._should_recompile(err): | |||
|
339 | return | |||
|
340 | try: | |||
|
341 | # may set last_syntax_error again if a SyntaxError is raised | |||
|
342 | self.safe_execfile(err.filename, self.user_ns) | |||
|
343 | except: | |||
|
344 | self.showtraceback() | |||
|
345 | else: | |||
|
346 | try: | |||
|
347 | f = open(err.filename) | |||
|
348 | try: | |||
|
349 | # This should be inside a display_trap block and I | |||
|
350 | # think it is. | |||
|
351 | sys.displayhook(f.read()) | |||
|
352 | finally: | |||
|
353 | f.close() | |||
|
354 | except: | |||
|
355 | self.showtraceback() | |||
|
356 | ||||
|
357 | def _should_recompile(self, e): | |||
|
358 | """Utility routine for edit_syntax_error""" | |||
|
359 | ||||
|
360 | if e.filename in ('<ipython console>', '<input>', '<string>', | |||
|
361 | '<console>', '<BackgroundJob compilation>', | |||
|
362 | None): | |||
|
363 | return False | |||
|
364 | try: | |||
|
365 | if (self.autoedit_syntax and | |||
|
366 | not self.ask_yes_no( | |||
|
367 | 'Return to editor to correct syntax error? ' | |||
|
368 | '[Y/n] ', 'y')): | |||
|
369 | return False | |||
|
370 | except EOFError: | |||
|
371 | return False | |||
|
372 | ||||
|
373 | def int0(x): | |||
|
374 | try: | |||
|
375 | return int(x) | |||
|
376 | except TypeError: | |||
|
377 | return 0 | |||
|
378 | ||||
|
379 | # always pass integer line and offset values to editor hook | |||
|
380 | try: | |||
|
381 | self.hooks.fix_error_editor(e.filename, | |||
|
382 | int0(e.lineno), int0(e.offset), | |||
|
383 | e.msg) | |||
|
384 | except TryNext: | |||
|
385 | warn('Could not open editor') | |||
|
386 | return False | |||
|
387 | return True | |||
|
388 | ||||
320 | if __name__ == '__main__': |
|
389 | if __name__ == '__main__': | |
321 | TerminalInteractiveShell.instance().interact() |
|
390 | TerminalInteractiveShell.instance().interact() |
General Comments 0
You need to be logged in to leave comments.
Login now