[Top][All Lists]

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

RE: Brittleness of called-interactively-p

From: T.V Raman
Subject: RE: Brittleness of called-interactively-p
Date: Thu, 16 Jul 2015 10:58:53 -0700

Apologies, the emacspeak implementation of  ems-interactive-p is in 
lisp/emacspeak-load-path.el it's fairly short and I'll append it here.

Re what failed with called-interactive-p -- from memory,  things like
ruby-mode that use backward-sexp internally during editting started
entering a recursive loop in that the emacspeak advice kept triggering
(and itself called backward-sexp again ) -- that was technically not
supposed to happen since the  advice was guarded by a
called-interactively-p check.

(defvar ems-called-interactively-p nil
  "Flag recording interactive calls.")

;; Record interactive calls:

(defsubst ems-record-interactive-p (f)
  "Predicate to test if we need to record interactive calls of
this function. Memoizes result for future use by placing a
property 'emacspeak on the function."
   ((not (symbolp f)) nil)
   ((get f 'emacspeak) t)
   ((ad-find-some-advice f 'any  "emacspeak")
    (put f 'emacspeak t))
   ((string-match "^\\(dt\\|emacspea\\)k" (symbol-name f))
    (put f 'emacspeak t))
   (t nil)))

(defadvice call-interactively (around emacspeak  pre act comp)
  "Set emacspeak  interactive flag if there is an advice."
  (let ((ems-called-interactively-p ems-called-interactively-p))
    (when (ems-record-interactive-p (ad-get-arg 0))
      (setq ems-called-interactively-p (ad-get-arg 0)))

(defsubst ems-interactive-p ()
  "Check our interactive flag.
Return T if set and we are called from the advice for the current
interactive command. Turn off the flag once used."
  (when ems-called-interactively-p      ; interactive call
    (let ((caller (second (backtrace-frame 1)))
          (caller-advice (ad-get-advice-info-field ems-called-interactively-p  
          (result nil))
      (setq result
            (or (eq caller caller-advice) ; called from our advice
                (eq ems-called-interactively-p caller ))) ; called from 
      (when result
        (setq ems-called-interactively-p nil) ; turn off now that we used  it

Drew Adams writes:
 > > Speaking from the perspective of developing Emacspeak:
 > > 
 > > Emacspeak uses the "is this an interactive call" heavily  -- it provides
 > > spoken feedback only if the call is interactive.
 > > 
 > > I originally implemented emacspeak starting in late 1994 and used the
 > > test (when (interactive-p)...) in all my code.
 > > 
 > > When interactive-p was deprecated and we moved to the new
 > > called-interactive-p -- I was unable to get the behavior I wanted using
 > > (called-interactive-p 'interactive) as  the test;  --  the code ended up
 > > chasing its tail given the heavy use of advice.
 > > 
 > > I worked around the problem by defining my own version of the
 > > interactive test -- see http://github.com/tvraman/emacspeak --
 > > specifically the implementation of function ems-interactive-p.
 > You might want to say which of the many (!) files in that directory
 > contains the definition of `ems-interactive-p'.  And perhaps tell us
 > why you mention it and, in particular, what is the "behavior [you]
 > wanted", and why.  You mention that `called-interactively-p' doesn't
 > work well enough for you when advice is involved, but some more info
 > about `ems-interactive-p' might be helpful.
 > FWIW, I still use `interactive-p' in much of my code, because the code
 > needs to work also with older Emacs versions.  And because I have never
 > noticed any problem, for this code anyway, with `interactive-p'.
 > What's more, the doc for `interactive-p' does not really tell you how
 > to replace it - it just says to use `called-interactively-p', without
 > any mention of which argument gives you the behavior you had previously
 > with `interactive-p' or similar-but-somehow-improved behavior.
 > `interactive-p' was indeed used heavily, over decades.  And it is no
 > doubt still in use quite a bit.  Too bad there is next-to-no guidance
 > on how to use `called-interactively-p' to replace it.



reply via email to

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