1

When I run helm-M-x and enter characters, I like to see only those commands which has key-bindings. How I can achieve that? I like to have reverse functionality as well, ie.. commands without key-bindings.

Drew
  • 75,699
  • 9
  • 109
  • 225
aartist
  • 133
  • 5
  • 2
    I think an essential building block will be [`where-is-internal`](https://www.gnu.org/software/emacs/manual/html_node/elisp/Scanning-Keymaps.html). – Tobias Oct 22 '19 at 14:09
  • Besides `where-is-internal`, `substitute-command-keys` is another option, it's used by `helm-M-x`. – xuchunyang Oct 22 '19 at 15:48

1 Answers1

2

You can use the following command which is independent of the used completion framework because it uses completing-read:

(defun execute-binding+ (arg)
  "Completing read a command and execute it.

With ARG non-nil only present commands without a key binding
otherwise only those which have one."
  (interactive "P")
  (let ((cmd (completing-read
              "Command: "
              obarray
              (lambda (sym)
                (and (commandp sym)
                     (let ((key (where-is-internal sym nil t)))
                       (if arg (not key) key)))))))
    (when cmd
      (setq cmd (intern cmd))
      (setq this-command cmd)
      (setq real-this-command cmd)
      (command-execute cmd 'record))))

As requested here is a version which shows the key bindings inline:

(defun execute-binding+ (arg)
  "Completing read a command and execute it.

    With ARG non-nil only present commands without a key binding
    otherwise only those which have one."
  (interactive "P")
  (let ((coll nil))
    (mapatoms (lambda (sym)
                (when (commandp sym)
                  (let ((key (where-is-internal sym nil t)))
                    (cond ((and arg (not key))
                           (push sym coll))
                          ((and (not arg) key)
                           (push (format "%s (%s)" sym
                                         (key-description key))
                                  coll)))))))
    (let ((cmd (completing-read "Command: " coll)))
      (setq cmd (intern (car (split-string cmd))))
      (setq this-command cmd)
      (setq real-this-command cmd)
      (command-execute cmd 'record))))
clemera
  • 3,401
  • 13
  • 40
  • Thanks. This works nicely. Now how we can show key-bindings along with commands ? – aartist Oct 22 '19 at 16:59
  • @aartist I have added another version for you – clemera Oct 23 '19 at 12:10
  • Thank you Clemera. This is very nice. It can help me to remember my own keybindings. It also tells me where I need to do keybindings. Looking at this list, now I like to make a set of my favorite command and use that list for completion. !!! May be there is a way to select from the list to add to favorites. – aartist Oct 23 '19 at 13:40
  • @aartist You might also try the `which-key-M-x+` command I described [here](https://with-emacs.com/posts/ui-hacks/prefix-command-completion/). The post also describes how you can get completing read for prefix keys, too: `C-x C-h` will give you completion for commands under `C-x`. – clemera Oct 31 '19 at 15:52
  • Great idea and functions. which-key integration is really nice here. Very helpful to emacs users on every level. – aartist Nov 01 '19 at 12:09