From c9f20a5a547631ab12cd3cf8da2ca51b71cfb28e Mon Sep 17 00:00:00 2001 From: Philip K Date: Thu, 18 Jun 2020 16:06:19 +0200 Subject: [PATCH 1/2] Use same keys in project-switch-project as in project-prefix-map * project.el (project-switch-commands): Convert to user option and change structure. (project-switch-use-entire-map): Add new option. (project--keymap-prompt): Adapt to change in project-switch-commands (project-switch-project): Use project-prefix-map instead of project-switch-commands to query valid commands. --- lisp/progmodes/project.el | 63 +++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 67ce3dc7d9..4f0233c8b7 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -974,27 +974,46 @@ project-known-project-roots ;;; Project switching ;;;###autoload -(defvar project-switch-commands - '((?f "Find file" project-find-file) - (?g "Find regexp" project-find-regexp) - (?d "Dired" project-dired) - (?v "VC-Dir" project-vc-dir) - (?e "Eshell" project-eshell)) - "Alist mapping keys to project switching menu entries. +(defcustom project-switch-commands + '((project-find-file . "Find file") + (project-find-regexp . "Find regexp") + (project-dired . "Dired") + (project-vc-dir . "VC-Dir") + (project-shell . "Shell") + (project-eshell . "Eshell")) + "Alist mapping commands to descriptions. Used by `project-switch-project' to construct a dispatch menu of commands available upon \"switching\" to another project. -Each element is of the form (KEY LABEL COMMAND), where COMMAND is the -command to run when KEY is pressed. LABEL is used to distinguish -the menu entries in the dispatch menu.") +Each element looks like (COMMAND LABEL), where COMMAND should be +bound in `project-prefix-map'. LABEL is used to distinguish the +choice in the dispatch menu." + :type '(alist :key-type function + :value-type string) + :options (mapcan (lambda (ent) + (and (commandp (cdr ent)) + (list (cdr ent)))) + (cdr project-prefix-map)) + :version "28.1") + +(defcustom project-switch-use-entire-map t + "Make `project-switch-project' use entire `project-prefix-map'. +If nil, `project-switch-project' will only recognize commands +listed in `project-switch-commands', and signal an error when +others are invoked. Otherwise, all keys in +`project-switch-commands', are legal even if they aren't listed +in the minibuffer." + :type 'bool + :version "28.1") (defun project--keymap-prompt () "Return a prompt for the project swithing dispatch menu." (mapconcat - (pcase-lambda (`(,key ,label)) - (format "[%s] %s" - (propertize (key-description `(,key)) 'face 'bold) - label)) + (pcase-lambda (`(,cmd . ,label)) + (let ((key (where-is-internal cmd project-prefix-map t))) + (format "[%s] %s" + (propertize (key-description key) 'face 'bold) + label))) project-switch-commands " ")) @@ -1004,14 +1023,14 @@ project-switch-project The available commands are presented as a dispatch menu made from `project-switch-commands'." (interactive) - (let ((dir (project-prompt-project-dir)) - (choice nil)) - (while (not choice) - (setq choice (assq (read-event (project--keymap-prompt)) - project-switch-commands))) - (let ((default-directory dir) - (project-current-inhibit-prompt t)) - (call-interactively (nth 2 choice))))) + (let* ((default-directory (project-prompt-project-dir)) + (project-current-inhibit-prompt t) + (key (read-key-sequence-vector (project--keymap-prompt))) + (cmd (lookup-key project-prefix-map key))) + (if (and cmd (or project-switch-use-entire-map + (assq cmd project-switch-commands))) + (call-interactively cmd) + (user-error "%s is undefined" (key-description key))))) (provide 'project) ;;; project.el ends here -- 2.27.0