(if any), so that the ignore rules for that repository are used, and
the file listing's performance is still optimized.
+*** New commands 'project-any-command' and 'project-prefix-or-any-command'.
+The former is now bound to 'C-x p o' by default.
+The latter is designed primarily for use as a value of
+'project-switch-commands'. If instead of a short menu you prefer to
+have access to all keys defined inside 'project-prefix-map', as well
+as global bindings (to run other commands inside the project root),
+you can add this to your init script:
+
+ (setq project-switch-commands #'project-prefix-or-any-command)
+
** JS Mode
The binding 'M-.' has been removed from the major mode keymaps in
'js-mode' and 'js-ts-mode', having it default to the global binding
(define-key map "G" 'project-or-external-find-regexp)
(define-key map "r" 'project-query-replace-regexp)
(define-key map "x" 'project-execute-extended-command)
+ (define-key map "o" 'project-any-command)
(define-key map "\C-b" 'project-list-buffers)
map)
"Keymap for project commands.")
(let ((default-directory (project-root (project-current t))))
(call-interactively #'execute-extended-command)))
+;;;###autoload
+(defun project-any-command (&optional overriding-map prompt-format)
+ "Run the next command in the current project.
+If the command is in `project-prefix-map', it gets passed that
+info with `project-current-directory-override'. Otherwise,
+`default-directory' is temporarily set to the current project's
+root.
+
+If OVERRIDING-MAP is non-nil, it will be used as
+`overriding-local-map' to provide shorter bindings from that map
+which will take priority over the global ones."
+ (interactive)
+ (let* ((pr (project-current t))
+ (prompt-format (or prompt-format "[execute in %s]:"))
+ (command (let ((overriding-local-map overriding-map))
+ (key-binding (read-key-sequence
+ (format prompt-format (project-root pr)))
+ t)))
+ (root (project-root pr))
+ found)
+ (when command
+ ;; We could also check the command name against "\\`project-",
+ ;; and/or (get command 'project-command).
+ (map-keymap
+ (lambda (_evt cmd) (if (eq cmd command) (setq found t)))
+ project-prefix-map)
+ (if found
+ (let ((project-current-directory-override root))
+ (call-interactively command))
+ (let ((default-directory root))
+ (call-interactively command))))))
+
+;;;###autoload
+(defun project-prefix-or-any-command ()
+ "Run the next command in the current project.
+Works like `project-any-command', but also mixes in the shorter
+bindings from `project-prefix-map'."
+ (interactive)
+ (project-any-command project-prefix-map "[execute in %s]:"))
+
(defun project-remember-projects-under (dir &optional recursive)
"Index all projects below a directory DIR.
If RECURSIVE is non-nil, recurse into all subdirectories to find
(project-find-regexp "Find regexp")
(project-find-dir "Find directory")
(project-vc-dir "VC-Dir")
- (project-eshell "Eshell"))
+ (project-eshell "Eshell")
+ (project-any-command "Other"))
"Alist mapping commands to descriptions.
Used by `project-switch-project' to construct a dispatch menu of
commands available upon \"switching\" to another project.
(choice :tag "Key to press"
(const :tag "Infer from the keymap" nil)
(character :tag "Explicit key"))))
- (symbol :tag "Single command")))
+ (const :tag "Use both short keys and global bindings"
+ project-prefix-or-any-command)
+ (symbol :tag "Custom command")))
(defcustom project-switch-use-entire-map nil
"Whether `project-switch-project' will use the entire `project-prefix-map'.