Subject: Re: bug#63469: 29.0.90; project.el doesn't add menu-bar entries

From: Juri Linkov <[email-masked]>
Date: Mon, 22 May 2023 20:48:08 +0300

>> >> +(define-minor-mode project-mode
>> >> +  "Toggle display of project menu in the project-aware buffers."
>> >> +  :lighter " Pro"
>> >> +  :keymap (define-keymap "<menu-bar>" project-mode-menu))
>> >
>> > If this mode is only for showing the menu, then at least the mode's
>> > name should reflect that.
>>
>> It can be used for anything.  For example, to display the project name
>> on the mode-line.  (Then better to cache the project name in a new
>> buffer-local variable.)
>
> I don't see anything but the menu in the patch you suggested.  I
> understand that in principle we could do many things there, but if you
> are proposing a real patch, not just an initial idea, please show all
> of the code you want to include in this mode.

Actually I miss this feature very much.  There is already the mode-line
indication with the VC system name and the VC branch name, but
no indication with a project name, so similar files
in different projects all are showing the same "Git-master".

Now here is the implementation of 'project-mode' based on 'vc-mode',
and 'project-menu-entry' based on 'vc-menu-entry' that shows
a project name alongside of vc info, and the mouse click opens
the project menu using 'menu-bar-project-menu' implemented by Spencer.

diff --git a/lisp/bindings.el b/lisp/bindings.el
index c77b64c05da..ba9f44b920c 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -616,6 +616,7 @@ mode-line-end-spaces
 	     "   "
 	     'mode-line-position
 	     '(vc-mode vc-mode)
+	     '(project-mode project-name)
 	     "  "
 	     'mode-line-modes
 	     'mode-line-misc-info
diff --git a/lisp/desktop.el b/lisp/desktop.el
index 6aacb85c12c..6198441d788 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -547,6 +547,7 @@ desktop-minor-mode-table
   '((defining-kbd-macro nil)
     (isearch-mode nil)
     (vc-mode nil)
+    (project-mode nil)
     (vc-dir-mode nil)
     (erc-track-minor-mode nil)
     (savehist-mode nil))
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 7c51778d5d4..06bd0d09b8e 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -1883,5 +1908,47 @@ project-switch-project
     (let ((project-current-directory-override dir))
       (call-interactively command))))
 
+;;; Project mode
+
+;; Tell Emacs about this new kind of minor mode
+(add-to-list 'minor-mode-alist '(project-mode project-name))
+
+(defvar project-name nil
+  "The project name of the current buffer when it belongs to a project.")
+
+;;;###autoload
+(put 'project-name 'risky-local-variable t)
+(put 'project-name 'permanent-local t)
+
+(defvar project-menu-entry
+  `(menu-item ,(purecopy "Project") ,menu-bar-project-menu))
+
+(defconst project-mode-line-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [mode-line down-mouse-1] project-menu-entry)
+    map))
+
+;;;###autoload
+(define-minor-mode project-mode
+  "Toggle display of project menu in the project-aware buffers."
+  (if project-mode
+      (setq-local project-name (concat
+	                        " "
+	                        (propertize
+	                         (project-name (project-current))
+	                         'mouse-face 'mode-line-highlight
+	                         'local-map project-mode-line-map)))))
+
+(defun project-mode--turn-on ()
+  "Turn on `project-mode' in all pertinent buffers."
+  (when (project-current)
+    (project-mode 1)))
+
+;;;###autoload
+(define-globalized-minor-mode global-project-mode
+  project-mode project-mode--turn-on
+  :group 'project
+  :version "30.1")
+
 (provide 'project)
 ;;; project.el ends here