Allow `declare' to set the interactive-only property

* lisp/emacs-lisp/byte-run.el (defun-declarations-alist):
Add interactive-only.  Doc tweak.
(macro-declarations-alist): Doc tweak.

* lisp/subr.el (declare): Doc tweak (add xref to manual).

* lisp/comint.el (comint-run):
* lisp/files.el (insert-file-literally, insert-file):
* lisp/replace.el (replace-string, replace-regexp):
* lisp/simple.el (beginning-of-buffer, end-of-buffer, delete-backward-char)
(delete-forward-char, goto-line, insert-buffer, next-line)
(previous-line): Set interactive-only via declare.

* doc/lispref/functions.texi (Declare Form): Add interactive-only.

* doc/lispref/commands.texi (Defining Commands) Mention declare.

* etc/NEWS: Mention this.
This commit is contained in:
Glenn Morris 2014-03-22 15:12:52 -07:00
parent 299ccd03f9
commit 5076d27513
11 changed files with 57 additions and 21 deletions

View file

@ -1,5 +1,8 @@
2014-03-22 Glenn Morris <rgm@gnu.org>
* functions.texi (Declare Form): Add interactive-only.
* commands.texi (Defining Commands) Mention declare.
* commands.texi (Defining Commands): List interactive-only values.
2014-03-22 Eli Zaretskii <eliz@gnu.org>

View file

@ -122,10 +122,12 @@ function symbol's @code{interactive-form} property. A non-@code{nil}
value for this property takes precedence over any @code{interactive}
form in the function body itself. This feature is seldom used.
@anchor{The interactive-only property}
@cindex @code{interactive-only} property
Sometimes, a function is only intended to be called interactively,
never directly from Lisp. In that case, give the function a
non-@code{nil} @code{interactive-only} property. This causes the
non-@code{nil} @code{interactive-only} property, either directly
or via @code{declare} (@pxref{Declare Form}). This causes the
byte compiler to warn if the command is called from Lisp. The value
of the property can be: a string, which the byte-compiler will
use directly in its warning (it should end with a period,

View file

@ -1742,6 +1742,10 @@ Indent calls to this function or macro according to @var{indent-spec}.
This is typically used for macros, though it works for functions too.
@xref{Indenting Macros}.
@item (interactive-only @var{value})
Set the function's @code{interactive-only} property to @var{value}.
@xref{The interactive-only property}.
@item (obsolete @var{current-name} @var{when})
Mark the function or macro as obsolete, similar to a call to
@code{make-obsolete} (@pxref{Obsolete Functions}). @var{current-name}

View file

@ -42,6 +42,7 @@ otherwise leave it unmarked.
---
** The Rmail commands d, C-d and u now handle repeat counts
to delete or undelete multiple messages.
* New Modes and Packages in Emacs 24.5
@ -51,6 +52,9 @@ to delete or undelete multiple messages.
* Lisp Changes in Emacs 24.5
+++
** You can specify a function's interactive-only property via `declare'.
* Changes in Emacs 24.5 on Non-Free Operating Systems

View file

@ -1,3 +1,16 @@
2014-03-22 Glenn Morris <rgm@gnu.org>
* emacs-lisp/byte-run.el (defun-declarations-alist):
Add interactive-only. Doc tweak.
(macro-declarations-alist): Doc tweak.
* subr.el (declare): Doc tweak (add xref to manual).
* comint.el (comint-run):
* files.el (insert-file-literally, insert-file):
* replace.el (replace-string, replace-regexp):
* simple.el (beginning-of-buffer, end-of-buffer, delete-backward-char)
(delete-forward-char, goto-line, insert-buffer, next-line)
(previous-line): Set interactive-only via declare.
2014-03-22 Dmitry Gutov <dgutov@yandex.ru>
* emacs-lisp/package.el (package-desc): Use the contents of the

View file

