Kevin J. Butler writes: > ... > > After my patch: > (Pdb) cl 3 > Deleted breakpoint 3 at z:\work\wm\wm.py:136 > (Pdb) cl wm.py:17 > Deleted breakpoint 5 at z:\work\wm\wm.py:17 I've applied your patch manually to my files bdb.py and pdb.py (I have 2.2) and it appears to work. If you load the file below in Emacs (M-x eval-buffer or M-x load-file), then type M-x pdb, the debugger (with your patch) should work with breakpoint icons in the display margin. Emacs must be a version from the CVS repository to work straight away. This will also give you buttons for debugging if you turn the toolbar on (M-x tool-bar-mode). I've tested it on GNU/Linux but it should work on Windows too if I've defined the regexp correctly. I've just noticed that you can enable/disable breakpoints in python. In my mode for gdb, the breakpoints are greyed out when the breakpoints become disabled. I could do this for python too if these commands were changed to emit a message. If your patches are accepted (by SF?) then I will integrate my changes into gud.el in the Emacs CVS repository. Nick ----------------------------------------------------- (require 'gud) (defun gud-sentinel (proc msg) (cond ((null (buffer-name (process-buffer proc))) ;; buffer killed ;; Stop displaying an arrow in a source file. (setq overlay-arrow-position nil) (set-process-buffer proc nil) (if (memq gud-minor-mode-type '(gdba pdb)) (gdb-reset) (gud-reset))) ((memq (process-status proc) '(signal exit)) ;; Stop displaying an arrow in a source file. (setq overlay-arrow-position nil) (with-current-buffer gud-comint-buffer (if (memq gud-minor-mode '(gdba pdb)) (gdb-reset) (gud-reset))) (let* ((obuf (current-buffer))) ;; save-excursion isn't the right thing if ;; process-buffer is current-buffer (unwind-protect (progn ;; Write something in *compilation* and hack its mode line, (set-buffer (process-buffer proc)) ;; Fix the mode line. (setq mode-line-process (concat ":" (symbol-name (process-status proc)))) (force-mode-line-update) (if (eobp) (insert ?\n mode-name " " msg) (save-excursion (goto-char (point-max)) (insert ?\n mode-name " " msg))) ;; If buffer and mode line will show that the process ;; is dead, we can delete it now. Otherwise it ;; will stay around until M-x list-processes. (delete-process proc)) ;; Restore old buffer, but don't restore old point ;; if obuf is the gud buffer. (set-buffer obuf)))))) (defun gdb-reset () "Exit a debugging session cleanly by killing the gdb buffers and resetting the source buffers." (dolist (buffer (buffer-list)) (if (not (eq buffer gud-comint-buffer)) (with-current-buffer buffer (if (memq gud-minor-mode '(gdba pdb)) (if (string-match "^\*.+*$" (buffer-name)) (kill-buffer nil) (if (display-images-p) (remove-images (point-min) (point-max)) (gdb-remove-strings (point-min) (point-max))) (setq left-margin-width 0) (setq gud-minor-mode nil) (kill-local-variable 'tool-bar-map) (setq gud-running nil) (if (get-buffer-window (current-buffer)) (set-window-margins (get-buffer-window (current-buffer)) left-margin-width right-margin-width)))))))) (defun gdb-put-string (putstring pos) "Put string PUTSTRING in front of POS in the current buffer. PUTSTRING is displayed by putting an overlay into the current buffer with a `before-string' STRING that has a `display' property whose value is PUTSTRING." (let ((gdb-string "x") (buffer (current-buffer))) (let ((overlay (make-overlay pos pos buffer)) (prop (list (list 'margin 'left-margin) putstring))) (put-text-property 0 (length gdb-string) 'display prop gdb-string) (overlay-put overlay 'put-break t) (overlay-put overlay 'before-string gdb-string)))) (defun gdb-remove-strings (start end &optional buffer) "Remove strings between START and END in BUFFER. Remove only strings that were put in BUFFER with calls to `put-string'. BUFFER nil or omitted means use the current buffer." (unless buffer (setq buffer (current-buffer))) (let ((overlays (overlays-in start end))) (while overlays (let ((overlay (car overlays))) (when (overlay-get overlay 'put-break) (delete-overlay overlay))) (setq overlays (cdr overlays))))) (defconst breakpoint-xpm-data "/* XPM */ static char *magick[] = { /* columns rows colors chars-per-pixel */ \"12 12 2 1\", \" c red\", \"+ c None\", /* pixels */ \"++++++++++++\", \"+++ +++\", \"++ ++\", \"+ +\", \"+ +\", \"+ +\", \"+ +\", \"+ +\", \"+ +\", \"++ ++\", \"+++ +++\", \"++++++++++++\" };" "XPM data used for breakpoint icon.") (defconst breakpoint-enabled-pbm-data "P1 12 12\", 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0" "PBM data used for enabled breakpoint icon.") (defvar breakpoint-enabled-icon (find-image `((:type xpm :data ,breakpoint-xpm-data) (:type pbm :data ,breakpoint-enabled-pbm-data))) "Icon for enabled breakpoint in display margin") ;; ====================================================================== ;; pdb (Python debugger) functions ;; History of argument lists passed to pdb. (defvar gud-pdb-history nil) ;; Last group is for return value, e.g. "> test.py(2)foo()->None" ;; Either file or function name may be omitted: "> <string>(0)?()" (defvar gud-pdb-marker-regexp "^> \\([-a-zA-Z0-9_/.:\\]*\\|<string>\\)(\\([0-9]+\\))\\([a-zA-Z0-9_]*\\|\\?\\)()\\(->[^\n]*\\)?\n") (defvar gud-pdb-marker-regexp-file-group 1) (defvar gud-pdb-marker-regexp-line-group 2) (defvar gud-pdb-marker-regexp-fnname-group 3) (defvar gud-pdb-marker-regexp-start "^> ") (defvar gud-pdb-marker-regexp-breakpoint "reakpoint [0-9]+ at \\(\\([a-zA-Z]:\\)?[^:\n]*\\):\\([0-9]*\\)\n") ;; There's no guarantee that Emacs will hand the filter the entire ;; marker at once; it could be broken up across several strings. We ;; might even receive a big chunk with several markers in it. If we ;; receive a chunk of text which looks like it might contain the ;; beginning of a marker, we save it here between calls to the ;; filter. (defun gud-pdb-marker-filter (string) (setq gud-marker-acc (concat gud-marker-acc string)) (let ((output "")) ;; Process all the complete markers in this chunk. (while (string-match gud-pdb-marker-regexp gud-marker-acc) (setq ;; Extract the frame position from the marker. gud-last-frame (let ((file (match-string gud-pdb-marker-regexp-file-group gud-marker-acc)) (line (string-to-int (match-string gud-pdb-marker-regexp-line-group gud-marker-acc)))) (if (string-equal file "<string>") gud-last-frame (cons file line))) ;; Output everything instead of the below output (concat output (substring gud-marker-acc 0 (match-end 0))) ;; ;; Append any text before the marker to the output we're going ;; ;; to return - we don't include the marker in this text. ;; output (concat output ;; (substring gud-marker-acc 0 (match-beginning 0))) ;; Set the accumulator to the remaining text. gud-marker-acc (substring gud-marker-acc (match-end 0)))) (if (string-match (concat "B" gud-pdb-marker-regexp-breakpoint) gud-marker-acc) (let ((file (match-string 1 gud-marker-acc)) (line (match-string 3 gud-marker-acc))) (gud-pdb-insert-breakpoint file line))) (if (string-match (concat "Deleted b" gud-pdb-marker-regexp-breakpoint) gud-marker-acc) (let ((file (match-string 1 gud-marker-acc)) (line (match-string 3 gud-marker-acc))) (gud-pdb-remove-breakpoint file line))) ;; Does the remaining text look like it might end with the ;; beginning of another marker? If it does, then keep it in ;; gud-marker-acc until we receive the rest of it. Since we ;; know the full marker regexp above failed, it's pretty simple to ;; test for marker starts. (if (string-match gud-pdb-marker-regexp-start gud-marker-acc) (progn ;; Everything before the potential marker start can be output. (setq output (concat output (substring gud-marker-acc 0 (match-beginning 0)))) ;; Everything after, we save, to combine with later input. (setq gud-marker-acc (substring gud-marker-acc (match-beginning 0)))) (setq output (concat output gud-marker-acc) gud-marker-acc "")) output)) (defun gud-pdb-insert-breakpoint (file line) (with-current-buffer (find-file-noselect file) (save-current-buffer (set (make-local-variable 'gud-minor-mode) 'pdb) (set (make-local-variable 'tool-bar-map) gud-tool-bar-map) (setq left-margin-width 2) (if (get-buffer-window (current-buffer)) (set-window-margins (get-buffer-window (current-buffer)) left-margin-width right-margin-width))) (save-excursion (goto-line (string-to-number line)) (let ((start (progn (beginning-of-line) (- (point) 1))) (end (progn (end-of-line) (+ (point) 1)))) (if (display-images-p) (progn (remove-images start end) (put-image breakpoint-enabled-icon (+ start 1) "breakpoint icon enabled" 'left-margin)) (gdb-remove-strings start end) (gdb-put-string "B" (+ start 1))))))) (defun gud-pdb-remove-breakpoint (file line) (with-current-buffer (find-file-noselect file) (save-excursion (goto-line (string-to-number line)) (let ((start (progn (beginning-of-line) (- (point) 1))) (end (progn (end-of-line) (+ (point) 1)))) (if (display-images-p) (remove-images start end) (gdb-remove-strings start end)))))) (defcustom gud-pdb-command-name "pdb" "File name for executing the Python debugger. This should be an executable on your path, or an absolute file name." :type 'string :group 'gud) (defun pdb (command-line) "Run pdb on program FILE in buffer `*gud-FILE*'. The directory containing FILE becomes the initial working directory and source-file directory for your debugger." (interactive (list (gud-query-cmdline 'pdb))) (gud-common-init command-line nil 'gud-pdb-marker-filter) (set (make-local-variable 'gud-minor-mode) 'pdb) (gud-def gud-break "break %l" "\C-b" "Set breakpoint at current line.") (gud-def gud-remove "clear %f:%l" "\C-d" "Remove breakpoint at current line") (gud-def gud-step "step" "\C-s" "Step one source line with display.") (gud-def gud-next "next" "\C-n" "Step one line (skip functions).") (gud-def gud-cont "continue" "\C-r" "Continue with display.") (gud-def gud-finish "return" "\C-f" "Finish executing current function.") (gud-def gud-up "up" "<" "Up one stack frame.") (gud-def gud-down "down" ">" "Down one stack frame.") (gud-def gud-print "p %e" "\C-p" "Evaluate Python expression at point.") ;; Is this right? (gud-def gud-statement "! %e" "\C-e" "Execute Python statement at point.") ;; (setq comint-prompt-regexp "^(.*pdb[+]?) *") (setq comint-prompt-regexp "^(Pdb) *") (setq paragraph-start comint-prompt-regexp) (run-hooks 'pdb-mode-hook))
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4