在调用 ivy-read 的时候显示 minibuffer 里绑定的按键

最近发现 ivy/counsel 内置了一些有趣的功能, 之前一直没有发现.

比如在调用 counsel-find-file 的时候按 $ 键可以从环境变量里读一个路径.

于是写了一个小函数, 可以在每次调用 ivy-read 的时候, 在 lv-window 里显示当前 minibuffer 里绑定了那些按键, 这样就不会忘记一些内置功能了 :rofl:.

(require 'dash)
(require 'lv)

(defun editor//display-keys--collect (-keymap)
  (let (keys)
    (when -keymap
      (cl--map-keymap-recursively
       (lambda (key definition)
         (unless (eq (aref key 0) 'remap) ; skip remap
           (push (cons (key-description key) definition) keys)))
       -keymap))
    (cl-loop
     for (definition . items) in (-group-by #'cdr keys)
     collect
     (format "[%s %s]"
             (mapconcat
              (lambda (item)
                (propertize (car item) 'face 'font-lock-builtin-face))
              items
              "/")
             (cond ((symbolp definition)
                    definition)
                   ((functionp definition)
                    "<anonymous>")
                   (t "<error>"))))))

(defvar editor-display-help-max-width 160)
(defun editor//display-keys ()
  (when-let ((keymap (ivy-state-keymap ivy-last))
             (keys (editor//display-keys--collect keymap)))
    (let ((max-width (min (frame-width) editor-display-help-max-width))
          (width 0)
          (strings))
      (dolist (key keys)
        (when (> (+ (length key) width) max-width)
          (push "\n" strings)
          (setq width 0))
        (cl-incf width (length key))
        (push key strings))
      (lv-message "%s" (string-join (nreverse strings))))))

(add-to-list 'ivy-hooks-alist
             '(t . editor//display-keys))

1 个赞