diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 944b886ce5..f61a3ebea6 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -917,6 +917,22 @@ project-vc-dir (interactive) (vc-dir (project-root (project-current t)))) +(defvar-local project--origin-project-root nil) + +(defun project--find-existing-buffer (mode root) + (seq-find + (lambda (buf) + (and + (buffer-live-p buf) + (provided-mode-derived-p + (buffer-local-value 'major-mode buf) + mode) + (equal (buffer-local-value + 'project--origin-project-root + buf) + root))) + (buffer-list))) + ;;;###autoload (defun project-shell () "Start an inferior shell in the current project's root directory. @@ -926,15 +942,12 @@ project-shell if one already exists." (interactive) (let* ((default-directory (project-root (project-current t))) - (default-project-shell-name - (concat "*" (file-name-nondirectory - (directory-file-name - (file-name-directory default-directory))) - "-shell*")) - (shell-buffer (get-buffer default-project-shell-name))) - (if (and shell-buffer (not current-prefix-arg)) - (pop-to-buffer shell-buffer) - (shell (generate-new-buffer-name default-project-shell-name))))) + (existing-buffer (project--find-existing-buffer + 'shell-mode default-directory))) + (if (and existing-buffer (not current-prefix-arg)) + (pop-to-buffer existing-buffer) + (shell (create-file-buffer (expand-file-name "*shell*"))) + (setq project--origin-project-root default-directory)))) ;;;###autoload (defun project-eshell () @@ -946,15 +959,14 @@ project-eshell (interactive) (defvar eshell-buffer-name) (let* ((default-directory (project-root (project-current t))) - (eshell-buffer-name - (concat "*" (file-name-nondirectory - (directory-file-name - (file-name-directory default-directory))) - "-eshell*")) - (eshell-buffer (get-buffer eshell-buffer-name))) - (if (and eshell-buffer (not current-prefix-arg)) - (pop-to-buffer eshell-buffer) - (eshell t)))) + (existing-buffer (project--find-existing-buffer + 'eshell-mode default-directory))) + (if (and existing-buffer (not current-prefix-arg)) + (pop-to-buffer existing-buffer) + (let ((eshell-buffer-name + (buffer-name (create-file-buffer (expand-file-name "*eshell*"))))) + (eshell) + (setq project--origin-project-root default-directory))))) ;;;###autoload (defun project-async-shell-command ()