0

The following function constructed by @dalanicolai has been adapted in a way that allows a user to automatically select a function affix name galaxy, protoc or typex, which is then bound to H-x.

What possibilities are there for improvement, enhancement, or simplification?

(defun command-affix (affix &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
   (list
    (let ( (cseq '("galaxy" "protoc" "typex")) )
      (completing-read "Affix: " cseq nil t "typex"))))

  (if (interactive-p)
      (progn
        (setq unread-command-events (listify-key-sequence affix))
        (call-interactively #'execute-extended-command))
    (funcall #'execute-extended-command args)))

(global-set-key (kbd "H-x") #'command-affix)
Dilna
  • 1,173
  • 3
  • 10
  • If you use a completion framework like `ivy/counsel` then you can simply replace the string after `listify-key-sequence` by some regexp: `^\(protoc\|typex\|galaxy\)` – dalanicolai Aug 16 '22 at 02:33
  • It would be good to extend your function for those not using `ivy-council`. Will still have a look at the `ivy/counsel` solution as another possibility. – Dilna Aug 16 '22 at 02:43

2 Answers2

0

If you use Emacs version >= 28 then you could also use the read-extended-command-predicate:

(defun command-affix (affix &optional prefixarg)
  (interactive (list (completing-read "Select affix: "
                                      '(galaxy protoc typex)
                                      nil t "typex")
                     current-prefix-arg))
  (let ((read-extended-command-predicate
         (lambda (s _)
           (string-match affix (symbol-name s)))))
    (execute-extended-command prefixarg)))
dalanicolai
  • 6,108
  • 7
  • 23
  • I am looking for something close to the first implementation. Rather than just showing `M-x protoc`, I would get either `M-x protoc` or `M-x galaxy`, or `M-x typex`. Perhaps with a `completing-read` to select a specific leading name. Or some other idea you think might actually be better. – Dilna Aug 16 '22 at 03:39
  • Again, you are not clear. You say that you would like either `protoc`, `galaxy` or `typex`, but you do not mention any condition when you would like to get what. Therefore, I can not answer this. Please, when you mention functionalities you would like, then think about the conditions first, and mention them. I do not always want to ask. – dalanicolai Aug 16 '22 at 08:18
  • Have modified the code to include a `completing-read` call for the user to select the initial affix. One thought involves letting the user change the initial value through a customisation option, so ho would not have to change the code itself (except to increase or change the affix possibilities). – Dilna Aug 16 '22 at 08:24
0

The following is tested with

~$ emacs --version
GNU Emacs 29.0.50
Development version 8b31c18fc866 on master branch; build date 2022-08-10.

It is based on the following NEWS entry New key binding after 'M-x' or 'M-X': 'M-X'

;; Define M-C-S-x (= M-C-X)

(global-set-key
 (kbd "M-C-S-x")
 (defun my-execute-extended-command (prefixarg &optional
                                               command-name typed)
   (declare (interactive-only command-execute))
   (interactive
    (let ((execute-extended-command--last-typed nil))
      (list current-prefix-arg
            (read-extended-command "M-C-X ")
            execute-extended-command--last-typed)))
   (with-suppressed-warnings ((interactive-only execute-extended-command))
     (execute-extended-command prefixarg command-name typed))))

;; ... which completes on `my-cmds'

(add-to-list
 'extended-command-versions
 (list "M-C-X "
       (defun my-command-completion--command ()
         (lambda (symbol buffer)
           (memq symbol my-cmds)))))

;; ... which is a set of commands that starts with `table-' or
;; `org-table-'

(setq my-cmds
      (cl-loop with prefixes = (list "table-" "org-table-") ; change prefixes to your taste
               for sym being the symbols
               when (commandp sym)
               when (cl-some (lambda (prefix)
                               (string-prefix-p prefix (symbol-name sym)))
                             prefixes)
               collect sym))


  • I am not focused on displaying commands relevant to the current buffer. It is about getting to particular functionality rapidly (e.g. commands starting with `galaxy` or `typex`). Will try your solution. – Dilna Aug 16 '22 at 05:16
  • How do I run things with a key? – Dilna Aug 16 '22 at 05:18
  • See the bottom of the info page [`(info "(elisp) Interactive Call")`](https://knowyourphrase.com/you-can-lead-a-horse-to-water) –  Aug 16 '22 at 06:42
  • You would have to let me know how to use your code, because I do not know how to approach the functionality for testing. – Dilna Aug 16 '22 at 07:23