| 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)) |