1

I am using M-x protoc to show me the interactive functions provided by the package protoc. Is it possible to have a shortcut for displaying protoc related functions without having to write protoc TAB after calling M-x?

For instance, the following fails

(global-set-key (kbd "H-x") (kbd "M-x protoc"))
Dilna
  • 1,173
  • 3
  • 10
  • Since I have taken you to task often about your questions, I wanted to acknowledge that this was a good one: interesting in itself plus it gave rise to a couple of enlightening answers and a couple of links to even more questions/answers that were equally interesting and enlightening. – NickD Aug 16 '22 at 02:17

2 Answers2

1

There is no association between functions (or variables) and the packages they were defined in, nor are packages even first–class objects. There is just the global environment and whatever functions (and variables) that have been defined therein.

However, by convention one names the functions and variables defined in a package with a prefix that contains or is at least similar to the package name, so all you have to do is enumerate the list of known symbols using mapatoms, searching for those that are fboundp and have the prefix you are looking for.

See chapter 9.3 Creating and Interning Symbols as well as the function documentation for mapatoms and fboundp for more information.

db48x
  • 15,741
  • 1
  • 19
  • 23
1

EDIT better alternative

A better alternative, provided in Emacs since version 28, is to use the read-extended-command-predicate to (pre-)filter the candidates listed by M-x:

(defun execute-my-extended-command (&optional prefixarg)
  (interactive "P")
  (let ((read-extended-command-predicate
         (lambda (s _)
           (string-match "protoc" (symbol-name s)))))
    (execute-extended-command prefixarg)))

I'll keep the old answer below, as it is also informative.

END EDIT

I don't understand unread-command-events very well, but from the answer here, I figured that you could use

(defun execute-my-extended-command (&rest args)
  "Read a command name to call, favoring commands that begin with `*'.

Like `execute-extended-command', but when called interactively, preload a
leading `*' into the minibuffer."
  (interactive)
  (if (interactive-p)
      (progn
        (setq unread-command-events (listify-key-sequence "protoc"))
        (call-interactively #'execute-extended-command))
    (funcall #'execute-extended-command args)))

Now you could bind that command to H-x (Wow, you have a hyper key!)

dalanicolai
  • 6,108
  • 7
  • 23