##// END OF EJS Templates
Add prompt toolkit 3 compatibility to ipdb...
Matthias Bussonnier -
Show More
@@ -1,120 +1,126 b''
1 import signal
1 import signal
2 import sys
2 import sys
3
3
4 from IPython.core.debugger import Pdb
4 from IPython.core.debugger import Pdb
5
5
6 from IPython.core.completer import IPCompleter
6 from IPython.core.completer import IPCompleter
7 from .ptutils import IPythonPTCompleter
7 from .ptutils import IPythonPTCompleter
8 from .shortcuts import suspend_to_bg, cursor_in_leading_ws
8 from .shortcuts import suspend_to_bg, cursor_in_leading_ws
9
9
10 from prompt_toolkit.enums import DEFAULT_BUFFER
10 from prompt_toolkit.enums import DEFAULT_BUFFER
11 from prompt_toolkit.filters import (Condition, has_focus, has_selection,
11 from prompt_toolkit.filters import (Condition, has_focus, has_selection,
12 vi_insert_mode, emacs_insert_mode)
12 vi_insert_mode, emacs_insert_mode)
13 from prompt_toolkit.key_binding import KeyBindings
13 from prompt_toolkit.key_binding import KeyBindings
14 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
14 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
15 from pygments.token import Token
15 from pygments.token import Token
16 from prompt_toolkit.shortcuts.prompt import PromptSession
16 from prompt_toolkit.shortcuts.prompt import PromptSession
17 from prompt_toolkit.enums import EditingMode
17 from prompt_toolkit.enums import EditingMode
18 from prompt_toolkit.formatted_text import PygmentsTokens
18 from prompt_toolkit.formatted_text import PygmentsTokens
19
19
20 from prompt_toolkit import __version__ as ptk_version
21 PTK3 = ptk_version.startswith('3.')
22
20
23
21 class TerminalPdb(Pdb):
24 class TerminalPdb(Pdb):
22 """Standalone IPython debugger."""
25 """Standalone IPython debugger."""
23
26
24 def __init__(self, *args, **kwargs):
27 def __init__(self, *args, **kwargs):
25 Pdb.__init__(self, *args, **kwargs)
28 Pdb.__init__(self, *args, **kwargs)
26 self._ptcomp = None
29 self._ptcomp = None
27 self.pt_init()
30 self.pt_init()
28
31
29 def pt_init(self):
32 def pt_init(self):
30 def get_prompt_tokens():
33 def get_prompt_tokens():
31 return [(Token.Prompt, self.prompt)]
34 return [(Token.Prompt, self.prompt)]
32
35
33 if self._ptcomp is None:
36 if self._ptcomp is None:
34 compl = IPCompleter(shell=self.shell,
37 compl = IPCompleter(shell=self.shell,
35 namespace={},
38 namespace={},
36 global_namespace={},
39 global_namespace={},
37 parent=self.shell,
40 parent=self.shell,
38 )
41 )
39 self._ptcomp = IPythonPTCompleter(compl)
42 self._ptcomp = IPythonPTCompleter(compl)
40
43
41 kb = KeyBindings()
44 kb = KeyBindings()
42 supports_suspend = Condition(lambda: hasattr(signal, 'SIGTSTP'))
45 supports_suspend = Condition(lambda: hasattr(signal, 'SIGTSTP'))
43 kb.add('c-z', filter=supports_suspend)(suspend_to_bg)
46 kb.add('c-z', filter=supports_suspend)(suspend_to_bg)
44
47
45 if self.shell.display_completions == 'readlinelike':
48 if self.shell.display_completions == 'readlinelike':
46 kb.add('tab', filter=(has_focus(DEFAULT_BUFFER)
49 kb.add('tab', filter=(has_focus(DEFAULT_BUFFER)
47 & ~has_selection
50 & ~has_selection
48 & vi_insert_mode | emacs_insert_mode
51 & vi_insert_mode | emacs_insert_mode
49 & ~cursor_in_leading_ws
52 & ~cursor_in_leading_ws
50 ))(display_completions_like_readline)
53 ))(display_completions_like_readline)
51
54
52 self.pt_app = PromptSession(
55 options = dict(
53 message=(lambda: PygmentsTokens(get_prompt_tokens())),
56 message=(lambda: PygmentsTokens(get_prompt_tokens())),
54 editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()),
57 editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()),
55 key_bindings=kb,
58 key_bindings=kb,
56 history=self.shell.debugger_history,
59 history=self.shell.debugger_history,
57 completer=self._ptcomp,
60 completer=self._ptcomp,
58 enable_history_search=True,
61 enable_history_search=True,
59 mouse_support=self.shell.mouse_support,
62 mouse_support=self.shell.mouse_support,
60 complete_style=self.shell.pt_complete_style,
63 complete_style=self.shell.pt_complete_style,
61 style=self.shell.style,
64 style=self.shell.style,
62 inputhook=self.shell.inputhook,
65 color_depth=self.shell.color_depth,
63 color_depth=self.shell.color_depth,
64 )
66 )
65
67
68 if not PTK3:
69 options['inputhook'] = self.inputhook
70 self.pt_app = PromptSession(**options)
71
66 def cmdloop(self, intro=None):
72 def cmdloop(self, intro=None):
67 """Repeatedly issue a prompt, accept input, parse an initial prefix
73 """Repeatedly issue a prompt, accept input, parse an initial prefix
68 off the received input, and dispatch to action methods, passing them
74 off the received input, and dispatch to action methods, passing them
69 the remainder of the line as argument.
75 the remainder of the line as argument.
70
76
71 override the same methods from cmd.Cmd to provide prompt toolkit replacement.
77 override the same methods from cmd.Cmd to provide prompt toolkit replacement.
72 """
78 """
73 if not self.use_rawinput:
79 if not self.use_rawinput:
74 raise ValueError('Sorry ipdb does not support use_rawinput=False')
80 raise ValueError('Sorry ipdb does not support use_rawinput=False')
75
81
76 self.preloop()
82 self.preloop()
77
83
78 try:
84 try:
79 if intro is not None:
85 if intro is not None:
80 self.intro = intro
86 self.intro = intro
81 if self.intro:
87 if self.intro:
82 self.stdout.write(str(self.intro)+"\n")
88 self.stdout.write(str(self.intro)+"\n")
83 stop = None
89 stop = None
84 while not stop:
90 while not stop:
85 if self.cmdqueue:
91 if self.cmdqueue:
86 line = self.cmdqueue.pop(0)
92 line = self.cmdqueue.pop(0)
87 else:
93 else:
88 self._ptcomp.ipy_completer.namespace = self.curframe_locals
94 self._ptcomp.ipy_completer.namespace = self.curframe_locals
89 self._ptcomp.ipy_completer.global_namespace = self.curframe.f_globals
95 self._ptcomp.ipy_completer.global_namespace = self.curframe.f_globals
90 try:
96 try:
91 line = self.pt_app.prompt() # reset_current_buffer=True)
97 line = self.pt_app.prompt() # reset_current_buffer=True)
92 except EOFError:
98 except EOFError:
93 line = 'EOF'
99 line = 'EOF'
94 line = self.precmd(line)
100 line = self.precmd(line)
95 stop = self.onecmd(line)
101 stop = self.onecmd(line)
96 stop = self.postcmd(stop, line)
102 stop = self.postcmd(stop, line)
97 self.postloop()
103 self.postloop()
98 except Exception:
104 except Exception:
99 raise
105 raise
100
106
101
107
102 def set_trace(frame=None):
108 def set_trace(frame=None):
103 """
109 """
104 Start debugging from `frame`.
110 Start debugging from `frame`.
105
111
106 If frame is not specified, debugging starts from caller's frame.
112 If frame is not specified, debugging starts from caller's frame.
107 """
113 """
108 TerminalPdb().set_trace(frame or sys._getframe().f_back)
114 TerminalPdb().set_trace(frame or sys._getframe().f_back)
109
115
110
116
111 if __name__ == '__main__':
117 if __name__ == '__main__':
112 import pdb
118 import pdb
113 # IPython.core.debugger.Pdb.trace_dispatch shall not catch
119 # IPython.core.debugger.Pdb.trace_dispatch shall not catch
114 # bdb.BdbQuit. When started through __main__ and an exception
120 # bdb.BdbQuit. When started through __main__ and an exception
115 # happened after hitting "c", this is needed in order to
121 # happened after hitting "c", this is needed in order to
116 # be able to quit the debugging session (see #9950).
122 # be able to quit the debugging session (see #9950).
117 old_trace_dispatch = pdb.Pdb.trace_dispatch
123 old_trace_dispatch = pdb.Pdb.trace_dispatch
118 pdb.Pdb = TerminalPdb
124 pdb.Pdb = TerminalPdb
119 pdb.Pdb.trace_dispatch = old_trace_dispatch
125 pdb.Pdb.trace_dispatch = old_trace_dispatch
120 pdb.main()
126 pdb.main()
General Comments 0
You need to be logged in to leave comments. Login now