emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Why don't let bound values die?


From: Lennart Borgman
Subject: Why don't let bound values die?
Date: Fri, 3 Sep 2010 20:11:28 +0200

I have a small utility in nXhtml to save commands accessed through the
menus to M-x history list. (We discussed such a feature here a while
ago.) Recently I noticed problems with menu items defined by easymenu.
Org-mode uses this, for example to define the menu item "Org -
Hyperlinks - Literal links".

When accessing this menu item a temporary command symbol is set up (if
I understand this correctly), something like menu-function-21. This
symbol then shows up in this-command (in pre-command-hook).

(BTW, it is in my opinion a bit annoying that anonymous functions are
used in the menus. Should not at least easymenu discourage this?)

I tried to avoid adding such symbols like menu-function-21 to the
history list. I thought it would be gone if I looked for it in a
run-with-idle-timer timer, but it is not. I do not understand why and
would be glad for an explanation. (I fixed it by saving the symbol
name and checking for it with intern-soft.)

Here is the code in question:


(defvar ourcomments-M-x-menu-timer nil)
(defvar ourcomments-M-x-menu-this-command nil)
(defun ourcomments-M-x-menu-pre ()
  "Add menu command to M-x history."
  (let ((is-menu-command (equal '(menu-bar)
                                (when (< 0 (length (this-command-keys-vector)))
                                  (elt (this-command-keys-vector) 0)))))
    (when (and is-menu-command
               (not (memq this-command '(ourcomments-M-x-menu-mode))))
      (when (timerp ourcomments-M-x-menu-timer)
        (cancel-timer ourcomments-M-x-menu-timer))
      (message "this-command=%s" this-command)
      (setq ourcomments-M-x-menu-this-command (symbol-name this-command))
      (setq ourcomments-M-x-menu-timer
            (run-with-idle-timer 3 nil 'ourcomments-M-x-menu-in-timer)))))

(defun ourcomments-M-x-menu-in-timer ()
  "Add MAYBE-COMMAND to M-x history if it is a command."
  (condition-case err
      (ourcomments-M-x-menu-in-timer-1)
    (error (message "M-x-menu-in-timer ERROR: %s" (error-message-string err)))))

(defun ourcomments-M-x-menu-in-timer-1 ()
  (setq ourcomments-M-x-menu-timer nil)
  ;; Fix-me: temporary commands, like from "Org - Hyperlinks - Literal
  ;; links" are still defined here, why???
  ;; Using symbol-name + intern-soft helped, but why is it necessary?
  (let ((maybe-command (intern-soft ourcomments-M-x-menu-this-command)))
    (message "maybe-command=%s, %s" maybe-command (commandp maybe-command))
    ;; this-command could have been let bound so check it:
    (when (commandp maybe-command)
      (let ((pre-len (length extended-command-history)))
        (pushnew (symbol-name maybe-command) extended-command-history)
        (when (< pre-len (length extended-command-history))
          ;; Give a temporary message
          (let ((msg
                 (format "(Added %s to M-x history so you can run it
from there)"
                         maybe-command)))
            (with-temp-message (propertize msg 'face 'file-name-shadow)
              (sit-for 3))))))))

;;;###autoload
(define-minor-mode ourcomments-M-x-menu-mode
  "Add commands started from Emacs menus to M-x history.
The purpose of this is to make it easier to redo them and easier
to learn how to do them from the command line \(which is often
faster if you know how to do it).

Only commands that are not already in M-x history are added."
  :global t
  (if ourcomments-M-x-menu-mode
      (add-hook 'pre-command-hook 'ourcomments-M-x-menu-pre)
    (remove-hook 'pre-command-hook 'ourcomments-M-x-menu-pre)))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]