textual-debugger 0.2.14__tar.gz → 0.2.16__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/PKG-INFO +213 -50
  2. {textual_debugger-0.2.14/src/tdb → textual_debugger-0.2.16}/README.md +209 -48
  3. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/pyproject.toml +20 -4
  4. {textual_debugger-0.2.14 → textual_debugger-0.2.16/src/tdb}/README.md +209 -48
  5. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/__init__.py +1 -1
  6. textual_debugger-0.2.16/src/tdb/adapters/bash/arith_for.py +326 -0
  7. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/bash/session.py +34 -1
  8. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/bash/tdb_harness.sh +29 -3
  9. textual_debugger-0.2.16/src/tdb/adapters/native/gdb_stl_printers.py +740 -0
  10. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/padwalker.py +53 -1
  11. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/inspect.py +27 -11
  12. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app.py +55 -27
  13. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app_handlers/dap_events.py +18 -3
  14. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/breakpoint_hook.py +55 -10
  15. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/cli.py +86 -7
  16. textual_debugger-0.2.16/src/tdb/examples/C/breakpoint_hook_demo.c +26 -0
  17. textual_debugger-0.2.16/src/tdb/examples/C/pi_digits.c +102 -0
  18. textual_debugger-0.2.16/src/tdb/examples/C++/breakpoint_hook_demo.cpp +26 -0
  19. textual_debugger-0.2.16/src/tdb/examples/C++/pi_digits.cpp +77 -0
  20. textual_debugger-0.2.16/src/tdb/examples/Fortran/breakpoint_hook_demo.f90 +38 -0
  21. textual_debugger-0.2.16/src/tdb/examples/Fortran/pi_digits.f90 +165 -0
  22. textual_debugger-0.2.16/src/tdb/examples/Go/breakpoint_hook_demo/go.mod +7 -0
  23. textual_debugger-0.2.16/src/tdb/examples/Go/breakpoint_hook_demo/main.go +32 -0
  24. textual_debugger-0.2.16/src/tdb/examples/Go/pi_digits.go +77 -0
  25. textual_debugger-0.2.16/src/tdb/examples/OCaml/breakpoint_hook_demo.ml +26 -0
  26. textual_debugger-0.2.16/src/tdb/examples/OCaml/pi_digits.ml +66 -0
  27. textual_debugger-0.2.16/src/tdb/examples/Perl/breakpoint_hook_demo.pl +20 -0
  28. textual_debugger-0.2.16/src/tdb/examples/Perl/pi_digits.pl +42 -0
  29. textual_debugger-0.2.16/src/tdb/examples/PowerShell/pi_digits.ps1 +50 -0
  30. textual_debugger-0.2.16/src/tdb/examples/Python/pi_digits.py +138 -0
  31. textual_debugger-0.2.16/src/tdb/examples/Ruby/breakpoint_hook_demo.rb +17 -0
  32. textual_debugger-0.2.16/src/tdb/examples/Ruby/pi_digits.rb +61 -0
  33. textual_debugger-0.2.16/src/tdb/examples/Rust/breakpoint_hook_demo/Cargo.toml +9 -0
  34. textual_debugger-0.2.16/src/tdb/examples/Rust/breakpoint_hook_demo/src/main.rs +22 -0
  35. textual_debugger-0.2.16/src/tdb/examples/Rust/pi_digits.rs +69 -0
  36. textual_debugger-0.2.16/src/tdb/examples/bash/pi_digits.sh +60 -0
  37. textual_debugger-0.2.16/src/tdb/examples/tcsh/pi_digits.tcsh +95 -0
  38. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/info.py +83 -2
  39. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/base.py +7 -0
  40. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/cpp.py +32 -5
  41. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/native_tools.py +36 -0
  42. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/python.py +12 -0
  43. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/rust.py +2 -14
  44. textual_debugger-0.2.16/src/tdb/mcp/__init__.py +45 -0
  45. textual_debugger-0.2.16/src/tdb/mcp/__main__.py +6 -0
  46. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/persist.py +31 -0
  47. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/post_mortem.py +42 -10
  48. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/run_mode.py +19 -2
  49. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/console_view.py +3 -0
  50. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/evaluate_console.py +7 -1
  51. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/variable_view.py +29 -23
  52. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/textual_debugger.egg-info/PKG-INFO +213 -50
  53. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/textual_debugger.egg-info/SOURCES.txt +24 -0
  54. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/textual_debugger.egg-info/entry_points.txt +1 -1
  55. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/textual_debugger.egg-info/requires.txt +4 -1
  56. textual_debugger-0.2.14/src/tdb/mcp/__init__.py +0 -10
  57. textual_debugger-0.2.14/src/tdb/mcp/__main__.py +0 -6
  58. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/LICENSE +0 -0
  59. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/setup.cfg +0 -0
  60. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/__main__.py +0 -0
  61. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/_timeouts.py +0 -0
  62. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/__init__.py +0 -0
  63. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/bash/__init__.py +0 -0
  64. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/bash/__main__.py +0 -0
  65. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/bash/declares.py +0 -0
  66. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/bash/server.py +0 -0
  67. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/native/__init__.py +0 -0
  68. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/native/tdb.h +0 -0
  69. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/ocaml/__init__.py +0 -0
  70. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/ocaml/lldb_formatters.py +0 -0
  71. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/Devel/TdbCompile.pm +0 -0
  72. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/Devel/TdbRemote.pm +0 -0
  73. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/__init__.py +0 -0
  74. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/__main__.py +0 -0
  75. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/helpers.pl +0 -0
  76. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/padwalker_src/Makefile.PL +0 -0
  77. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/padwalker_src/PadWalker.pm +0 -0
  78. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/padwalker_src/PadWalker.xs +0 -0
  79. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/protocol.py +0 -0
  80. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/refs.py +0 -0
  81. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/server.py +0 -0
  82. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/perl/session.py +0 -0
  83. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/powershell/__init__.py +0 -0
  84. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/powershell/__main__.py +0 -0
  85. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/powershell/locate.py +0 -0
  86. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/powershell/output.py +0 -0
  87. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/powershell/server.py +0 -0
  88. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/powershell/tdb_launch.ps1 +0 -0
  89. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/ruby/__init__.py +0 -0
  90. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/ruby/__main__.py +0 -0
  91. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/ruby/server.py +0 -0
  92. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/ruby/tdb.rb +0 -0
  93. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/seqs.py +0 -0
  94. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/__init__.py +0 -0
  95. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/__main__.py +0 -0
  96. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/breakpoints.py +0 -0
  97. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/cli.py +0 -0
  98. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/guardian.py +0 -0
  99. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/instrumenter.py +0 -0
  100. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/models.py +0 -0
  101. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/protocol.py +0 -0
  102. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/runtime.py +0 -0
  103. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/scanner.py +0 -0
  104. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/server.py +0 -0
  105. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/session.py +0 -0
  106. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/adapters/tcsh/transport.py +0 -0
  107. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app_handlers/__init__.py +0 -0
  108. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app_handlers/inspection.py +0 -0
  109. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app_handlers/routing.py +0 -0
  110. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app_handlers/ui_panels.py +0 -0
  111. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/app_helpers.py +0 -0
  112. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/dap/__init__.py +0 -0
  113. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/dap/client.py +0 -0
  114. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/dap/messages.py +0 -0
  115. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/dap/protocol.py +0 -0
  116. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/dap/reverse.py +0 -0
  117. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/dap/types.py +0 -0
  118. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/eval_mode.py +0 -0
  119. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/examine.py +0 -0
  120. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/go_concurrency/__init__.py +0 -0
  121. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/go_concurrency/analyzer.py +0 -0
  122. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/go_concurrency/classifier.py +0 -0
  123. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/go_concurrency/collector.py +0 -0
  124. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/go_concurrency/models.py +0 -0
  125. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/inspection.py +0 -0
  126. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/inspection_full.py +0 -0
  127. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/keybindings/__init__.py +0 -0
  128. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/__init__.py +0 -0
  129. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/bash.py +0 -0
  130. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/errors.py +0 -0
  131. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/go.py +0 -0
  132. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/ocaml.py +0 -0
  133. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/perl.py +0 -0
  134. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/powershell.py +0 -0
  135. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/registry.py +0 -0
  136. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/ruby.py +0 -0
  137. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/languages/tcsh.py +0 -0
  138. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/mcp/server.py +0 -0
  139. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/mcp/session.py +0 -0
  140. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/processes_cache.py +0 -0
  141. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/replay.py +0 -0
  142. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/replay_tui.py +0 -0
  143. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/__init__.py +0 -0
  144. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/analyzer.py +0 -0
  145. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/classifier.py +0 -0
  146. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/collector.py +0 -0
  147. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/models.py +0 -0
  148. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/probes/__init__.py +0 -0
  149. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/probes/base.py +0 -0
  150. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/probes/gdb.py +0 -0
  151. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/probes/gdb_script.py +0 -0
  152. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/probes/lldb.py +0 -0
  153. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/rust_concurrency/probes/lldb_script.py +0 -0
  154. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/server/__init__.py +0 -0
  155. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/server/app.py +0 -0
  156. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/server/event_handler.py +0 -0
  157. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/server/handlers.py +0 -0
  158. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/server/rpc_types.py +0 -0
  159. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/server/runner.py +0 -0
  160. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/__init__.py +0 -0
  161. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/breakpoint_sync.py +0 -0
  162. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/child_processes.py +0 -0
  163. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/controller.py +0 -0
  164. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/errors.py +0 -0
  165. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/event_bus.py +0 -0
  166. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/inspect_service.py +0 -0
  167. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/messages.py +0 -0
  168. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/post_mortem_loader.py +0 -0
  169. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/recorder.py +0 -0
  170. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/state.py +0 -0
  171. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/statement_stepper.py +0 -0
  172. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/terminal.py +0 -0
  173. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/session/textual_handler.py +0 -0
  174. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/source_analysis.py +0 -0
  175. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/source_edit.py +0 -0
  176. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/__init__.py +0 -0
  177. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/_inspection_modal.py +0 -0
  178. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/async_tasks_modal.py +0 -0
  179. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/breakpoint_view.py +0 -0
  180. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/code_editor.py +0 -0
  181. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/code_view.py +0 -0
  182. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/full_contents_modal.py +0 -0
  183. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/goroutines_modal.py +0 -0
  184. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/menu_bar.py +0 -0
  185. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/modals.py +0 -0
  186. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/processes_modal.py +0 -0
  187. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/rust_concurrency_modal.py +0 -0
  188. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/stack_view.py +0 -0
  189. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/status_bar.py +0 -0
  190. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/tdb/widgets/threads_modal.py +0 -0
  191. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/textual_debugger.egg-info/dependency_links.txt +0 -0
  192. {textual_debugger-0.2.14 → textual_debugger-0.2.16}/src/textual_debugger.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: textual-debugger