@ -746,11 +746,11 @@ The buffer name is made by surrounding the file name of PROGRAM with `*'s.
The file name is used to make a symbol name, such as `comint-sh-hook', and any
hooks on this symbol are run in the buffer.
See `make-comint' and `comint-exec'."
(declare (interactive-only make-comint))
(interactive "sRun program: ")
(let ((name (file-name-nondirectory program)))
(switch-to-buffer (make-comint name program))
(run-hooks (intern-soft (concat "comint-" name "-hook")))))
(put 'comint-run 'interactive-only 'make-comint)
(defun comint-exec (buffer name command startfile switches)
"Start up a process named NAME in buffer BUFFER for Comint modes.

View file

@ -69,6 +69,7 @@ The return value of this function is not used."
;; handle declarations in macro definitions and this is the first file
;; loaded by loadup.el that uses declarations in macros.
;; Add any new entries to info node `(elisp)Declare Form'.
(defvar defun-declarations-alist
(list
;; We can only use backquotes inside the lambdas and not for those
@ -81,6 +82,10 @@ The return value of this function is not used."
#'(lambda (f _args new-name when)
(list 'make-obsolete
(list 'quote f) (list 'quote new-name) (list 'quote when))))
(list 'interactive-only
#'(lambda (f _args instead)
(list 'put (list 'quote f) ''interactive-only
(list 'quote instead))))
(list 'compiler-macro
#'(lambda (f args compiler-function)
`(eval-and-compile
@ -101,7 +106,9 @@ Each element of the list takes the form (PROP FUN) where FUN is
a function. For each (PROP . VALUES) in a function's declaration,
the FUN corresponding to PROP is called with the function name,
the function's arglist, and the VALUES and should return the code to use
to set this property.")
to set this property.
This is used by `declare'.")
(defvar macro-declarations-alist
(cons
@ -115,7 +122,9 @@ to set this property.")
Each element of the list takes the form (PROP FUN) where FUN is a function.
For each (PROP . VALUES) in a macro's declaration, the FUN corresponding
to PROP is called with the macro name, the macro's arglist, and the VALUES
and should return the code to use to set this property.")
and should return the code to use to set this property.
This is used by `declare'.")
(put 'defmacro 'doc-string-elt 3)
(put 'defmacro 'lisp-indent-function 2)

View file

@ -2089,9 +2089,9 @@ This function ensures that none of these modifications will take place."
This function is meant for the user to run interactively.
Don't call it from programs! Use `insert-file-contents-literally' instead.
\(Its calling sequence is different; see its documentation)."
(declare (interactive-only insert-file-contents-literally))
(interactive "*fInsert file literally: ")
(insert-file-1 filename #'insert-file-contents-literally))
(put 'insert-file-literally 'interactive-only 'insert-file-contents-literally)
(defvar find-file-literally nil
"Non-nil if this buffer was made by `find-file-literally' or equivalent.
@ -5018,9 +5018,9 @@ Set mark after the inserted text.
This function is meant for the user to run interactively.
Don't call it from programs! Use `insert-file-contents' instead.
\(Its calling sequence is different; see its documentation)."
(declare (interactive-only insert-file-contents))
(interactive "*fInsert file: ")
(insert-file-1 filename #'insert-file-contents))
(put 'insert-file 'interactive-only 'insert-file-contents)
(defun append-to-file (start end filename)
"Append the contents of the region to the end of file FILENAME.

View file

@ -523,6 +523,8 @@ What you probably want is a loop like this:
which will run faster and will not set the mark or print anything.
\(You may need a more complex loop if FROM-STRING can match the null string
and TO-STRING is also null.)"
(declare (interactive-only
"use `search-forward' and `replace-match' instead."))
(interactive
(let ((common
(query-replace-read-args
@ -540,8 +542,6 @@ and TO-STRING is also null.)"
(region-end))
(nth 3 common))))
(perform-replace from-string to-string nil nil delimited nil nil start end backward))
(put 'replace-string 'interactive-only
"use `search-forward' and `replace-match' instead.")
(defun replace-regexp (regexp to-string &optional delimited start end backward)
"Replace things after point matching REGEXP with TO-STRING.
@ -597,6 +597,8 @@ What you probably want is a loop like this:
(while (re-search-forward REGEXP nil t)
(replace-match TO-STRING nil nil))
which will run faster and will not set the mark or print anything."
(declare (interactive-only
"use `re-search-forward' and `replace-match' instead."))
(interactive
(let ((common
(query-replace-read-args
@ -614,8 +616,6 @@ which will run faster and will not set the mark or print anything."
(region-end))
(nth 3 common))))
(perform-replace regexp to-string nil t delimited nil nil start end backward))
(put 'replace-regexp 'interactive-only
"use `re-search-forward' and `replace-match' instead.")
(defvar regexp-history nil

View file

@ -874,6 +874,7 @@ position, unless a \\[universal-argument] prefix is supplied.
Don't use this command in Lisp programs!
\(goto-char (point-min)) is faster."
(declare (interactive-only "use `(goto-char (point-min))' instead."))
(interactive "^P")
(or (consp arg)
(region-active-p)
@ -888,8 +889,6 @@ Don't use this command in Lisp programs!
(/ (+ 10 (* size (prefix-numeric-value arg))) 10)))
(point-min))))
(if (and arg (not (consp arg))) (forward-line 1)))
(put 'beginning-of-buffer 'interactive-only
"use `(goto-char (point-min))' instead.")
(defun end-of-buffer (&optional arg)
"Move point to the end of the buffer.
@ -902,6 +901,7 @@ position, unless a \\[universal-argument] prefix is supplied.
Don't use this command in Lisp programs!
\(goto-char (point-max)) is faster."
(declare (interactive-only "use `(goto-char (point-max))' instead."))
(interactive "^P")
(or (consp arg) (region-active-p) (push-mark))
(let ((size (- (point-max) (point-min))))
@ -922,7 +922,6 @@ Don't use this command in Lisp programs!
;; then scroll specially to put it near, but not at, the bottom.
(overlay-recenter (point))
(recenter -3))))
(put 'end-of-buffer 'interactive-only "use `(goto-char (point-max))' instead.")
(defcustom delete-active-region t
"Whether single-char deletion commands delete an active region.
@ -963,6 +962,7 @@ arg, and KILLFLAG is set if N is explicitly specified.
In Overwrite mode, single character backward deletion may replace
tabs with spaces so as to back over columns, unless point is at
the end of the line."
(declare (interactive-only delete-char))
(interactive "p\nP")
(unless (integerp n)
(signal 'wrong-type-argument (list 'integerp n)))
@ -985,7 +985,6 @@ the end of the line."
(insert-char ?\s (- ocol (current-column)) nil))))
;; Otherwise, do simple deletion.
(t (delete-char (- n) killflag))))
(put 'delete-backward-char 'interactive-only 'delete-char)
(defun delete-forward-char (n &optional killflag)
"Delete the following N characters (previous if N is negative).
@ -996,6 +995,7 @@ To disable this, set variable `delete-active-region' to nil.
Optional second arg KILLFLAG non-nil means to kill (save in kill
ring) instead of delete. Interactively, N is the prefix arg, and
KILLFLAG is set if N was explicitly specified."
(declare (interactive-only delete-char))
(interactive "p\nP")
(unless (integerp n)
(signal 'wrong-type-argument (list 'integerp n)))
@ -1009,7 +1009,6 @@ KILLFLAG is set if N was explicitly specified."
;; Otherwise, do simple deletion.
(t (delete-char n killflag))))
(put 'delete-forward-char 'interactive-only 'delete-char)
(defun mark-whole-buffer ()
"Put point at beginning and mark at end of buffer.
@ -1045,6 +1044,7 @@ What you probably want instead is something like:
(forward-line (1- N))
If at all possible, an even better solution is to use char counts
rather than line counts."
(declare (interactive-only forward-line))
(interactive
(if (and current-prefix-arg (not (consp current-prefix-arg)))
(list (prefix-numeric-value current-prefix-arg))
@ -1084,7 +1084,6 @@ rather than line counts."
(if (eq selective-display t)
(re-search-forward "[\n\C-m]" nil 'end (1- line))
(forward-line (1- line)))))
(put 'goto-line 'interactive-only 'forward-line)
(defun count-words-region (start end &optional arg)
"Count the number of words in the region.
@ -4245,6 +4244,7 @@ BUFFER may be a buffer or a buffer name.
This function is meant for the user to run interactively.
Don't call it from programs: use `insert-buffer-substring' instead!"
(declare (interactive-only insert-buffer-substring))
(interactive
(list
(progn
@ -4259,7 +4259,6 @@ Don't call it from programs: use `insert-buffer-substring' instead!"
(insert-buffer-substring (get-buffer buffer))
(point)))
nil)
(put 'insert-buffer 'interactive-only 'insert-buffer-substring)
(defun append-to-buffer (buffer start end)
"Append to specified buffer the text of the region.
@ -4847,6 +4846,7 @@ lines rather than by display lines.
If you are thinking of using this in a Lisp program, consider
using `forward-line' instead. It is usually easier to use
and more reliable (no dependence on goal column, etc.)."
(declare (interactive-only forward-line))
(interactive "^p\np")
(or arg (setq arg 1))
(if (and next-line-add-newlines (= arg 1))
@ -4863,7 +4863,6 @@ and more reliable (no dependence on goal column, etc.)."
(signal (car err) (cdr err))))
(line-move arg nil nil try-vscroll)))
nil)
(put 'next-line 'interactive-only 'forward-line)
(defun previous-line (&optional arg try-vscroll)
"Move cursor vertically up ARG lines.
@ -4894,6 +4893,8 @@ lines rather than by display lines.
If you are thinking of using this in a Lisp program, consider using
`forward-line' with a negative argument instead. It is usually easier
to use and more reliable (no dependence on goal column, etc.)."
(declare (interactive-only
"use `forward-line' with negative argument instead."))
(interactive "^p\np")
(or arg (setq arg 1))
(if (called-interactively-p 'interactive)
@ -4903,8 +4904,6 @@ to use and more reliable (no dependence on goal column, etc.)."
(signal (car err) (cdr err))))
(line-move (- arg) nil nil try-vscroll))
nil)
(put 'previous-line 'interactive-only
"use `forward-line' with negative argument instead.")
(defcustom track-eol nil
"Non-nil means vertical motion starting at end of line keeps to ends of lines.

View file

@ -265,7 +265,9 @@ information about the function or macro; these go into effect
during the evaluation of the `defun' or `defmacro' form.
The possible values of SPECS are specified by
`defun-declarations-alist' and `macro-declarations-alist'."
`defun-declarations-alist' and `macro-declarations-alist'.
For more information, see info node `(elisp)Declare Form'."
;; FIXME: edebug spec should pay attention to defun-declarations-alist.
nil)