remove `declare' macro
[bpt/emacs.git] / lisp / subr2.el
1 (defvar called-interactively-p-functions nil
2 "Special hook called to skip special frames in `called-interactively-p'.
3 The functions are called with 3 arguments: (I FRAME1 FRAME2),
4 where FRAME1 is a \"current frame\", FRAME2 is the next frame,
5 I is the index of the frame after FRAME2. It should return nil
6 if those frames don't seem special and otherwise, it should return
7 the number of frames to skip (minus 1).")
8
9 (defconst internal--funcall-interactively
10 (symbol-function 'funcall-interactively))
11
12 (defun called-interactively-p (&optional kind)
13 nil)
14
15 ;; (defun called-interactively-p (&optional kind)
16 ;; "Return t if the containing function was called by `call-interactively'.
17 ;; If KIND is `interactive', then only return t if the call was made
18 ;; interactively by the user, i.e. not in `noninteractive' mode nor
19 ;; when `executing-kbd-macro'.
20 ;; If KIND is `any', on the other hand, it will return t for any kind of
21 ;; interactive call, including being called as the binding of a key or
22 ;; from a keyboard macro, even in `noninteractive' mode.
23
24 ;; This function is very brittle, it may fail to return the intended result when
25 ;; the code is debugged, advised, or instrumented in some form. Some macros and
26 ;; special forms (such as `condition-case') may also sometimes wrap their bodies
27 ;; in a `lambda', so any call to `called-interactively-p' from those bodies will
28 ;; indicate whether that lambda (rather than the surrounding function) was called
29 ;; interactively.
30
31 ;; Instead of using this function, it is cleaner and more reliable to give your
32 ;; function an extra optional argument whose `interactive' spec specifies
33 ;; non-nil unconditionally (\"p\" is a good way to do this), or via
34 ;; \(not (or executing-kbd-macro noninteractive)).
35
36 ;; The only known proper use of `interactive' for KIND is in deciding
37 ;; whether to display a helpful message, or how to display it. If you're
38 ;; thinking of using it for any other purpose, it is quite likely that
39 ;; you're making a mistake. Think: what do you want to do when the
40 ;; command is called from a keyboard macro?"
41 ;; (declare (advertised-calling-convention (kind) "23.1"))
42 ;; (when (not (and (eq kind 'interactive)
43 ;; (or executing-kbd-macro noninteractive)))
44 ;; (let* ((i 1) ;; 0 is the called-interactively-p frame.
45 ;; frame nextframe
46 ;; (get-next-frame
47 ;; (lambda ()
48 ;; (setq frame nextframe)
49 ;; (setq nextframe (backtrace-frame i 'called-interactively-p))
50 ;; ;; (message "Frame %d = %S" i nextframe)
51 ;; (setq i (1+ i)))))
52 ;; (funcall get-next-frame) ;; Get the first frame.
53 ;; (while
54 ;; ;; FIXME: The edebug and advice handling should be made modular and
55 ;; ;; provided directly by edebug.el and nadvice.el.
56 ;; (progn
57 ;; ;; frame =(backtrace-frame i-2)
58 ;; ;; nextframe=(backtrace-frame i-1)
59 ;; (funcall get-next-frame)
60 ;; ;; `pcase' would be a fairly good fit here, but it sometimes moves
61 ;; ;; branches within local functions, which then messes up the
62 ;; ;; `backtrace-frame' data we get,
63 ;; (or
64 ;; ;; Skip special forms (from non-compiled code).
65 ;; (and frame (null (car frame)))
66 ;; ;; Skip also `interactive-p' (because we don't want to know if
67 ;; ;; interactive-p was called interactively but if it's caller was)
68 ;; ;; and `byte-code' (idem; this appears in subexpressions of things
69 ;; ;; like condition-case, which are wrapped in a separate bytecode
70 ;; ;; chunk).
71 ;; ;; FIXME: For lexical-binding code, this is much worse,
72 ;; ;; because the frames look like "byte-code -> funcall -> #[...]",
73 ;; ;; which is not a reliable signature.
74 ;; (memq (nth 1 frame) '(interactive-p 'byte-code))
75 ;; ;; Skip package-specific stack-frames.
76 ;; (let ((skip (run-hook-with-args-until-success
77 ;; 'called-interactively-p-functions
78 ;; i frame nextframe)))
79 ;; (pcase skip
80 ;; (`nil nil)
81 ;; (`0 t)
82 ;; (_ (setq i (+ i skip -1)) (funcall get-next-frame)))))))
83 ;; ;; Now `frame' should be "the function from which we were called".
84 ;; (pcase (cons frame nextframe)
85 ;; ;; No subr calls `interactive-p', so we can rule that out.
86 ;; (`((,_ ,(pred (lambda (f) (subrp (indirect-function f)))) . ,_) . ,_) nil)
87 ;; ;; In case #<subr funcall-interactively> without going through the
88 ;; ;; `funcall-interactively' symbol (bug#3984).
89 ;; (`(,_ . (t ,(pred (lambda (f)
90 ;; (eq internal--funcall-interactively
91 ;; (indirect-function f))))
92 ;; . ,_))
93 ;; t)))))
94
95 (defun interactive-p ()
96 "Return t if the containing function was run directly by user input.
97 This means that the function was called with `call-interactively'
98 \(which includes being called as the binding of a key)
99 and input is currently coming from the keyboard (not a keyboard macro),
100 and Emacs is not running in batch mode (`noninteractive' is nil).
101
102 The only known proper use of `interactive-p' is in deciding whether to
103 display a helpful message, or how to display it. If you're thinking
104 of using it for any other purpose, it is quite likely that you're
105 making a mistake. Think: what do you want to do when the command is
106 called from a keyboard macro or in batch mode?
107
108 To test whether your function was called with `call-interactively',
109 either (i) add an extra optional argument and give it an `interactive'
110 spec that specifies non-nil unconditionally (such as \"p\"); or (ii)
111 use `called-interactively-p'."
112 (declare (obsolete called-interactively-p "23.2"))
113 (called-interactively-p 'interactive))
114 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
115
116 (defvar called-interactively-p-functions nil
117 "Special hook called to skip special frames in `called-interactively-p'.
118 The functions are called with 3 arguments: (I FRAME1 FRAME2),
119 where FRAME1 is a \"current frame\", FRAME2 is the next frame,
120 I is the index of the frame after FRAME2. It should return nil
121 if those frames don't seem special and otherwise, it should return
122 the number of frames to skip (minus 1).")
123
124 (defun interactive-p ()
125 "Return t if the containing function was run directly by user input.
126 This means that the function was called with `call-interactively'
127 \(which includes being called as the binding of a key)
128 and input is currently coming from the keyboard (not a keyboard macro),
129 and Emacs is not running in batch mode (`noninteractive' is nil).
130
131 The only known proper use of `interactive-p' is in deciding whether to
132 display a helpful message, or how to display it. If you're thinking
133 of using it for any other purpose, it is quite likely that you're
134 making a mistake. Think: what do you want to do when the command is
135 called from a keyboard macro or in batch mode?
136
137 To test whether your function was called with `call-interactively',
138 either (i) add an extra optional argument and give it an `interactive'
139 spec that specifies non-nil unconditionally (such as \"p\"); or (ii)
140 use `called-interactively-p'."
141 (declare (obsolete called-interactively-p "23.2"))
142 (called-interactively-p 'interactive))