3
- Version: 0.2.14
3
+ Version: 0.2.16
4
4
  Summary: A TUI debugger for Python, Perl, and other languages. Based on textual.
5
5
  Author-email: Al Danial <al.danial@gmail.com>
6
6
  License: textual-debugger is licensed to you under the MIT/X Consortium license:
@@ -53,10 +53,12 @@ Requires-Dist: debugpy>=1.8.12
53
53
  Requires-Dist: pygments>=2.17.0
54
54
  Requires-Dist: fastapi>=0.115.0
55
55
  Requires-Dist: uvicorn>=0.30.0
56
- Requires-Dist: mcp<3.0.0,>=2.0.0
57
56
  Provides-Extra: edit
58
57
  Requires-Dist: textual[syntax]>=8.0.0; extra == "edit"
58
+ Provides-Extra: mcp
59
+ Requires-Dist: mcp<3.0.0,>=2.0.0; extra == "mcp"
59
60
  Provides-Extra: dev
61
+ Requires-Dist: textual-debugger[mcp]; extra == "dev"
60
62
  Requires-Dist: pytest; extra == "dev"
61
63
  Requires-Dist: pytest-cov; extra == "dev"
62
64
  Requires-Dist: pytest-asyncio; extra == "dev"
@@ -74,7 +76,7 @@ Dynamic: license-file
74
76
  a full-featured terminal-based debugger for Python and other languages
75
77
  with a Debug Adapter Protocol (DAP) implementation. In addition to Python,
76
78
  `tdb` comes with built-in support for
77
- - C and C++ (via `gdb` or `lldb-dap`)
79
+ - C, C++, Fortran (via `gdb` or `lldb-dap`)
78
80
  - Rust (via `gdb` or `lldb-dap`, selected explicitly)
79
81
  - Perl (via `perl -d`)
