unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Augusto Stoffel <arstoffel@gmail.com>
To: 56997@debbugs.gnu.org
Cc: Philip Kaludercic <philipk@posteo.net>,
	Stefan Monnier <monnier@iro.umontreal.ca>
Subject: bug#56997: [PATCH] Analogue of project-shell for Python
Date: Fri, 05 Aug 2022 09:31:02 +0200	[thread overview]
Message-ID: <874jyr87ux.fsf@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 677 bytes --]

The Python shell already allows a shell to be "dedicated" to a buffer.
This patch adds the option to create a shell dedicated to a project, as
well as the option to make all Python shells dedicated by default.

Stefan: you mentioned python.el could use project.el without a hard
dependency, so it remains compatible with old Emacsen.  Is this a good
approach?  (Also: the added seq dependency is kinda superfluous now, but
it's nice to have it available for future developments as well.)

Philip: I'm working around the possible absence of
'read-multiple-choice' here.  Not sure it's a popular/useful enough
function to include in compat, but I thought I would bring this up.


[-- Attachment #2: 0001-Python-shells-dedicated-to-a-project.patch --]
[-- Type: text/x-patch, Size: 7756 bytes --]

From 7174b34701cb201c088f0fce6a57aee9a75eef20 Mon Sep 17 00:00:00 2001
From: Augusto Stoffel <arstoffel@gmail.com>
Date: Thu, 4 Aug 2022 12:08:58 +0200
Subject: [PATCH] Python shells dedicated to a project

These shells run in the project root directory and are shared among
all project buffers.

* lisp/progmodes/python.el: Require 'seq' and (optionally) 'project'
libraries.
(python-shell-dedicated): New user option
(python-shell-get-process-name): Adapt to project-dedicated shells.
(run-python): Offer possibility to create a project-dedicated shell,
or use 'python-shell-dedicated' as the default behavior.
(python-shell-get-buffer): Adapt to project-dedicated shells.
---
 etc/NEWS                 | 11 ++++++
 lisp/progmodes/python.el | 79 ++++++++++++++++++++++++++++------------
 2 files changed, 66 insertions(+), 24 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 963aa22c68..fcbf7deba7 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2055,6 +2055,17 @@ the Galeon web browser was released in September, 2008.
 Note that this historical web browser is different from Mozilla
 Firefox; it is its predecessor.
 
+** Python Mode
++++
+*** Project shells and a new user option 'python-shell-dedicated'
+When called with a prefix argument, 'run-python' now offers the choice
+of creating a shell dedicated to the current project.  This shell runs
+in the project root directory and is shared among all project buffers.
+
+Without a prefix argument, the kind of shell (buffer-dedicated,
+project-dedicated or global) is specified by the new
+'python-shell-dedicated' variable.
+
 ** Ruby Mode
 
 ---
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index b8fc7d4c54..bbdd2a9502 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -5,7 +5,7 @@
 ;; Author: Fabián E. Gallina <fgallina@gnu.org>
 ;; URL: https://github.com/fgallina/python.el
 ;; Version: 0.28
-;; Package-Requires: ((emacs "24.4") (cl-lib "1.0"))
+;; Package-Requires: ((emacs "24.4") (cl-lib "1.0") (seq "2.23"))
 ;; Maintainer: emacs-devel@gnu.org
 ;; Created: Jul 2010
 ;; Keywords: languages
@@ -245,6 +245,8 @@
 (require 'ansi-color)
 (require 'cl-lib)
 (require 'comint)
+(require 'project nil 'noerror)
+(require 'seq)
 (eval-when-compile (require 'subr-x))   ;For `string-empty-p'.
 
 ;; Avoid compiler warnings
@@ -2218,6 +2220,16 @@ python-shell-compilation-regexp-alist
   "`compilation-error-regexp-alist' for inferior Python."
   :type '(alist regexp))
 
+(defcustom python-shell-dedicated nil
+  "Whether to make Python shells dedicated by default.
+This option influences `run-python' when called without a prefix
+argument.  If `buffer' or `project', create a Python shell
+dedicated to the current buffer or its project (if one is found)."
+  :version "29.1"
+  :type '(choice (const :tag "To buffer" buffer)
+                 (const :tag "To project" project)
+                 (const :tag "Not dedicated" nil)))
+
 (defvar python-shell-output-filter-in-progress nil)
 (defvar python-shell-output-filter-buffer nil)
 
@@ -2580,12 +2592,19 @@ python-shell-prompt-set-calculated-regexps
 
 (defun python-shell-get-process-name (dedicated)
   "Calculate the appropriate process name for inferior Python process.
-If DEDICATED is t returns a string with the form
-`python-shell-buffer-name'[`buffer-name'] else returns the value
-of `python-shell-buffer-name'."
-  (if dedicated
-      (format "%s[%s]" python-shell-buffer-name (buffer-name))
-    python-shell-buffer-name))
+If DEDICATED is nil, this is simply `python-shell-buffer-name'.
+If DEDICATED is `buffer' or `project', append the current buffer
+name respectively the current project name."
+  (pcase dedicated
+    ('nil python-shell-buffer-name)
+    ('project
+     (if-let ((proj (and (featurep 'project)
+                         (project-current))))
+         (format "%s[%s]" python-shell-buffer-name (file-name-nondirectory
+                                                    (directory-file-name
+                                                     (project-root proj))))
+       python-shell-buffer-name))
+    (_ (format "%s[%s]" python-shell-buffer-name (buffer-name)))))
 
 (defun python-shell-internal-get-process-name ()
   "Calculate the appropriate process name for Internal Python process.
@@ -3043,8 +3062,8 @@ run-python
 Argument CMD defaults to `python-shell-calculate-command' return
 value.  When called interactively with `prefix-arg', it allows
 the user to edit such value and choose whether the interpreter
-should be DEDICATED for the current buffer.  When numeric prefix
-arg is other than 0 or 4 do not SHOW.
+should be DEDICATED to the current buffer or project.  When
+numeric prefix arg is other than 0 or 4 do not SHOW.
 
 For a given buffer and same values of DEDICATED, if a process is
 already running for it, it will do nothing.  This means that if
@@ -3058,13 +3077,27 @@ run-python
    (if current-prefix-arg
        (list
         (read-shell-command "Run Python: " (python-shell-calculate-command))
-        (y-or-n-p "Make dedicated process? ")
+        (if (not (fboundp 'read-multiple-choice))
+            (y-or-n-p "Make dedicated process? ")
+          (alist-get (car (read-multiple-choice "Make dedicated process?"
+                                                '((?b "to buffer")
+                                                  (?p "to project")
+                                                  (?n "no"))))
+                     '((?b . buffer) (?p . project))))
         (= (prefix-numeric-value current-prefix-arg) 4))
-     (list (python-shell-calculate-command) nil t)))
-  (let ((buffer
-         (python-shell-make-comint
-          (or cmd (python-shell-calculate-command))
-          (python-shell-get-process-name dedicated) show)))
+     (list (python-shell-calculate-command)
+           python-shell-dedicated
+           t)))
+  (let* ((project (and (eq 'project dedicated)
+                       (featurep 'project)
+                       (project-current t)))
+         (default-directory (if project
+                                (project-root project)
+                              default-directory))
+         (buffer (python-shell-make-comint
+                  (or cmd (python-shell-calculate-command))
+                  (python-shell-get-process-name dedicated)
+                  show)))
     (get-buffer-process buffer)))
 
 (defun run-python-internal ()
@@ -3094,15 +3127,13 @@ python-shell-get-buffer
 If current buffer is in `inferior-python-mode', return it."
   (if (derived-mode-p 'inferior-python-mode)
       (current-buffer)
-    (let* ((dedicated-proc-name (python-shell-get-process-name t))
-           (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name))
-           (global-proc-name  (python-shell-get-process-name nil))
-           (global-proc-buffer-name (format "*%s*" global-proc-name))
-           (dedicated-running (comint-check-proc dedicated-proc-buffer-name))
-           (global-running (comint-check-proc global-proc-buffer-name)))
-      ;; Always prefer dedicated
-      (or (and dedicated-running dedicated-proc-buffer-name)
-          (and global-running global-proc-buffer-name)))))
+    (seq-some
+     (lambda (dedicated)
+       (let* ((proc-name (python-shell-get-process-name dedicated))
+              (buffer-name (format "*%s*" proc-name)))
+         (when (comint-check-proc buffer-name)
+           buffer-name)))
+     '(buffer project nil))))
 
 (defun python-shell-get-process ()
   "Return inferior Python process for current buffer."
-- 
2.37.1


             reply	other threads:[~2022-08-05  7:31 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-05  7:31 Augusto Stoffel [this message]
2022-08-05  9:22 ` bug#56997: [PATCH] Analogue of project-shell for Python Philip Kaludercic
2022-08-05  9:52   ` Augusto Stoffel
2022-08-05 11:00     ` Philip Kaludercic
2022-08-05 11:43       ` Augusto Stoffel
2022-08-23 16:40 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-08-24 16:55   ` Augusto Stoffel
2022-09-04 11:14     ` Lars Ingebrigtsen

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

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874jyr87ux.fsf@gmail.com \
    --to=arstoffel@gmail.com \
    --cc=56997@debbugs.gnu.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=philipk@posteo.net \
    /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 public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).