From: Andrii Kolomoiets <andreyk.mad@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: emacs-devel@gnu.org
Subject: Re: python: Let pdb tracking not kill buffers
Date: Sat, 2 Nov 2019 18:37:26 +0200 [thread overview]
Message-ID: <6F09449A-0EDF-4D7C-86DC-EE466CE032C8@gmail.com> (raw)
In-Reply-To: <83ftj8lz23.fsf@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 782 bytes --]
On 1 Nov 2019, at 11:35, Eli Zaretskii <eliz@gnu.org> wrote:
> Can you please add:
>
> . Commit log message formatted according to instructions in
> CONTRIBUTE
> . Suitable short entry for NEWS about the new options
Please see attached updated patch.
> Also, I don't see any rationale for changing
> python-pdbtrack-stacktrace-info-regexp; can you tell why you needed
> that?
Current python-pdbtrack-stacktrace-info-regexp match only lines with real
filenames, like:
> /Users/mad/test.py(3)<module>()->None
Pdb command "next" can bring us to upper stack frame, like:
> <stdin>(1)<module>()->None
At this point pdbtracking session can be considered over. And new
python-pdbtrack-stacktrace-info-regexp can match such lines with "<stdin>"
or "<string>" as filenames.
[-- Attachment #2: 0001-python.el-Pdbtracking-improvements.patch --]
[-- Type: application/octet-stream, Size: 13004 bytes --]
From 705dd66d5e46d115cda71abb856d68cea3f8f70c Mon Sep 17 00:00:00 2001
From: Andrii Kolomoiets <andreyk.mad@gmail.com>
Date: Sat, 2 Nov 2019 18:08:13 +0200
Subject: [PATCH] python.el: Pdbtracking improvements
Allow to not kill buffers when pdbtracking session is finished.
Pdbtracking session consider finished judging from the user input.
* lisp/progmodes/python.el (python-pdbtrack-kill-buffers): New
customizable variable.
(python-pdbtrack-set-tracked-buffer): Use it.
(python-pdbtrack-unset-tracked-buffer, python-pdbtrack-tracking-finish): New
functions.
(python-pdbtrack-continue-command, python-pdbtrack-exit-command): New
customizable variables.
(python-pdbtrack-process-sentinel): New function. Finish pdbtracking session
when process is killed.
(python-pdbtrack-prev-command-continue): New variable.
(python-pdbtrack-comint-input-filter-function): New function. Finish
pdbtracking session based on commands sent to pdb.
(python-pdbtrack-comint-output-filter-function): Unset/set tracking buffer if
looking at pdb prompt; finish pdbtracking session if filename of current
stack frame starts with "<" e.g. "<stdin>".
(python-pdbtrack-comint-output-filter-function): Don't override
overlay-arrow-string.
(python-pdbtrack-setup-tracking): New function.
(inferior-python-mode): Use it.
; * etc/NEWS: Mention python-pdbtrack-kill-buffers
diff --git a/etc/NEWS b/etc/NEWS
index 7a76d90ed5..903a991a1f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1389,6 +1389,11 @@ unescaping text.
The maximum level is used by default; customize
'font-lock-maximum-decoration' to tone down the decoration.
+---
+*** New user option 'python-pdbtrack-kill-buffers'.
+If nil, buffers opened during pdbtracking session is not killed when
+pdbtracking session is finished.
+
** Help
---
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index bdc0f1cd96..b217f6cfde 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -2785,7 +2785,6 @@ inferior-python-mode
(set (make-local-variable 'comint-output-filter-functions)
'(ansi-color-process-output
python-shell-comint-watch-for-first-prompt-output-filter
- python-pdbtrack-comint-output-filter-function
python-comint-postoutput-scroll-to-bottom
comint-watch-for-password-prompt))
(set (make-local-variable 'compilation-error-regexp-alist)
@@ -2794,12 +2793,11 @@ inferior-python-mode
#'python-shell-completion-at-point nil 'local)
(define-key inferior-python-mode-map "\t"
'python-shell-completion-complete-or-indent)
- (make-local-variable 'python-pdbtrack-buffers-to-kill)
- (make-local-variable 'python-pdbtrack-tracked-buffer)
(make-local-variable 'python-shell-internal-last-output)
(when python-shell-font-lock-enable
(python-shell-font-lock-turn-on))
- (compilation-shell-minor-mode 1))
+ (compilation-shell-minor-mode 1)
+ (python-pdbtrack-setup-tracking))
(defun python-shell-make-comint (cmd proc-name &optional show internal)
"Create a Python shell comint buffer.
@@ -3728,19 +3726,59 @@ python-shell-completion-complete-or-indent
;;; PDB Track integration
(defcustom python-pdbtrack-activate t
- "Non-nil makes Python shell enable pdbtracking."
+ "Non-nil makes Python shell enable pdbtracking.
+Pdbtracking would open the file for current stack frame found in pdb output by
+`python-pdbtrack-stacktrace-info-regexp' and add overlay arrow in currently
+inspected line in that file.
+
+After command listed in `python-pdbtrack-continue-command' or
+`python-pdbtrack-exit-command' is sent to pdb, pdbtracking session is
+considered over. Overlay arrow will be removed from currentry tracked
+buffer. Additionally, if `python-pdbtrack-kill-buffers' is non-nil, all
+files opened by pdbtracking will be killed."
:type 'boolean
:group 'python
:safe 'booleanp)
(defcustom python-pdbtrack-stacktrace-info-regexp
- "> \\([^\"(<]+\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_<>]+\\)()"
+ "> \\([^\"(]+\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_<>]+\\)()"
"Regular expression matching stacktrace information.
Used to extract the current line and module being inspected."
:type 'string
- :group 'python
+ :version "27.1"
:safe 'stringp)
+(defcustom python-pdbtrack-continue-command '("c" "cont" "continue")
+ "Pdb 'continue' command aliases.
+After one of this commands is sent to pdb, pdbtracking session is
+considered over.
+
+This command is remembered by pdbtracking. If next command sent to pdb
+is empty string, it considered 'continue' command if previous command
+was 'continue'. This behavior slightly differentiate 'continue' command
+from 'exit' commands listed in `python-pdbtrack-exit-command'.
+
+See `python-pdbtrack-activate' for pdbtracking session overview."
+ :type 'list
+ :version "27.1")
+
+(defcustom python-pdbtrack-exit-command '("q" "quit" "exit")
+ "Pdb 'exit' command aliases.
+After one of this commands is sent to pdb, pdbtracking session is
+considered over.
+
+See `python-pdbtrack-activate' for pdbtracking session overview."
+ :type 'list
+ :version "27.1")
+
+(defcustom python-pdbtrack-kill-buffers t
+ "If non-nil, kill buffers when pdbtracking session is over.
+Only buffers opened by pdbtracking will be killed.
+
+See `python-pdbtrack-activate' for pdbtracking session overview."
+ :type 'boolean
+ :version "27.1")
+
(defvar python-pdbtrack-tracked-buffer nil
"Variable containing the value of the current tracked buffer.
Never set this variable directly, use
@@ -3749,6 +3787,9 @@ python-pdbtrack-tracked-buffer
(defvar python-pdbtrack-buffers-to-kill nil
"List of buffers to be deleted after tracking finishes.")
+(defvar python-pdbtrack-prev-command-continue nil
+ "Is t if previous pdb command was 'continue'.")
+
(defun python-pdbtrack-set-tracked-buffer (file-name)
"Set the buffer for FILE-NAME as the tracked buffer.
Internally it uses the `python-pdbtrack-tracked-buffer' variable.
@@ -3756,8 +3797,7 @@ python-pdbtrack-set-tracked-buffer
(let* ((file-name-prospect (concat (file-remote-p default-directory)
file-name))
(file-buffer (get-file-buffer file-name-prospect)))
- (if file-buffer
- (setq python-pdbtrack-tracked-buffer file-buffer)
+ (unless file-buffer
(cond
((file-exists-p file-name-prospect)
(setq file-buffer (find-file-noselect file-name-prospect)))
@@ -3765,10 +3805,55 @@ python-pdbtrack-set-tracked-buffer
(file-exists-p file-name))
;; Fallback to a locally available copy of the file.
(setq file-buffer (find-file-noselect file-name-prospect))))
- (when (not (member file-buffer python-pdbtrack-buffers-to-kill))
+ (when (and python-pdbtrack-kill-buffers
+ (not (member file-buffer python-pdbtrack-buffers-to-kill)))
(add-to-list 'python-pdbtrack-buffers-to-kill file-buffer)))
+ (setq python-pdbtrack-tracked-buffer file-buffer)
file-buffer))
+(defun python-pdbtrack-unset-tracked-buffer ()
+ "Untrack currently tracked buffer."
+ (when python-pdbtrack-tracked-buffer
+ (with-current-buffer python-pdbtrack-tracked-buffer
+ (set-marker overlay-arrow-position nil))
+ (setq python-pdbtrack-tracked-buffer nil)))
+
+(defun python-pdbtrack-tracking-finish ()
+ "Finish tracking."
+ (python-pdbtrack-unset-tracked-buffer)
+ (when python-pdbtrack-kill-buffers
+ (mapc #'(lambda (buffer)
+ (ignore-errors (kill-buffer buffer)))
+ python-pdbtrack-buffers-to-kill))
+ (setq python-pdbtrack-buffers-to-kill nil))
+
+(defun python-pdbtrack-process-sentinel (process _event)
+ "Untrack buffers when PROCESS is killed."
+ (unless (process-live-p process)
+ (let ((buffer (process-buffer process)))
+ (when (buffer-live-p buffer)
+ (with-current-buffer buffer
+ (python-pdbtrack-tracking-finish))))))
+
+(defun python-pdbtrack-comint-input-filter-function (input)
+ "Finish tracking session depending on command in INPUT.
+Commands that must finish tracking session is listed in
+`python-pdbtrack-untracking-commands'."
+ (when (and python-pdbtrack-tracked-buffer
+ ;; Empty input is sent by C-d or `comint-send-eof'
+ (or (string-empty-p input)
+ ;; "n some text" is "n" command for pdb. Split input and get firs part
+ (let* ((command (car (split-string (string-trim input) " "))))
+ (setq python-pdbtrack-prev-command-continue
+ (or (member command python-pdbtrack-continue-command)
+ ;; if command is empty and previous command was 'continue'
+ ;; then current command is 'continue' too.
+ (and (string-empty-p command)
+ python-pdbtrack-prev-command-continue)))
+ (or python-pdbtrack-prev-command-continue
+ (member command python-pdbtrack-exit-command)))))
+ (python-pdbtrack-tracking-finish)))
+
(defun python-pdbtrack-comint-output-filter-function (output)
"Move overlay arrow to current pdb line in tracked buffer.
Argument OUTPUT is a string with the output from the comint process."
@@ -3788,19 +3873,27 @@ python-pdbtrack-comint-output-filter-function
;; the _last_ stack frame printed in the most recent
;; batch of output, then jump to the corresponding
;; file/line number.
+ ;; Parse output only if at pdb prompt to avoid double code
+ ;; run in situation when output and pdb prompt received in
+ ;; different hunks
(goto-char (point-max))
- (when (re-search-backward python-pdbtrack-stacktrace-info-regexp nil t)
+ (goto-char (line-beginning-position))
+ (when (and (looking-at python-shell-prompt-pdb-regexp)
+ (re-search-backward python-pdbtrack-stacktrace-info-regexp nil t))
(setq line-number (string-to-number
(match-string-no-properties 2)))
(match-string-no-properties 1)))))
- (if (and file-name line-number)
- (let* ((tracked-buffer
- (python-pdbtrack-set-tracked-buffer file-name))
+ (when (and file-name line-number)
+ (if (string-prefix-p "<" file-name)
+ ;; Finish tracking session if stacktrace info is like
+ ;; "> <stdin>(1)<module>()->None"
+ (python-pdbtrack-tracking-finish)
+ (python-pdbtrack-unset-tracked-buffer)
+ (let* ((tracked-buffer (python-pdbtrack-set-tracked-buffer file-name))
(shell-buffer (current-buffer))
(tracked-buffer-window (get-buffer-window tracked-buffer))
(tracked-buffer-line-pos))
(with-current-buffer tracked-buffer
- (set (make-local-variable 'overlay-arrow-string) "=>")
(set (make-local-variable 'overlay-arrow-position) (make-marker))
(setq tracked-buffer-line-pos (progn
(goto-char (point-min))
@@ -3811,17 +3904,21 @@ python-pdbtrack-comint-output-filter-function
tracked-buffer-window tracked-buffer-line-pos))
(set-marker overlay-arrow-position tracked-buffer-line-pos))
(pop-to-buffer tracked-buffer)
- (switch-to-buffer-other-window shell-buffer))
- (when python-pdbtrack-tracked-buffer
- (with-current-buffer python-pdbtrack-tracked-buffer
- (set-marker overlay-arrow-position nil))
- (mapc #'(lambda (buffer)
- (ignore-errors (kill-buffer buffer)))
- python-pdbtrack-buffers-to-kill)
- (setq python-pdbtrack-tracked-buffer nil
- python-pdbtrack-buffers-to-kill nil)))))
+ (switch-to-buffer-other-window shell-buffer))))))
output)
+(defun python-pdbtrack-setup-tracking ()
+ "Setup pdb tracking in current buffer."
+ (make-local-variable 'python-pdbtrack-buffers-to-kill)
+ (make-local-variable 'python-pdbtrack-tracked-buffer)
+ (add-to-list (make-local-variable 'comint-input-filter-functions)
+ #'python-pdbtrack-comint-input-filter-function)
+ (add-to-list (make-local-variable 'comint-output-filter-functions)
+ #'python-pdbtrack-comint-output-filter-function)
+ (add-function :before (process-sentinel (get-buffer-process (current-buffer)))
+ #'python-pdbtrack-process-sentinel)
+ (add-hook 'kill-buffer-hook #'python-pdbtrack-tracking-finish nil t))
+
\f
;;; Symbol completion
--
2.15.1
next prev parent reply other threads:[~2019-11-02 16:37 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-04 20:32 python: Let pdb tracking not kill buffers Andrii Kolomoiets
2019-10-05 6:40 ` Eli Zaretskii
2019-10-07 4:33 ` Lawrence Liu
2019-10-07 16:19 ` Eli Zaretskii
2019-10-07 16:26 ` Lawrence Liu
2019-10-07 12:28 ` Andrii Kolomoiets
2019-10-30 19:14 ` Andrii Kolomoiets
2019-11-01 9:35 ` Eli Zaretskii
2019-11-02 16:37 ` Andrii Kolomoiets [this message]
2019-11-02 17:29 ` Eli Zaretskii
2019-11-02 18:51 ` Andrii Kolomoiets
2019-11-07 16:57 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=6F09449A-0EDF-4D7C-86DC-EE466CE032C8@gmail.com \
--to=andreyk.mad@gmail.com \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.