]> code.delx.au - gnu-emacs-elpa/blob - pdbtrack.el
Remove unnecessary rst require (was for filter)
[gnu-emacs-elpa] / pdbtrack.el
1 ;;; pdbtrack - Track source file lines as you run python/pdb in an emacs shell.
2
3 ;;; Standalone Python PDB dynamic file tracking.
4
5 (define-minor-mode pdbtrack-minor-mode
6 "Show lines in source file when Python PDB debugger steps through them."
7 nil ":PDBtrack" :require 'pdbtrack :version "2.1"
8
9 (add-hook 'comint-output-filter-functions
10 'pdbtrack-comint-output-filter-function)
11 (make-local-variable 'pdbtrack-buffers-to-kill)
12 (make-local-variable 'pdbtrack-tracked-buffer)
13 )
14
15 (defcustom pdbtrack-stacktrace-info-regexp
16 "> \\([^\"(<]+\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_<>]+\\)()"
17 "Regular Expression matching stacktrace information.
18 Used to extract the current line and module being inspected."
19 :type 'string
20 :group 'python
21 :safe 'stringp)
22
23 (defvar pdbtrack-tracked-buffer nil
24 "Variable containing the value of the current tracked buffer.
25 Never set this variable directly, use
26 `pdbtrack-set-tracked-buffer' instead.")
27
28 (defcustom pdbtrack-remove-new-buffers-after-tracking t
29 "Remove buffers visited for the sake of tracking, on pdb session conclusion."
30 :type 'boolean
31 :group 'python)
32 (defvar pdbtrack-buffers-to-kill nil
33 "List of buffers to be deleted after tracking finishes.")
34
35 (defun pdbtrack-set-tracked-buffer (file-name)
36 "Set the buffer for FILE-NAME as the tracked buffer.
37 Internally it uses the `pdbtrack-tracked-buffer' variable.
38 Returns the tracked buffer."
39 (let ((file-buffer (get-file-buffer
40 (concat (file-remote-p default-directory)
41 file-name))))
42 (if file-buffer
43 (setq pdbtrack-tracked-buffer file-buffer)
44 (setq file-buffer (find-file-noselect file-name))
45 (when (not (member file-buffer pdbtrack-buffers-to-kill))
46 (add-to-list 'pdbtrack-buffers-to-kill file-buffer)))
47 file-buffer))
48
49 (defun pdbtrack-comint-output-filter-function (output)
50 "Move overlay arrow to current pdb line in tracked buffer.
51 Argument OUTPUT is a string with the output from the comint process."
52 (when (and pdbtrack-minor-mode (not (string= output "")))
53 (let* ((full-output (ansi-color-filter-apply
54 (buffer-substring comint-last-input-end (point-max))))
55 (line-number)
56 (file-name
57 (with-temp-buffer
58 (insert full-output)
59 ;; When the debugger encounters a pdb.set_trace()
60 ;; command, it prints a single stack frame. Sometimes
61 ;; it prints a bit of extra information about the
62 ;; arguments of the present function. When ipdb
63 ;; encounters an exception, it prints the _entire_ stack
64 ;; trace. To handle all of these cases, we want to find
65 ;; the _last_ stack frame printed in the most recent
66 ;; batch of output, then jump to the corresponding
67 ;; file/line number.
68 (goto-char (point-max))
69 (when (re-search-backward pdbtrack-stacktrace-info-regexp nil t)
70 (setq line-number (string-to-number
71 (match-string-no-properties 2)))
72 (match-string-no-properties 1)))))
73 (if (and file-name line-number)
74 (let* ((tracked-buffer
75 (pdbtrack-set-tracked-buffer file-name))
76 (shell-buffer (current-buffer))
77 (tracked-buffer-window (get-buffer-window tracked-buffer))
78 (tracked-buffer-line-pos))
79 (with-current-buffer tracked-buffer
80 (set (make-local-variable 'overlay-arrow-string) "=>")
81 (set (make-local-variable 'overlay-arrow-position) (make-marker))
82 (setq tracked-buffer-line-pos (progn
83 (goto-char (point-min))
84 (forward-line (1- line-number))
85 (point-marker)))
86 (when tracked-buffer-window
87 (set-window-point
88 tracked-buffer-window tracked-buffer-line-pos))
89 (set-marker overlay-arrow-position tracked-buffer-line-pos))
90 (pop-to-buffer tracked-buffer)
91 (switch-to-buffer-other-window shell-buffer))
92 (when pdbtrack-tracked-buffer
93 (with-current-buffer pdbtrack-tracked-buffer
94 (set-marker overlay-arrow-position nil))
95 (when (not pdbtrack-remove-new-buffers-after-tracking)
96 (mapc #'(lambda (buffer)
97 (ignore-errors (kill-buffer buffer)))
98 pdbtrack-buffers-to-kill))
99 (setq pdbtrack-tracked-buffer nil
100 pdbtrack-buffers-to-kill nil)))))
101 output)
102
103 (provide 'pdbtrack)