##// END OF EJS Templates
Add Ctrl-Z shortcut (suspend) in terminal debugger...
Thomas Kluyver -
Show More
@@ -1,98 +1,110 b''
1 import signal
2 import sys
3
1 4 from IPython.core.debugger import Pdb
2 5
3 6 from IPython.core.completer import IPCompleter
4 7 from .ptutils import IPythonPTCompleter
8 from .shortcuts import suspend_to_bg
5 9
10 from prompt_toolkit.filters import Condition
11 from prompt_toolkit.keys import Keys
12 from prompt_toolkit.key_binding.manager import KeyBindingManager
6 13 from prompt_toolkit.token import Token
7 14 from prompt_toolkit.shortcuts import create_prompt_application
8 15 from prompt_toolkit.interface import CommandLineInterface
9 16 from prompt_toolkit.enums import EditingMode
10 import sys
11 17
12 18
13 19 class TerminalPdb(Pdb):
14 20 def __init__(self, *args, **kwargs):
15 21 Pdb.__init__(self, *args, **kwargs)
16 22 self._ptcomp = None
17 23 self.pt_init()
18 24
19 25 def pt_init(self):
20 26 def get_prompt_tokens(cli):
21 27 return [(Token.Prompt, self.prompt)]
22 28
23 29 def patch_stdout(**kwargs):
24 30 return self.pt_cli.patch_stdout_context(**kwargs)
25 31
26 32 if self._ptcomp is None:
27 33 compl = IPCompleter(shell=self.shell,
28 34 namespace={},
29 35 global_namespace={},
30 36 parent=self.shell,
31 37 )
32 38 self._ptcomp = IPythonPTCompleter(compl, patch_stdout=patch_stdout)
33 39
40 kbmanager = KeyBindingManager.for_prompt()
41 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
42 kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend
43 )(suspend_to_bg)
44
34 45 self._pt_app = create_prompt_application(
35 46 editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()),
47 key_bindings_registry=kbmanager.registry,
36 48 history=self.shell.debugger_history,
37 49 completer= self._ptcomp,
38 50 enable_history_search=True,
39 51 mouse_support=self.shell.mouse_support,
40 52 get_prompt_tokens=get_prompt_tokens
41 53 )
42 54 self.pt_cli = CommandLineInterface(self._pt_app, eventloop=self.shell._eventloop)
43 55
44 56 def cmdloop(self, intro=None):
45 57 """Repeatedly issue a prompt, accept input, parse an initial prefix
46 58 off the received input, and dispatch to action methods, passing them
47 59 the remainder of the line as argument.
48 60
49 61 override the same methods from cmd.Cmd to provide prompt toolkit replacement.
50 62 """
51 63 if not self.use_rawinput:
52 64 raise ValueError('Sorry ipdb does not support use_rawinput=False')
53 65
54 66 self.preloop()
55 67
56 68 try:
57 69 if intro is not None:
58 70 self.intro = intro
59 71 if self.intro:
60 72 self.stdout.write(str(self.intro)+"\n")
61 73 stop = None
62 74 while not stop:
63 75 if self.cmdqueue:
64 76 line = self.cmdqueue.pop(0)
65 77 else:
66 78 self._ptcomp.ipy_completer.namespace = self.curframe_locals
67 79 self._ptcomp.ipy_completer.global_namespace = self.curframe.f_globals
68 80 try:
69 81 line = self.pt_cli.run(reset_current_buffer=True).text
70 82 except EOFError:
71 83 line = 'EOF'
72 84 line = self.precmd(line)
73 85 stop = self.onecmd(line)
74 86 stop = self.postcmd(stop, line)
75 87 self.postloop()
76 88 except Exception:
77 89 raise
78 90
79 91
80 92 def set_trace(frame=None):
81 93 """
82 94 Start debugging from `frame`.
83 95
84 96 If frame is not specified, debugging starts from caller's frame.
85 97 """
86 98 TerminalPdb().set_trace(frame or sys._getframe().f_back)
87 99
88 100
89 101 if __name__ == '__main__':
90 102 import pdb
91 103 # IPython.core.debugger.Pdb.trace_dispatch shall not catch
92 104 # bdb.BdbQuit. When started through __main__ and an exception
93 105 # happened after hitting "c", this is needed in order to
94 106 # be able to quit the debugging session (see #9950).
95 107 old_trace_dispatch = pdb.Pdb.trace_dispatch
96 108 pdb.Pdb = TerminalPdb
97 109 pdb.Pdb.trace_dispatch = old_trace_dispatch
98 110 pdb.main()
General Comments 0
You need to be logged in to leave comments. Login now