diff options
| author | Augusto Stoffel | 2022-09-04 13:13:57 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2022-09-04 13:13:57 +0200 |
| commit | 4932d26b5df14af01ae757b2a5232d157df69008 (patch) | |
| tree | 52b12bbc84322cd75ddea4360f33734a9338b175 /lisp/progmodes/python.el | |
| parent | 2db8b0e12f913ecd720aa81a70580e58fd032397 (diff) | |
| download | emacs-4932d26b5df14af01ae757b2a5232d157df69008.tar.gz emacs-4932d26b5df14af01ae757b2a5232d157df69008.zip | |
Python shells dedicated to a project
* lisp/progmodes/python.el: Require 'seq' and (optionally) 'compat'
and '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
(bug#56997).
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 78 |
1 files changed, 54 insertions, 24 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index d3ffc2db2c9..6020d52b91f 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | ;; Author: Fabián E. Gallina <fgallina@gnu.org> | 5 | ;; Author: Fabián E. Gallina <fgallina@gnu.org> |
| 6 | ;; URL: https://github.com/fgallina/python.el | 6 | ;; URL: https://github.com/fgallina/python.el |
| 7 | ;; Version: 0.28 | 7 | ;; Version: 0.28 |
| 8 | ;; Package-Requires: ((emacs "24.4") (cl-lib "1.0")) | 8 | ;; Package-Requires: ((emacs "24.4") (compat "28.1.2.1") (seq "2.23")) |
| 9 | ;; Maintainer: emacs-devel@gnu.org | 9 | ;; Maintainer: emacs-devel@gnu.org |
| 10 | ;; Created: Jul 2010 | 10 | ;; Created: Jul 2010 |
| 11 | ;; Keywords: languages | 11 | ;; Keywords: languages |
| @@ -245,6 +245,9 @@ | |||
| 245 | (require 'ansi-color) | 245 | (require 'ansi-color) |
| 246 | (require 'cl-lib) | 246 | (require 'cl-lib) |
| 247 | (require 'comint) | 247 | (require 'comint) |
| 248 | (require 'compat nil 'noerror) | ||
| 249 | (require 'project nil 'noerror) | ||
| 250 | (require 'seq) | ||
| 248 | (eval-when-compile (require 'subr-x)) ;For `string-empty-p'. | 251 | (eval-when-compile (require 'subr-x)) ;For `string-empty-p'. |
| 249 | 252 | ||
| 250 | ;; Avoid compiler warnings | 253 | ;; Avoid compiler warnings |
| @@ -2304,6 +2307,16 @@ virtualenv." | |||
| 2304 | "`compilation-error-regexp-alist' for inferior Python." | 2307 | "`compilation-error-regexp-alist' for inferior Python." |
| 2305 | :type '(alist regexp)) | 2308 | :type '(alist regexp)) |
| 2306 | 2309 | ||
| 2310 | (defcustom python-shell-dedicated nil | ||
| 2311 | "Whether to make Python shells dedicated by default. | ||
| 2312 | This option influences `run-python' when called without a prefix | ||
| 2313 | argument. If `buffer' or `project', create a Python shell | ||
| 2314 | dedicated to the current buffer or its project (if one is found)." | ||
| 2315 | :version "29.1" | ||
| 2316 | :type '(choice (const :tag "To buffer" buffer) | ||
| 2317 | (const :tag "To project" project) | ||
| 2318 | (const :tag "Not dedicated" nil))) | ||
| 2319 | |||
| 2307 | (defvar python-shell-output-filter-in-progress nil) | 2320 | (defvar python-shell-output-filter-in-progress nil) |
| 2308 | (defvar python-shell-output-filter-buffer nil) | 2321 | (defvar python-shell-output-filter-buffer nil) |
| 2309 | 2322 | ||
| @@ -2666,12 +2679,19 @@ from `python-shell-prompt-regexp', | |||
| 2666 | 2679 | ||
| 2667 | (defun python-shell-get-process-name (dedicated) | 2680 | (defun python-shell-get-process-name (dedicated) |
| 2668 | "Calculate the appropriate process name for inferior Python process. | 2681 | "Calculate the appropriate process name for inferior Python process. |
| 2669 | If DEDICATED is t returns a string with the form | 2682 | If DEDICATED is nil, this is simply `python-shell-buffer-name'. |
| 2670 | `python-shell-buffer-name'[`buffer-name'] else returns the value | 2683 | If DEDICATED is `buffer' or `project', append the current buffer |
| 2671 | of `python-shell-buffer-name'." | 2684 | name respectively the current project name." |
| 2672 | (if dedicated | 2685 | (pcase dedicated |
| 2673 | (format "%s[%s]" python-shell-buffer-name (buffer-name)) | 2686 | ('nil python-shell-buffer-name) |
| 2674 | python-shell-buffer-name)) | 2687 | ('project |
| 2688 | (if-let ((proj (and (featurep 'project) | ||
| 2689 | (project-current)))) | ||
| 2690 | (format "%s[%s]" python-shell-buffer-name (file-name-nondirectory | ||
| 2691 | (directory-file-name | ||
| 2692 | (project-root proj)))) | ||
| 2693 | python-shell-buffer-name)) | ||
| 2694 | (_ (format "%s[%s]" python-shell-buffer-name (buffer-name))))) | ||
| 2675 | 2695 | ||
| 2676 | (defun python-shell-internal-get-process-name () | 2696 | (defun python-shell-internal-get-process-name () |
| 2677 | "Calculate the appropriate process name for Internal Python process. | 2697 | "Calculate the appropriate process name for Internal Python process. |
| @@ -3129,8 +3149,8 @@ killed." | |||
| 3129 | Argument CMD defaults to `python-shell-calculate-command' return | 3149 | Argument CMD defaults to `python-shell-calculate-command' return |
| 3130 | value. When called interactively with `prefix-arg', it allows | 3150 | value. When called interactively with `prefix-arg', it allows |
| 3131 | the user to edit such value and choose whether the interpreter | 3151 | the user to edit such value and choose whether the interpreter |
| 3132 | should be DEDICATED for the current buffer. When numeric prefix | 3152 | should be DEDICATED to the current buffer or project. When |
| 3133 | arg is other than 0 or 4 do not SHOW. | 3153 | numeric prefix arg is other than 0 or 4 do not SHOW. |
| 3134 | 3154 | ||
| 3135 | For a given buffer and same values of DEDICATED, if a process is | 3155 | For a given buffer and same values of DEDICATED, if a process is |
| 3136 | already running for it, it will do nothing. This means that if | 3156 | already running for it, it will do nothing. This means that if |
| @@ -3144,13 +3164,25 @@ process buffer for a list of commands.)" | |||
| 3144 | (if current-prefix-arg | 3164 | (if current-prefix-arg |
| 3145 | (list | 3165 | (list |
| 3146 | (read-shell-command "Run Python: " (python-shell-calculate-command)) | 3166 | (read-shell-command "Run Python: " (python-shell-calculate-command)) |
| 3147 | (y-or-n-p "Make dedicated process? ") | 3167 | (alist-get (car (read-multiple-choice "Make dedicated process?" |
| 3168 | '((?b "to buffer") | ||
| 3169 | (?p "to project") | ||
| 3170 | (?n "no")))) | ||
| 3171 | '((?b . buffer) (?p . project))) | ||
| 3148 | (= (prefix-numeric-value current-prefix-arg) 4)) | 3172 | (= (prefix-numeric-value current-prefix-arg) 4)) |
| 3149 | (list (python-shell-calculate-command) nil t))) | 3173 | (list (python-shell-calculate-command) |
| 3150 | (let ((buffer | 3174 | python-shell-dedicated |
| 3151 | (python-shell-make-comint | 3175 | t))) |
| 3152 | (or cmd (python-shell-calculate-command)) | 3176 | (let* ((project (and (eq 'project dedicated) |
| 3153 | (python-shell-get-process-name dedicated) show))) | 3177 | (featurep 'project) |
| 3178 | (project-current t))) | ||
| 3179 | (default-directory (if project | ||
| 3180 | (project-root project) | ||
| 3181 | default-directory)) | ||
| 3182 | (buffer (python-shell-make-comint | ||
| 3183 | (or cmd (python-shell-calculate-command)) | ||
| 3184 | (python-shell-get-process-name dedicated) | ||
| 3185 | show))) | ||
| 3154 | (get-buffer-process buffer))) | 3186 | (get-buffer-process buffer))) |
| 3155 | 3187 | ||
| 3156 | (defun run-python-internal () | 3188 | (defun run-python-internal () |
| @@ -3180,15 +3212,13 @@ startup." | |||
| 3180 | If current buffer is in `inferior-python-mode', return it." | 3212 | If current buffer is in `inferior-python-mode', return it." |
| 3181 | (if (derived-mode-p 'inferior-python-mode) | 3213 | (if (derived-mode-p 'inferior-python-mode) |
| 3182 | (current-buffer) | 3214 | (current-buffer) |
| 3183 | (let* ((dedicated-proc-name (python-shell-get-process-name t)) | 3215 | (seq-some |
| 3184 | (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name)) | 3216 | (lambda (dedicated) |
| 3185 | (global-proc-name (python-shell-get-process-name nil)) | 3217 | (let* ((proc-name (python-shell-get-process-name dedicated)) |
| 3186 | (global-proc-buffer-name (format "*%s*" global-proc-name)) | 3218 | (buffer-name (format "*%s*" proc-name))) |
| 3187 | (dedicated-running (comint-check-proc dedicated-proc-buffer-name)) | 3219 | (when (comint-check-proc buffer-name) |
| 3188 | (global-running (comint-check-proc global-proc-buffer-name))) | 3220 | buffer-name))) |
| 3189 | ;; Always prefer dedicated | 3221 | '(buffer project nil)))) |
| 3190 | (or (and dedicated-running dedicated-proc-buffer-name) | ||
| 3191 | (and global-running global-proc-buffer-name))))) | ||
| 3192 | 3222 | ||
| 3193 | (defun python-shell-get-process () | 3223 | (defun python-shell-get-process () |
| 3194 | "Return inferior Python process for current buffer." | 3224 | "Return inferior Python process for current buffer." |