0

In reference to my previous question Unwanted Focus Shift when Clicking Menu Functions in Emacs Mode Line, I have found a possible solution:

(defmacro with-ignore-mouse-events (&rest body)
  "Macro to ignore mouse events before evaluating BODY."
  `(progn
     (when (input-pending-p)
       (let ((event (read-event)))
         (if (mouse-event-p event)
             (let ((button (event-basic-type event)))
               (if (eq button 'mouse-1)
                   (ignore)
                 (setq unread-command-events (list event))))
           (setq unread-command-events (list event)))))
     ,@body))

(defun mwe-function-1 () "MWE function 1" (interactive) (unwind-protect (query-replace "foo" "bar" nil (point-min) (point-max)) ;; UNWINDFORMS (read-string "function 1 executed")))

(defun mwe-function-1* () (interactive) (with-ignore-mouse-events (mwe-function-1)))

(defun mwe-function-2 () "MWE function 3" (interactive) (unwind-protect (query-replace "foo" "bar" nil (point-min) (point-max)) ;; UNWINDFORMS (read-string "function 2 executed")))

(defun mwe-function-3 () "MWE function 3" (interactive) (unwind-protect (query-replace "foo" "bar" nil (point-min) (point-max)) ;; UNWINDFORMS (read-string "function 3 executed")))

(define-minor-mode mwe-mode "MWE mode" :init-value nil :lighter (:eval (propertize " MWE " 'face '(:foreground "RoyalBlue" :background "DarkGoldenrod1")))

:keymap `( (,(kbd "<C-kp-1>") . mwe-function) )

(if mwe-mode (easy-menu-define mwe-menu mwe-mode-map "MWE" '("MWE mode" ;; I want the menu on mode-line only: :visible (not (eq (framep (selected-frame)) 'x)) ["mwe-function-1" mwe-function-1* :help "mwe-function 1"] ["mwe-function-2" mwe-function-2 :help "mwe-function 2"] ["mwe-function-3" mwe-function-3 :help "mwe-function 3"])) t))

I defined a starred version of my mwe-function-1 wrapped with the with-ignore-mouse-events macro. I made some test and this seems to fix my problem.

My question is: Is there a way to generate a starred version (other suffixes are also ok) of a given function without explicitly define it?

What I need is that SOME functions called using the menu must be wrapped with the with-ignore-mouse-events macro. Using a lambda function in the menu definition could also be good form me, but the best would be using a "suffix" without the need to define the "suffixed" function.

Is that possible?

I'm open to other solutions.

Note added. I mean I want to use the starred version of my mwe-function-1 but don't want to define it. I'm searching for a method to wrap SOME of my function with my macro when called from the menu. I though that a system to "autodefine" these functions could be a solution but I don't know if it is possible.

I mean when the "compiler" finds an undefined symbol with a given suffix it defines the function wrapping the "basename" function with the given macro.

I will follow Phils suggestion:

If you have a list of commands to create derivatives of, and the same macro is applicable in each case, then simply loop over the list, generating a derivative for each one via your macro.

Gabriele
  • 1,554
  • 9
  • 21
  • 1
    You can write a macro that takes the unstarred symbol as argument and produces the starred version; you can then call the macro as needed. It would be up to you to manually adjust the menu to cal it, instead of calling the unstarred version. Is that what you are asking? – NickD Feb 18 '24 at 13:50
  • As @phils said in his answer, the question isn't clear. Just what are you asking? – Drew Feb 18 '24 at 15:50
  • @Drew I updated my question. I hope that It is clearer now. – Gabriele Feb 18 '24 at 17:46
  • @NickD I'll try your idea too. – Gabriele Feb 18 '24 at 17:49

1 Answers1

1

Based on the discussion in the comments, the goal was to create a number of derivative commands without verbose per-command function definitions in the code, at which point my suggestion was:

If you have a list of commands to create derivatives of, and the same macro is applicable in each case, then simply loop over the list, generating a derivative for each one via your macro.

(The sample code from my original answer provides some insight into how one could do that, and it was discussed in more detail in a separate question.)


Original answer follows:

I find the question confusing, but I think you might be asking how to name a function without that name being globally visible, in which case you're asking about uninterned symbols.

The interned symbols constitute the set of globally-known symbols (as held in the main obarray), but you can create uninterned symbols as well. E.g.:

(let ((sym (make-symbol "your-name-here")))
  (defalias sym
    (lambda () (interactive) (do-the-thing))
    "Do the thing.")
  (global-set-key (kbd "C-c c") sym))
C-c c runs the command your-name-here (found in global-map), which is
an interactive Lisp closure.

It is bound to C-c c.

(your-name-here)

Do the thing.

(symbol-function 'your-name-here)
nil

You want to read C-hig (elisp)Creating Symbols

Take care that your system is self-documenting if you're using this kind of approach, as it's obviously liable to cause confusion.

phils
  • 50,977
  • 3
  • 79
  • 122
  • I'm sorry for the confusion. I mean I want to use the starred version of my mwe-function-1 but don't want to define it. I'm searching for a method to wrap SOME of my function with my macro when called from the menu. I though that a system to "autodefine" these functions could be a solution but I don't know if it is possible. – Gabriele Feb 18 '24 at 10:09
  • I mean when the "compiler" finds an undefined symbol with a given suffix it defines the function wrapping the basename function with the given macro. – Gabriele Feb 18 '24 at 10:11
  • There's no such thing, but you can simply use the autoload mechanism. See C-h i g (elisp)Autoload. The real function will be defined by loading the library specified by the autoload stub. – phils Feb 18 '24 at 10:36
  • Ok, thanks. Your answer has nonetheless taught me something very useful. – Gabriele Feb 18 '24 at 10:41
  • Or you could define a function which can generate and call its own replacement function definition, and define your 'stub' functions in terms of that. Whatever you do, though, you do need to define something for each function -- if nothing has been defined for a given function name, calling that name is simply an error. – phils Feb 18 '24 at 10:46
  • Since my aim is to simplify code writing, I'll focus on finding a way to simplify "wrapping" functions in my macro when called through a menu built with easy-menu-define. Lamda function work but I'm searching for something "easier". – Gabriele Feb 18 '24 at 13:32
  • 1
    I'd recommend simply using derivative commands in the menu, and not trying to obfuscate anything. If you have a list of commands to create derivatives of, and the same macro is applicable in each case, then simply loop over the list, generating a derivative for each one via your macro. – phils Feb 18 '24 at 13:40
  • Please add your last comment to your answer and I'll accept it. Thank you. – Gabriele Feb 18 '24 at 17:43
  • Sure; I've done that now. – phils Feb 20 '24 at 04:09