embark icon indicating copy to clipboard operation
embark copied to clipboard

Add mouse prompter

Open minad opened this issue 4 years ago • 2 comments

This would complicate the internals though, since for multiple targets we would want nested submenus instead of cycling.

(x-popup-menu (list '(0 0) (selected-window))
              '("Embark" ("Actions" ("Action1" . act1) ("Action2" . act2))))

See also #307.

minad avatar Jul 29 '21 23:07 minad

Simple demo. Just dropping this here. Not sure if this can actually be made usable or if it is rather a example of how inconvenient these large menu context menus become in comparison to a key-driven approach. Still nice for exploration maybe.

;;; -*- lexical-binding: t -*-

(require 'subr-x)
(require 'embark)

(defvar embark-mouse-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map [mouse-3] nil)
    (define-key map [down-mouse-3]
      '(menu-item "Embark" ignore :filter embark-mouse-menu))
    map)
  "Embark mouse mode map.")

(defun embark-mouse-menu (_)
  (when-let* ((posn (event-start last-input-event))
	      (pt (posn-point posn)))
    (with-demoted-errors "Error: %S"
      (save-excursion
        (goto-char pt)
        (when-let (targets (embark--targets))
          (let ((menu (make-sparse-keymap (propertize "Embark" 'hide t))))
            (dolist (target targets)
              (let ((actions (make-sparse-keymap)))
                (map-keymap
                 (lambda (key def)
                   (unless (memq def '(negative-argument digit-argument))
                     (define-key actions (vector key)
                       (cons (format "%S (%s)" def (single-key-description key))
                             (lambda ()
                               (interactive)
                               (goto-char pt)
                               (embark--act def target))))))
                 (keymap-canonicalize (embark--action-keymap (plist-get target :type) nil)))
                (define-key menu (vector (intern (format "target-%s" (plist-get target :type))))
                  (cons (format "%s %s" (plist-get target :type)
                                (truncate-string-to-width
                                 (substring-no-properties (embark--truncate-target (plist-get target :target)))
                                 20 0 nil t))
                        actions))))
            menu))))))

(define-minor-mode embark-mouse-mode
  "Embark mouse mode."
  :global t :group 'mouse)

minad avatar Feb 18 '22 16:02 minad

That's pretty neat! Maybe just some "pagination" is enough to make it useable: limit each submenu to, say, 10 items, and an item "More..." that shows the next 10, and so on.

oantolin avatar Feb 19 '22 02:02 oantolin

I think this could be a thing for the wiki. Emacs 28 offers a context menu where this could be hooked into. However given the richness of Embark, mouse manipulation just doesn't seem convenient enough.

minad avatar Apr 22 '23 04:04 minad