80
82
  - Bash (via bash's own `DEBUG` trap; bash ≥ 4.4)
@@ -100,12 +102,12 @@ MIT License. Copyright 2026 by Al Danial.
100
102
  `tdb`:
101
103
 
102
104
  - debugs multiple languages through the Debug Adapter Protocol: Python (via `debugpy`,
103
- the richest feature set), C/C++ (via `gdb -i dap` or `lldb-dap`), Rust (via `gdb` or
104
- `lldb-dap`), Perl (via `perl -d`),
105
- Bash (via bash's own `DEBUG` trap), Tcsh (via source instrumentation of a
106
- stock `tcsh`), Ruby (via the debug gem's `rdbg`), OCaml (native via
107
- `lldb-dap`/`gdb`, bytecode via ocamlearlybird), Go (via Delve's `dlv
108
- dap`), and PowerShell 7 (via PowerShell Editor Services). Most languages are
105
+ the richest feature set); C/C++ and Fortran (via `gdb -i dap` or `lldb-dap`); Rust (via `gdb` or
106
+ `lldb-dap`); Perl (via `perl -d`);
107
+ Bash (via bash's own `DEBUG` trap); Tcsh (via source instrumentation of a
108
+ stock `tcsh`); Ruby (via the debug gem's `rdbg`); OCaml (native via
109
+ `lldb-dap`/`gdb`, bytecode via ocamlearlybird); Go (via Delve's `dlv
110
+ dap`); and PowerShell 7 (via PowerShell Editor Services). Most languages are
109
111
  auto-detected from the target; Rust intentionally requires `--lang rust`
110
112
  (ref. [Multi-Language Debugging](#multi-language-debugging)).
111
113
 
@@ -128,7 +130,7 @@ built with `textual`, `prompt-toolkit`, `urwid`, `curses`, `rich`, and so on
128
130
  to have `tdb` pop open automatically at the first uncaught exception, and a live
129
131
  breakpoint hook (`tdb.breakpoint()` in Python, `Devel::TdbRemote::breakpoint()`
130
132
  in Perl, `Tdb.breakpoint` in Ruby, `tdb.Breakpoint()` in Go, `tdb_breakpoint()`
131
- in C/C++, `tdb::breakpoint()` in Rust, `Tdb.breakpoint ()` in OCaml) that opens
133
+ in C/C++ and Fortran, `tdb::breakpoint()` in Rust, `Tdb.breakpoint ()` in OCaml) that opens
132
134
  `tdb` paused at a line of your choosing
133
135
 
134
136
  - can be entirely keyboard-driven
@@ -167,6 +169,14 @@ or run it without installing:
167
169
  uvx --from textual-debugger tdb my_program.py
168
170
  ```
169
171
 
172
+ The MCP server (`tdb-mcp`, `tdb --mcp`) is an optional extra because its
173
+ `mcp` dependency requires the `cryptography` package, which cannot be
174
+ installed on every platform. Add it with:
175
+
176
+ ```bash
177
+ pip install "textual-debugger[mcp]"
178
+ ```
179
+
170
180
 
171
181
  ## Quick Start
172
182
 
@@ -177,9 +187,21 @@ tdb --doc
177
187
  # show the Help > About text, where tdb and its config, breakpoints and
178
188
  # log files live, and the path + version of each interpreter and native
179
189
  # debugger it would use (python, gdb, lldb-dap, perl, ruby, dlv,
180
- # ocamlearlybird, bash, tcsh, pwsh)
190
+ # ocamlearlybird, bash, tcsh, pwsh), whether gdb has its DAP interpreter
191
+ # (`gdb -i dap`), whether perl has ExtUtils::MakeMaker (needed to
192
+ # build the bundled PadWalker), and the `examples dir` holding the
193
+ # per-language examples (C, C++, Fortran, Go, OCaml, Perl, PowerShell,
194
+ # Python, Ruby, Rust, bash, tcsh) installed with the package
181
195
  tdb --info
182
196
 
197
+ # reset config.json to defaults (the old file is kept as
198
+ # config.json-YYYY-mm-DD-HH:MM:SS; HH.MM.SS on Windows)
199
+ tdb --config write-default
200
+
201
+ # build and cache the bundled PadWalker Perl module now rather than
202
+ # on the first Perl launch
203
+ tdb --config install-padwalker
204
+
183
205
  # debug a Python program (stops at first line by default)
184
206
  tdb my_program.py
185
207
 
@@ -258,7 +280,7 @@ languages are supported out of the box:
258
280
  | Language | Adapter(s) | Dependencies | Feature level |
259
281
  |----------|------------|------------------------|---------------|
260
282
  | Python | `debugpy` (default) | Python ≥ 3.11 | everything in this README |
261
- | C / C++ (any native binary) | `gdb` (default), `lldb-dap` (alternate) | `gdb -i dap` requires GDB ≥ 14 built with Python (RHEL 8/9: `dnf install gcc-toolset-14-gdb`, see [C/C++ tips](#cc-tips)); `lldb-dap` ships with LLVM ≥ 17 (e.g. `apt install lldb`) | core debugging: breakpoints, stepping, stack, variables, evaluate console + remote attach (gdbserver/lldb-server, local symbol-bearing executable required) |
283
+ | C / C++ / Fortran (any native binary) | `gdb` (default), `lldb-dap` (alternate) | `gdb -i dap` requires GDB ≥ 14 built with Python (RHEL 8/9: `dnf install gcc-toolset-14-gdb`, see [C/C++/Fortran tips](#cc-tips)); `lldb-dap` ships with LLVM ≥ 17 (e.g. `apt install lldb`) | core debugging: breakpoints, stepping, stack, variables, evaluate console + remote attach (gdbserver/lldb-server, local symbol-bearing executable required) |
262
284
  | Rust (explicit `--lang rust`) | `gdb` (Linux default), `lldb-dap` (macOS default) | any rustc building with debug info; GDB ≥ 14 or LLVM `lldb-dap` ≥ 17 (concurrency ownership evidence additionally requires stable Rust 1.98) | core debugging + best-effort Rust concurrency inspection + remote attach |
263
285
  | Perl | perl-tdb (bundled) | perl ≥ 5.18 on PATH | core debugging + remote attach |
264
286
  | Bash | bash-tdb (bundled) | bash ≥ 4.4 on PATH | core debugging (no remote attach) |
@@ -279,7 +301,7 @@ The language is auto-detected from the debug target:
279
301
  `.sh` / `.bash` → Bash; `.csh` / `.tcsh` → Tcsh; `.rb` → Ruby; `.ps1` /
280
302
  `.psm1` → PowerShell. (`.ml` / `.mli` do *not* auto-select OCaml, see
281
303
  point 6.)
282
- 3. Native executables (ELF, Mach-O, PE magic bytes) → C/C++, unless
304
+ 3. Native executables (ELF, Mach-O, PE magic bytes) → C/C++/Fortran, unless
283
305
  byte-checking finds an OCaml marker (a native binary's
284
306
  `caml_program`/`caml_startup` runtime symbols, a bytecode file's
285
307
  trailing `Caml1999` marker, or a `#!...ocamlrun` shebang) → OCaml
@@ -287,13 +309,13 @@ The language is auto-detected from the debug target:
287
309
  `go version` itself locates, scanned in the first 16MB of the file) →
288
310
  Go. A stripped native OCaml binary, or a Go binary whose buildinfo
289
311
  blob sits beyond the 16MB scan window, that byte-checking can't
290
- identify falls back to C/C++; force it with `--lang ocaml` or `--lang
312
+ identify falls back to C/C++/Fortran; force it with `--lang ocaml` or `--lang
291
313
  go` respectively. Rust is never inferred from an executable; select it
292
314
  explicitly with `--lang rust`.
293
315
  4. A `#!...python`, `#!...perl`, `#!...bash`, `#!...csh`/`#!...tcsh`,
294
316
  `#!...ruby`, or `#!...pwsh` shebang → Python / Perl / Bash / Tcsh / Ruby /
295
317
  PowerShell respectively.
296
- 5. C/C++/Rust *source* files (`.c`, `.cpp`, `.rs`, …) produce an error with a
318
+ 5. C/C++/Fortran/Rust *source* files (`.c`, `.cpp`, `.rs`, …) produce an error with a
297
319
  hint: compile with debug info (`g++ -g -O0`) and debug the binary.
298
320
  6. `.ml` / `.mli` (OCaml source) produce an error too: build the project
299
321
  first (dune's dev profile keeps debug info) and pass the **built
@@ -320,7 +342,7 @@ message naming its path and version; when that `gdb` came from `PATH`
320
342
  (not from `--adapter` or `config.json`), `tdb` first looks for a newer one
321
343
  installed by Red Hat's Software Collections
322
344
  (`/opt/rh/gcc-toolset-*/root/usr/bin/gdb`, `/opt/rh/devtoolset-*/...`) and
323
- uses the newest that qualifies. See [C/C++ tips](#cc-tips) for RHEL 8.
345
+ uses the newest that qualifies. See [C/C++/Fortran tips](#cc-tips) for RHEL 8.
324
346
 
325
347
  > **Migration note:** extensionless Python scripts without a `python` shebang
326
348
  > were previously assumed to be Python; they now require `--lang python`.
@@ -358,16 +380,16 @@ programs by nature). Remote attach (`-r`) also works for Perl (see
358
380
  [Perl](#perl), `Devel::TdbRemote` in place of `debugpy.listen()`), Ruby
359
381
  (see [Ruby](#ruby), `rdbg --open` in place of `debugpy.listen()`), Go (see
360
382
  [Go](#go), `dlv dap --listen` in place of `debugpy.listen()`), and for
361
- Rust and C/C++ native binaries (against a gdbserver/lldb-server stub, with
383
+ Rust and C/C++/Fortran native binaries (against a gdbserver/lldb-server stub, with
362
384
  a local symbol-bearing executable; see [Rust](#rust) — the same flags work
363
- for a C/C++ target without `--lang`), but not for Bash, Tcsh, OCaml, or
385
+ for a C/C++/Fortran target without `--lang`), but not for Bash, Tcsh, OCaml, or
364
386
  PowerShell. `--terminal` works for every launch-mode
365
- language — Python, Perl, Bash, Tcsh, Ruby, and C/C++, OCaml native, or Rust
387
+ language — Python, Perl, Bash, Tcsh, Ruby, and C/C++/Fortran, OCaml native, or Rust
366
388
  sessions via `--adapter lldb-dap` — see
367
389
  [External Terminal Support](#external-terminal-support). Go and PowerShell do
368
390
  not support `--terminal` yet (`dlv dap` and PSES have no terminal-routing
369
391
  mode). Typing into the Console view to feed the program's stdin works for
370
- Python, Perl, Bash, Tcsh, Ruby, and PowerShell, but not for C/C++, Rust,
392
+ Python, Perl, Bash, Tcsh, Ruby, and PowerShell, but not for C/C++/Fortran, Rust,
371
393
  OCaml, or Go, whose adapters spawn the debuggee themselves — see
372
394
  [Console Output and Input](#console-output-and-input).
373
395
 
@@ -458,14 +480,14 @@ picture:
458
480
  multiprocessing child attach.
459
481
  - Detection of a Go binary via buildinfo check scans only the first
460
482
  16MB of the file; a huge binary whose buildinfo blob sits beyond that
461
- falls back to C/C++ — force it with `--lang go`.
483
+ falls back to C/C++/Fortran — force it with `--lang go`.
462
484
  - `-a`/`--attach`'s language auto-detection (reading the target pid's
463
485
  buildinfo from `/proc/PID/exe`) is Linux-only; on macOS/Windows pass
464
486
  `--lang go` alongside `-a`.
465
487
 
466
488
  See [Go](#go) below for launch details.
467
489
 
468
- ### C/C++ tips
490
+ ### C/C++/Fortran tips
469
491
 
470
492
  - Compile with `-g` (ideally `-g -O0` or `-g3 -O0`).
471
493
  If no breakpoint in a file can be
@@ -485,6 +507,29 @@ See [Go](#go) below for launch details.
485
507
  - GDB (the default adapter) has the most complete libstdc++
486
508
  pretty-printing. `lldb-dap` (via `--adapter lldb-dap`) also debugs
487
509
  GCC-built binaries fine. DWARF is compiler-neutral.
510
+ - **STL containers in the Variables view.** A distro `gdb` shows
511
+ `std::vector<Result>` as `std::vector of length 2, capacity 2` with
512
+ `[0]`, `[1]` children because gcc installs libstdc++'s pretty-printers
513
+ next to it and `gdb` auto-loads them. A `gdb` built from source into
514
+ its own prefix never finds that auto-load script and shows the same
515
+ variable as `_M_impl` / `_M_start` pointer soup. `tdb` sources a small
516
+ helper into every `gdb` session that, on the first `std::` value it
517
+ sees, looks for gcc's printers (the distro auto-load script for the
518
+ loaded `libstdc++.so`, `share/gcc*/python` near that library or near
519
+ gdb's data directory, then the usual distro, Red Hat toolset, Homebrew
520
+ and MacPorts locations) and uses them; when none are installed it
521
+ falls back to its own bundled printers for `std::string`, `vector`,
522
+ `deque`, `list`, `map`/`set` (and multi-), `unordered_map`/`set`,
523
+ `unique_ptr`, `shared_ptr`/`weak_ptr` and `optional`. Printers gdb
524
+ auto-loads itself or that your `.gdbinit` registers still take
525
+ precedence. The helper also shields gdb's DAP layer from gcc 15's map
526
+ and set printers, whose child count is broken there (expanding a
527
+ `std::map` fails with "name 'self' is not defined" on an unpatched
528
+ distro gdb). `TDB_GDB_STL_PRINTERS` tunes it: `off` registers nothing,
529
+ `bundled` forces the bundled printers (and drops gdb's auto-loaded
530
+ ones), a directory holding `libstdcxx/` names gcc's printers
531
+ explicitly. Type `tdb-stl-printers` in the evaluate console to see
532
+ which printers are in use.
488
533
  - **GDB evaluate-console quirk:** GDB's DAP treats REPL input as CLI
489
534
  commands, so evaluate expressions with an explicit `print`, e.g.
490
535
  `print x` rather than bare `x` (bare `x` collides with GDB's
@@ -501,7 +546,8 @@ See [Go](#go) below for launch details.
501
546
  from the evaluate console without you having typed `list`.
502
547
  - **RHEL 8 (and 9) gdb is too old for DAP:** the stock `/usr/bin/gdb` is
503
548
  8.2 on RHEL 8 (10.2 on RHEL 9) and answers `gdb -i dap` with
504
- ``Interpreter `dap' unrecognized``. Install a newer one from the
549
+ ``Interpreter `dap' unrecognized``. Install a newer one
550
+ (minimum GCC Toolset version is 14) from the
505
551
  GCC Toolset, which leaves `/usr/bin/gdb` alone:
506
552
 
507
553
  ```bash
@@ -517,19 +563,22 @@ See [Go](#go) below for launch details.
517
563
  wrote the file). Either delete the entry or point it at the toolset
518
564
  gdb. A GDB ≥ 14 that was built without Python support gives the same
519
565
  ``Interpreter `dap' unrecognized`` error (`gdb --configuration` shows
520
- `--without-python`); use `--adapter lldb-dap` or a gdb built with
566
+ `--without-python`); `tdb --info` probes for this and reports
567
+ `GDB LACKS DAP CAPABILITY AND CANNOT BE USED` in its `DAP interpreter`
568
+ row when the gdb it found rejects `-i dap`. Use `--adapter lldb-dap`
569
+ or a gdb built with
521
570
  Python.
522
571
 
523
572
  **Attach to a running process:** `tdb -a PID` attaches gdb (or `--adapter
524
573
  lldb-dap`) to a live native process and stops it. On Linux tdb reads
525
574
  `/proc/PID/exe` to identify the language (Go, OCaml, Rust, otherwise
526
- C/C++) and to load symbols; pass the executable path as well to use a
575
+ C/C++/Fortran) and to load symbols; pass the executable path as well to use a
527
576
  different symbol file, and pass `--lang` off Linux. `--no-pause-on-attach`
528
577
  leaves the process running, for a program about to stop itself. An
529
- interpreter process (python3, perl, ruby, bash) is attached as C/C++; for
578
+ interpreter process (python3, perl, ruby, bash) is attached as C/C++/Fortran; for
530
579
  Python, Perl, and Ruby programs use `--remote-attach` instead.
531
580
 
532
- **Live breakpoint hook:** the C/C++ counterpart of Python's
581
+ **Live breakpoint hook:** the C/C++/Fortran counterpart of Python's
533
582
  [`tdb.breakpoint()`](#live-breakpoint-hook). Include `tdb.h` (its directory
534
583
  is the `tdb.h dir` row of `tdb --info`) and call `tdb_breakpoint()`:
535
584
 
@@ -567,6 +616,29 @@ header-only. Linux only: the hook grants ptrace access to tdb's debugger
567
616
  with `PR_SET_PTRACER`; elsewhere it warns once and returns. See
568
617
  `examples/C/breakpoint_hook_demo.c` and `examples/C++/breakpoint_hook_demo.cpp`.
569
618
 
619
+ Fortran (or any language that can call C) uses the same header: compile
620
+ `tdb.h` as C into an object that defines `tdb_breakpoint()`, declare it with
621
+ `bind(C)`, and link the object in:
622
+
623
+ ```fortran
624
+ interface
625
+ subroutine tdb_breakpoint() bind(C, name="tdb_breakpoint")
626
+ end subroutine tdb_breakpoint
627
+ end interface
628
+ ...
629
+ call tdb_breakpoint() ! tdb opens here, paused on the next line
630
+ ```
631
+
632
+ ```bash
633
+ gcc -g -O0 -c -x c "$(tdb --info | awk -F': ' '/tdb.h dir/ {print $2}')/tdb.h" -o tdb.o
634
+ gfortran -g -O0 -o prog prog.f90 tdb.o
635
+ ./prog # run it directly, not under tdb
636
+ ```
637
+
638
+ Use gdb (the default) for Fortran: lldb-dap stops on the right line but,
639
+ lacking Fortran support, shows no Fortran locals. See
640
+ `examples/Fortran/breakpoint_hook_demo.f90`.
641
+
570
642
  ### Rust
571
643
 
572
644
  Rust debugging is intentionally explicit: build a normal debug executable,
@@ -587,7 +659,7 @@ cargo rustc -- -C debuginfo=2 -C opt-level=0
587
659
  # Equivalent direct rustc settings: rustc -C debuginfo=2 -C opt-level=0 src/main.rs
588
660
  ```
589
661
 
590
- As for C/C++, the Console view cannot feed the program's stdin (the gdb and
662
+ As for C/C++/Fortran, the Console view cannot feed the program's stdin (the gdb and
591
663
  lldb adapters spawn it themselves); use `--terminal` with `--adapter
592
664
  lldb-dap` for interactive programs. A panic that terminates the debuggee opens the error modal with the parsed
593
665
  panic message and backtrace; `tdb` injects `RUST_BACKTRACE=1` into launched
@@ -624,7 +696,7 @@ for example `ssh -L 2345:127.0.0.1:2345 host`, then attach to `127.0.0.1:2345`.
624
696
  `--adapter lldb-dap`) to a live Rust process and stops it; tdb loads
625
697
  symbols from `/proc/PID/exe`, or from an executable path you pass as well.
626
698
  Without `--lang`, tdb recognizes a non-stripped Rust binary by its runtime
627
- symbols; a stripped one is debugged as C/C++.
699
+ symbols; a stripped one is debugged as C/C++/Fortran.
628
700
 
629
701
  **Live breakpoint hook:** the Rust counterpart of Python's
630
702
  [`tdb.breakpoint()`](#live-breakpoint-hook). Depend on the `tdb` crate from
@@ -696,12 +768,20 @@ per interpreter under its config directory (`~/.config/tdb/padwalker/` on
696
768
  Linux/macOS, `%APPDATA%\\tdb\\padwalker\\` on Windows), and prepends that
697
769
  directory to the debuggee's `PERL5LIB`. The build takes about a second and
698
770
  needs perl's headers (`libperl-dev` on Debian/Ubuntu, `perl-devel` on
699
- Fedora/RHEL) plus a C compiler; Strawberry Perl on Windows ships both. When
700
- the build is not possible, `tdb` prints a one-line notice on the console and
701
- falls back to a read-only pad walk, so outer-frame lexicals degrade but
702
- debugging otherwise proceeds. `tdb --info` reports the source directory, the
703
- cache directory, and whether a build exists for the `perl` on your `PATH`.
771
+ Fedora/RHEL), a C compiler, and the core `ExtUtils::MakeMaker` module (some
772
+ minimal distro perls omit it; `perl-ExtUtils-MakeMaker` on Fedora/RHEL);
773
+ Strawberry Perl on Windows ships all three. When the build is not possible,
774
+ `tdb` prints a one-line notice on the console and falls back to a read-only
775
+ pad walk, so outer-frame lexicals degrade but debugging otherwise proceeds.
776
+ `tdb --info` reports the source directory, the cache directory, and the
777
+ `ExtUtils::MakeMaker` version of the `perl` it would use, with a warning when
778
+ that module is missing and PadWalker therefore cannot be built.
704
779
  `TDB_PADWALKER_CACHE` overrides the cache location.
780
+ To build it ahead of time (for example when provisioning a machine, or to
781
+ see the compiler's error output without starting a debug session), run
782
+ `tdb --config install-padwalker`; it exits 0 when PadWalker loads
783
+ (natively, from the cache, or freshly built) and 1 with the reason when it
784
+ cannot be built.
705
785
 
706
786
  **Launching a script:**
707
787
 
@@ -1001,7 +1081,7 @@ tihs line correctly.
1001
1081
  usual behavior.
1002
1082
 
1003
1083
  A stripped native binary that byte-checking can't identify as OCaml falls
1004
- back to C/C++; force it with `--lang ocaml`. Override the adapter or point
1084
+ back to C/C++/Fortran; force it with `--lang ocaml`. Override the adapter or point
1005
1085
  at a non-`PATH` install in `config.json` (see
1006
1086
  [Configuration](#configuration)):
1007
1087
 
@@ -1131,7 +1211,7 @@ tdb -r host:port --lang go # attach to a `dlv dap --listen` already running remo
1131
1211
 
1132
1212
  `tdb --test ./pkg` debugs the package's tests under Delve's `test` mode;
1133
1213
  pass test-binary flags after `--`, e.g. `tdb --test ./pkg -- -run TestFoo`.
1134
- `-a`/`--attach` works for Go and, through gdb/lldb-dap, for C/C++, Rust,
1214
+ `-a`/`--attach` works for Go and, through gdb/lldb-dap, for C/C++/Fortran, Rust,
1135
1215
  and OCaml; on Linux `tdb` identifies the language from `/proc/PID/exe`
1136
1216
  without `--lang` (elsewhere pass `--lang go` alongside `-a`). Attaching
1137
1217
  stops the process immediately so you get control right away;
@@ -1330,6 +1410,13 @@ A cursor line (blue) tracks your position; the current execution line is highlig
1330
1410
  | `Ctrl+S` | Stack View |
1331
1411
  | `Ctrl+B` | Breakpoint View |
1332
1412
 
1413
+ Pressing the shortcut of the view that already has focus returns focus to
1414
+ the previous view, so e.g. `Ctrl+E` jumps from the Code View to the
1415
+ Evaluate Console and a second `Ctrl+E` jumps back.
1416
+ The shortcuts also work while typing in the Evaluate Console and the
1417
+ Console View's stdin line, where `Ctrl+E` and `Ctrl+V` take precedence over
1418
+ end-of-line and paste (`End` and the terminal's own paste still work).
1419
+
1333
1420
  **Menu-bar shortcuts (global):**
1334
1421
 
1335
1422
  `Alt+<first-letter>` opens the corresponding tab in the menu bar.
@@ -1507,7 +1594,7 @@ returns. Two ways to pin, two ways to unpin:
1507
1594
  | | Evaluate Console | Variables View |
1508
1595
  |---|---|---|
1509
1596
  | pin | `display b` | right-click the variable's row |
1510
- | unpin | `undisplay b` | left-click its row under **Display** |
1597
+ | unpin | `undisplay b` | right-click its row under **Display** |
1511
1598
 
1512
1599
  ```
1513
1600
  >>> display b
@@ -1523,6 +1610,8 @@ returns. Two ways to pin, two ways to unpin:
1523
1610
 
1524
1611
  Right-clicking a child of an expanded object pins the full path
1525
1612
  (`obj.count`, `items[2]`), and a bare `display` lists everything pinned.
1613
+ Left-click works the same under **Display** as in every other scope:
1614
+ it expands or collapses an object, and a double-click opens it in a modal.
1526
1615
  A click in the Variables View is recorded exactly as the typed command,
1527
1616
  so `--record`/`--replay` sessions reproduce it. Some terminals keep
1528
1617
  right-click for their own paste or context menu (Windows Terminal and
@@ -1588,8 +1677,8 @@ variable lives:
1588
1677
  | tcsh | `set name …`, `setenv NAME …` | the whole run |
1589
1678
  | Ruby | `name = …`, `$name = …`, `@name = …` | globals and instance variables persist; plain locals live only in the eval's binding and read back as unavailable after the next step |
1590
1679
  | PowerShell | `$name = …`, `$global:name = …` | the function scope, or the whole run for `$global:` |
1591
- | C/C++/Rust/OCaml under gdb | `set $name = …` (a gdb convenience variable) | the whole run |
1592
- | C/C++/Rust/OCaml under lldb-dap | `int $name = …` (an lldb persistent variable) | the whole run |
1680
+ | C/C++/Fortran/Rust/OCaml under gdb | `set $name = …` (a gdb convenience variable) | the whole run |
1681
+ | C/C++/Fortran/Rust/OCaml under lldb-dap | `int $name = …` (an lldb persistent variable) | the whole run |
1593
1682
  | Go (dlv), OCaml under ocamlearlybird | not possible: their evaluate cannot create variables | — |
1594
1683
 
1595
1684
  A tracked name that no longer resolves (a Python local after its frame
@@ -1619,7 +1708,7 @@ when the session has no stdin to feed.
1619
1708
 
1620
1709
  Stdin forwarding works for the languages whose program `tdb` launches on a
1621
1710
  pipe it owns: Python, Perl, Bash, Tcsh, Ruby, and PowerShell. It is not
1622
- available for the compiled languages — C/C++, Rust, OCaml, and Go — because
1711
+ available for the compiled languages — C/C++/Fortran, Rust, OCaml, and Go — because
1623
1712
  their adapters (`gdb -i dap`, `lldb-dap`, `dlv dap`) spawn the debuggee
1624
1713
  themselves and give `tdb` no handle on its stdin; the input line stays
1625
1714
  hidden there. It is also unavailable for remote attach (`-r`), where the
@@ -1744,12 +1833,57 @@ This behavior matches hitting `c` while in a conventional (that is, the Python
1744
1833
  standard library's) `breakpoint()` session.
1745
1834
  If you want to kill the program instead, use `Ctrl+c` in the terminal running the debuggee.
1746
1835
 
1747
- Perl, Ruby, Go, C/C++, Rust, and OCaml programs get the same hook as
1836
+ Perl, Ruby, Go, C/C++/Fortran, Rust, and OCaml programs get the same hook as
1748
1837
  `Devel::TdbRemote::breakpoint()`, `Tdb.breakpoint`, `tdb.Breakpoint()`,
1749
1838
  `tdb_breakpoint()`, `tdb::breakpoint()`, and `Tdb.breakpoint ()`; see
1750
- [Perl](#perl), [Ruby](#ruby), [Go](#go), [C/C++ tips](#cc-tips),
1839
+ [Perl](#perl), [Ruby](#ruby), [Go](#go), [C/C++/Fortran tips](#cc-tips),
1751
1840
  [Rust](#rust), and [OCaml](#ocaml).
1752
1841
 
1842
+ ### pytest Integration (`--pdbcls`)
1843
+
1844
+ `tdb` can stand in for `pdb` when `pytest` stops on a failing test, the
1845
+ same way IPython (`--pdbcls=IPython.terminal.debugger:Pdb`) and pudb
1846
+ (`--pdbcls=pudb.debugger:Debugger`) do:
1847
+
1848
+ ```bash
1849
+ pytest --pdb --pdbcls=tdb.pytest_debugger:Debugger
1850
+ ```
1851
+
1852
+ `-s` / `--capture=no` is not required; pytest suspends output capturing
1853
+ before handing control to the debugger. To make it the default, add the
1854
+ options to your pytest configuration:
1855
+
1856
+ ```toml
1857
+ [tool.pytest.ini_options]
1858
+ addopts = "--pdbcls=tdb.pytest_debugger:Debugger"
1859
+ ```
1860
+
1861
+ (`tdb.pytest_debugger:Pdb` is an alias for the same class.)
1862
+
1863
+ What you get depends on how pytest enters the debugger:
1864
+
1865
+ | pytest trigger | `tdb` behavior |
1866
+ |---|---|
1867
+ | `--pdb`, test fails or errors | Post-mortem TUI on the failing test, as with [`tdb.exception_hook`](#post-mortem-exception-hook). Navigate the stack and inspect every frame's variables at the point of failure. pytest's own runner frames are trimmed from the Stack View. Quit `tdb` (`q`, then `q` again to confirm) and pytest moves on to the next test. |
1868
+ | `breakpoint()` or `pytest.set_trace()` in a test | Live `tdb` attached to the pytest process, paused on the line after the call, as with [`tdb.breakpoint()`](#live-breakpoint-hook). Step, evaluate, set breakpoints, continue. |
1869
+ | `--trace` | Live `tdb` paused on the first line of each test. |
1870
+
1871
+ Notes:
1872
+
1873
+ - Post-mortem mode is a frozen snapshot: no Evaluate View, no stepping.
1874
+ For a live view of a failure, put a `breakpoint()` in the test (or use
1875
+ `--trace`) and `continue`. `tdb` stops on the failing line with the
1876
+ interpreter still alive.
1877
+ - One live `tdb` serves the whole pytest run. After `continue` it stays
1878
+ attached, showing **Running**, and the next `breakpoint()` or `--trace`
1879
+ stop appears in it. If a test fails under `--pdb` while it is still
1880
+ attached, the post-mortem view opens once you quit the live `tdb`.
1881
+ - Every failure opens its own post-mortem session. Combine with `-x` or
1882
+ `--maxfail=N` to limit how many you step through.
1883
+ - Live stops need `debugpy` installed in the environment running pytest.
1884
+ - When stdin/stdout aren't a terminal (CI, `pytest-xdist` workers), the
1885
+ class falls back to plain `pdb` behavior.
1886
+
1753
1887
  ### Async Task Inspector
1754
1888
 
1755
1889
  For programs using `asyncio`, the menu bar shows an **Async Tasks (N)** label with the count of
@@ -1924,8 +2058,8 @@ tdb --terminal xterm my_tui_app.py
1924
2058
  ```
1925
2059
 
1926
2060
  `--terminal` works for every language `tdb` can *launch* (as opposed to
1927
- attach to): Python, Perl, Bash, Tcsh, Ruby, and C/C++ or native OCaml
1928
- sessions via `--adapter lldb-dap`. Neither `gdb -i dap` (the default C/C++
2061
+ attach to): Python, Perl, Bash, Tcsh, Ruby, and C/C++/Fortran or native OCaml
2062
+ sessions via `--adapter lldb-dap`. Neither `gdb -i dap` (the default C/C++/Fortran
1929
2063
  adapter, and an alternate for native OCaml) nor `ocamlearlybird` (the
1930
2064
  bytecode OCaml adapter) has any terminal integration -- `tdb` rejects
1931
2065
  `--terminal` up front for both, with an error pointing at `--adapter
@@ -2033,7 +2167,7 @@ nonzero `sys.exit()`, which `debugpy` treats as an uncaught `SystemExit` -- `tdb
2033
2167
  the TUI at the point of failure instead of exiting silently, so you can inspect the
2034
2168
  crash. Exit-code passthrough applies only to a clean exit during the headless phase.
2035
2169
 
2036
- Supported languages: Python, Perl, Bash, Tcsh, Ruby, PowerShell 7, C/C++
2170
+ Supported languages: Python, Perl, Bash, Tcsh, Ruby, PowerShell 7, C/C++/Fortran
2037
2171
  (both `gdb` and `lldb-dap`), and native OCaml (both `gdb` and `lldb-dap`;
2038
2172
  bytecode/`ocamlearlybird` sessions don't support pause, so `--run` is
2039
2173
  unavailable for those). `--run` is rejected up front for any other
@@ -2043,7 +2177,18 @@ language.
2043
2177
  blocking external call or syscall, the pause can't land until that call returns --
2044
2178
  `tdb` prints a notice and opens the TUI once the stop actually arrives.
2045
2179
 
2046
- **Incompatible flags:** `-r`, `-k`/`-t`, `--record`, `--replay`, `--replay-tui`, `--server`,
2180
+ **Breakpoints:** run mode never uses breakpoints saved in `breakpoints.json`, and
2181
+ never writes to it either, so the breakpoints you saved for normal sessions are left
2182
+ untouched. Breakpoints given on the command line with `-k`/`-t` are accepted, but they
2183
+ stay inactive while the program runs headlessly. They are installed the first time the
2184
+ TUI opens (normally when you press Ctrl-C), and stay live after you detach, so the
2185
+ program then stops at them:
2186
+
2187
+ ```bash
2188
+ tdb --run -k 120 -k utils.py:45 my_program.py # breakpoints arm on the first Ctrl-C
2189
+ ```
2190
+
2191
+ **Incompatible flags:** `-r`, `--record`, `--replay`, `--replay-tui`, `--server`,
2047
2192
  `--headless`, `--mcp`, `--terminal`.
2048
2193
 
2049
2194
  ### Eval Mode (`-e`/`--eval`)
@@ -2085,7 +2230,7 @@ evaluated in each child process that reaches it.
2085
2230
  uncaught-exception stop) is continued untouched, so the program runs to
2086
2231
  completion unattended.
2087
2232
  - For non-Python debuggees the expression must be in the debug adapter's
2088
- own syntax, for example gdb's `print x` / `set var x=3` for C/C++, and not
2233
+ own syntax, for example gdb's `print x` / `set var x=3` for C/C++/Fortran, and not
2089
2234
  necessarily the debuggee's language. The adapter may bind the breakpoint
2090
2235
  to the next executable line (gdb moves one off a declaration or brace);
2091
2236
  the eval point matches that bound line, so the expression still runs.
@@ -2272,6 +2417,16 @@ its companion `examples/sales_report_buggy.py`.
2272
2417
 
2273
2418
  ### Running the MCP server
2274
2419
 
2420
+ The MCP server needs the optional `mcp` extra:
2421
+
2422
+ ```bash
2423
+ pip install "textual-debugger[mcp]"
2424
+ ```
2425
+
2426
+ Without it, `tdb-mcp` and `tdb --mcp` exit with that install hint, and
2427
+ `tdb --info` reports `MCP server : not installed`. Everything else in
2428
+ tdb works without the extra.
2429
+
2275
2430
  Configure your MCP client (Claude Desktop, an IDE extension, etc.) to
2276
2431
  launch `tdb-mcp` over stdio. Example `claude_desktop_config.json`:
2277
2432
 
@@ -2357,13 +2512,14 @@ usage: tdb [-h] [-v] [-r [HOST:]PORT] [--cwd CWD] [--no-stop-on-entry]
2357
2512
  [--terminal {xterm,konsole,gnome-terminal,ghostty,kitty,iterm2,warp,wezterm,terminator}]
2358
2513
  [--local-root PATH] [--remote-root PATH]
2359
2514
  [--server] [--headless] [-k FILE:LINE|LINE] [--server-port SERVER_PORT] [-d] [--doc-text] [--info]
2515
+ [--config {write-default,install-padwalker}]
2360
2516
  [program] [args ...]
2361
2517
  ```
2362
2518
 
2363
2519
  | Flag | Description |
2364
2520
  |------|-------------|
2365
2521
  | `-r HOST:PORT` | Attach to a remote debugpy server |
2366
- | `-a`, `--attach PID` | Attach to a running local process by pid: Go (Delve) or a native C/C++, Rust, or OCaml program (gdb or lldb-dap). Linux identifies the language from `/proc/PID/exe`; elsewhere pass `--lang` and, for native programs, the executable path. |
2522
+ | `-a`, `--attach PID` | Attach to a running local process by pid: Go (Delve) or a native C/C++, Fortran, Rust, or OCaml program (gdb or lldb-dap). Linux identifies the language from `/proc/PID/exe`; elsewhere pass `--lang` and, for native programs, the executable path. |
2367
2523
  | `--local-root PATH` | Local directory containing a copy of remote code (repeat to mirror multiple trees). Pair with `--remote-root`; counts must match. Required when `-k` sets a breakpoint against a remote debuggee whose code lives at a different path. |
2368
2524
  | `--remote-root PATH` | Remote directory matched to `--local-root` (same CLI position via `zip()`). |
2369
2525
  | `-k`, `--breakpoint FILE:LINE|LINE` | Set a breakpoint (may be repeated). Passing `-k` implies `--no-stop-on-entry` so the program runs straight to the first breakpoint. |
@@ -2392,6 +2548,11 @@ usage: tdb [-h] [-v] [-r [HOST:]PORT] [--cwd CWD] [--no-stop-on-entry]
2392
2548
  | `--replay-interval S` | With `--replay`/`--replay-tui`: fixed S-second delay before each action instead of the recorded gaps |
2393
2549
  | `--replay-timeout S` | With `--replay`/`--replay-tui`: per-action stop-wait timeout (default 30) |
2394
2550
  | `--examine-log DEST` | With --run: write each Ctrl-\ / SIGUSR2 stack snapshot to DEST (- = stdout; repeatable) |
2551
+ | `--doc` | Display this README in a terminal Markdown viewer and exit |
2552
+ | `--doc-text` | Print this README to stdout as wrapped plain text and exit |
2553
+ | `--info` | Print the About text, file locations, and the path and version of each interpreter and debugger `tdb` would use, then exit |
2554
+ | `--config write-default` | Rename the existing `config.json` to `config.json-YYYY-mm-DD-HH:MM:SS` (`HH.MM.SS` on Windows, which forbids colons in filenames) and write a new one holding every default value, then exit |
2555
+ | `--config install-padwalker` | Build and cache the bundled PadWalker Perl module now, for the perl `tdb` would debug with (`adapters.perl` in `config.json`, else `perl` on `PATH`), instead of waiting for the first Perl launch; exits 1 if it cannot be built |
2395
2556
 
2396
2557
  ## Configuration
2397
2558
 
@@ -2406,7 +2567,9 @@ On Windows, it uses `%APPDATA%\tdb\`.
2406
2567
 
2407
2568
  ### Sample `config.json`
2408
2569
 
2409
- Every key `tdb` reads, with its default or a representative value. Copy
2570
+ Every key `tdb` reads, with its default or a representative value.
2571
+ `tdb --config write-default` writes a fresh file with these defaults
2572
+ (moving the old one aside as `config.json-YYYY-mm-DD-HH:MM:SS`), or copy
2410
2573
  this to restore a deleted or corrupted file, then delete the entries you
2411
2574
  don't need: a missing key takes its default, an unknown key is ignored,
2412
2575
  and an invalid value (say a misspelled `step_mode`) falls back to the
@@ -2495,7 +2658,7 @@ fires as expected.
2495
2658
 
2496
2659
  - [textual](https://github.com/Textualize/textual) : TUI framework
2497
2660
  - [debugpy](https://github.com/microsoft/debugpy) : Debug Adapter Protocol implementation for Python
2498
- - [gdb](https://sourceware.org/gdb/) / [lldb-dap](https://lldb.llvm.org/resources/lldbdap.html) : optional, user-installed DAP adapters for C/C++
2661
+ - [gdb](https://sourceware.org/gdb/) / [lldb-dap](https://lldb.llvm.org/resources/lldbdap.html) : optional, user-installed DAP adapters for C/C++/Fortran
2499
2662
  - [debug gem](https://github.com/ruby/debug) (`rdbg`) : optional, user-installed DAP adapter for Ruby
2500
2663
  - [ocamlearlybird](https://github.com/hackwaly/ocamlearlybird) : optional, user-installed DAP adapter for OCaml bytecode (native OCaml reuses `gdb`/`lldb-dap`)
2501
2664
  - [pygments](https://pygments.org/) : Syntax highlighting