From b68b33375caeb82a4b3418d43c75bc8ccd43633a Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 13 Jul 2012 15:06:09 +0800 Subject: [PATCH] Don't warn on toggle-read-only calls. Clarify the documentation of toggle-read-only, and audit the code tree for uses of toggle-read-only; where appropriate, switch to setting the variable buffer-read-only or calling toggle-read-only with a (new) second arg. * lisp/files.el (toggle-read-only): Doc fix and code cleanup. New arg to allow printing the message when called from Lisp. * lisp/emacs-lisp/bytecomp.el (byte-compile-interactive-only-functions): Remove toggle-read-only. * lisp/bindings.el (mode-line-toggle-read-only): * lisp/dired.el (dired-toggle-read-only): * lisp/ibuffer.el (ibuffer-do-toggle-read-only): Call toggle-read-only with non-nil second arg. * lisp/bs.el (bs-toggle-readonly): * lisp/buff-menu.el (Buffer-menu-toggle-read-only): Remove with-no-warnings around toggle-read-only. * lisp/ffap.el (ffap--toggle-read-only): Accept a list of buffers. Remove with-no-warnings around toggle-read-only. (ffap-read-only, ffap-read-only-other-window) (ffap-read-only-other-frame): Callers changed. * lisp/help-mode.el: Don't require view package. (help-mode-finish): Set buffer-read-only instead of calling toggle-read-only. * lisp/emacs-lisp/eieio-custom.el (eieio-customize-object): * lisp/vc/ediff.el (ediff-set-read-only-in-buf-A): Set buffer-read-only directly. * lisp/gnus/smime.el (smime-certificate-info): Set buffer-read-only directly, instead of calling toggle-read-only with a (bogus) argument. * doc/emacs/buffers.texi (Misc Buffer): Document view-read-only. * doc/lispref/buffers.texi (Read Only Buffers): Document toggle-read-only changes. Reword to account for the fact that read-only is currently not supported in overlay properties. --- doc/emacs/ChangeLog | 4 +++ doc/emacs/buffers.texi | 5 ++- doc/lispref/ChangeLog | 6 ++++ doc/lispref/buffers.texi | 45 +++++++++++++++--------- etc/NEWS | 3 ++ lisp/ChangeLog | 30 ++++++++++++++++ lisp/bindings.el | 2 +- lisp/bs.el | 2 +- lisp/buff-menu.el | 5 +-- lisp/dired.el | 11 +++--- lisp/emacs-lisp/bytecomp.el | 2 +- lisp/emacs-lisp/eieio-custom.el | 2 +- lisp/emacs-lisp/eieio.el | 2 +- lisp/ffap.el | 17 +++++---- lisp/files.el | 76 +++++++++++++++++++++++------------------ lisp/gnus/ChangeLog | 5 +++ lisp/gnus/smime.el | 2 +- lisp/help-mode.el | 6 +--- lisp/ibuffer.el | 2 +- lisp/vc/ediff.el | 2 +- 20 files changed, 148 insertions(+), 81 deletions(-) diff --git a/doc/emacs/ChangeLog b/doc/emacs/ChangeLog index 311a28a3e39..fc2b7fe073a 100644 --- a/doc/emacs/ChangeLog +++ b/doc/emacs/ChangeLog @@ -1,3 +1,7 @@ +2012-07-13 Chong Yidong + + * buffers.texi (Misc Buffer): Document view-read-only. + 2012-07-07 Chong Yidong * custom.texi (Init File): Index site-lisp (Bug#11435). diff --git a/doc/emacs/buffers.texi b/doc/emacs/buffers.texi index 159bf894834..24bb0e83778 100644 --- a/doc/emacs/buffers.texi +++ b/doc/emacs/buffers.texi @@ -232,11 +232,14 @@ have special commands to operate on the text; also by visiting a file whose access control says you cannot write it. @findex toggle-read-only +@vindex view-read-only The command @kbd{C-x C-q} (@code{toggle-read-only}) makes a read-only buffer writable, and makes a writable buffer read-only. This works by setting the variable @code{buffer-read-only}, which has a local value in each buffer and makes the buffer read-only if its value is -non-@code{nil}. +non-@code{nil}. If you change the option @code{view-read-only} to a +non-@code{nil} value, making the buffer read-only with @kbd{C-x C-q} +also enables View mode in the buffer (@pxref{View Mode}). @findex rename-buffer @kbd{M-x rename-buffer} changes the name of the current buffer. You diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index 1faf9e04ec1..d7875a7de90 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,9 @@ +2012-07-13 Chong Yidong + + * buffers.texi (Read Only Buffers): Document toggle-read-only + changes. Reword to account for the fact that read-only is + currently not supported in overlay properties. + 2012-07-07 Chong Yidong * loading.texi (Library Search): Index site-lisp directories. diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi index 072ffeb4321..6ad329f3a30 100644 --- a/doc/lispref/buffers.texi +++ b/doc/lispref/buffers.texi @@ -730,11 +730,9 @@ The buffer is read-only if this variable is non-@code{nil}. @defvar inhibit-read-only If this variable is non-@code{nil}, then read-only buffers and, depending on the actual value, some or all read-only characters may be -modified. Read-only characters in a buffer are those that have -non-@code{nil} @code{read-only} properties (either text properties or -overlay properties). @xref{Special Properties}, for more information -about text properties. @xref{Overlays}, for more information about -overlays and their properties. +modified. Read-only characters in a buffer are those that have a +non-@code{nil} @code{read-only} text property. @xref{Special +Properties}, for more information about text properties. If @code{inhibit-read-only} is @code{t}, all @code{read-only} character properties have no effect. If @code{inhibit-read-only} is a list, then @@ -742,18 +740,31 @@ properties have no effect. If @code{inhibit-read-only} is a list, then of the list (comparison is done with @code{eq}). @end defvar -@deffn Command toggle-read-only &optional arg -This command toggles whether the current buffer is read-only. It is -intended for interactive use; do not use it in programs (it may have -side-effects, such as enabling View mode, and does not affect -read-only text properties). To change the read-only state of a buffer in -a program, explicitly set @code{buffer-read-only} to the proper value. -To temporarily ignore a read-only state, bind @code{inhibit-read-only}. - -If @var{arg} is non-@code{nil}, it should be a raw prefix argument. -@code{toggle-read-only} sets @code{buffer-read-only} to @code{t} if -the numeric value of that prefix argument is positive and to -@code{nil} otherwise. @xref{Prefix Command Arguments}. +@deffn Command toggle-read-only &optional arg message +This command toggles whether the current buffer is read-only, by +setting the variable @code{buffer-read-only}. If @var{arg} is +non-@code{nil}, it should be a raw prefix argument; the command then +makes the buffer read-only if the numeric value of that prefix +argument is positive, and makes the buffer writable otherwise. +@xref{Prefix Command Arguments}. + +If called interactively, or if called from Lisp with @var{message} is +non-@code{nil}, the command prints a message reporting the buffer's +new read-only status. + +When making the buffer read-only, this command also enables View mode +if the option @code{view-read-only} is non-@code{nil}. @xref{Misc +Buffer,,Miscellaneous Buffer Operations, emacs, The GNU Emacs Manual}. +When making the buffer writable, it disables View mode if View mode +was enabled. + +Lisp programs should only call @code{toggle-read-only} if they really +intend to do the same thing as the user command, including possibly +enabling or disabling View mode. Note also that this command works by +setting @code{buffer-read-only}, so even if you make the buffer +writable, characters with non-@code{nil} @code{read-only} text +properties will remain read-only. To temporarily ignore all read-only +states, bind @code{inhibit-read-only}, as described above. @end deffn @defun barf-if-buffer-read-only diff --git a/etc/NEWS b/etc/NEWS index 32c738a2aad..0132a3a9ed7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -476,6 +476,9 @@ still be supported for Emacs 24.x. * Lisp changes in Emacs 24.2 +** `toggle-read-only' accepts a second argument specifying whether to +print a message, if called from Lisp. + ** CL-style generalized variables are now in core Elisp. `setf' is autoloaded and `push' and `pop' accept generalized variables. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 349cc783bab..d6ce409dc9c 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,33 @@ +2012-07-13 Chong Yidong + + * files.el (toggle-read-only): Doc fix and code cleanup. New arg + to allow printing the message when called from Lisp. + + * emacs-lisp/bytecomp.el (byte-compile-interactive-only-functions): + Remove toggle-read-only. + + * bs.el (bs-toggle-readonly): + * buff-menu.el (Buffer-menu-toggle-read-only): Remove + with-no-warnings around toggle-read-only. + + * ffap.el (ffap--toggle-read-only): Accept a list of buffers. + Remove with-no-warnings around toggle-read-only. + (ffap-read-only, ffap-read-only-other-window) + (ffap-read-only-other-frame): Callers changed. + + * help-mode.el: Don't require view package. + (help-mode-finish): Set buffer-read-only instead of calling + toggle-read-only. + + * bindings.el (mode-line-toggle-read-only): + * dired.el (dired-toggle-read-only): + * ibuffer.el (ibuffer-do-toggle-read-only): Call toggle-read-only + with non-nil second arg. + + * emacs-lisp/eieio-custom.el (eieio-customize-object): + * vc/ediff.el (ediff-set-read-only-in-buf-A): Set buffer-read-only + directly. + 2012-07-12 Eli Zaretskii * emacs-lisp/bytecomp.el (byte-recompile-directory): Use cl-incf, diff --git a/lisp/bindings.el b/lisp/bindings.el index 109cd8a0d49..e0bea34cd0a 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -40,7 +40,7 @@ corresponding to the mode line clicked." (interactive "e") (save-selected-window (select-window (posn-window (event-start event))) - (with-no-warnings (toggle-read-only)) + (toggle-read-only nil t) (force-mode-line-update))) (defun mode-line-toggle-modified (event) diff --git a/lisp/bs.el b/lisp/bs.el index 09aefee416e..45a7e4d4440 100644 --- a/lisp/bs.el +++ b/lisp/bs.el @@ -962,7 +962,7 @@ Default is `bs--current-sort-function'." Uses function `toggle-read-only'." (interactive) (with-current-buffer (bs--current-buffer) - (call-interactively 'toggle-read-only)) + (toggle-read-only)) (bs--update-current-line)) (defun bs-clear-modified () diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index ab1de184ea0..6a65749e0c5 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -515,11 +515,12 @@ The current window remains selected." (bury-buffer menu))) (defun Buffer-menu-toggle-read-only () - "Toggle read-only status of buffer on this line." + "Toggle read-only status of buffer on this line. +This behaves like invoking \\[toggle-read-only] in that buffer." (interactive) (let (read-only) (with-current-buffer (Buffer-menu-buffer t) - (with-no-warnings (toggle-read-only)) + (toggle-read-only) (setq read-only buffer-read-only)) (tabulated-list-set-col 1 (if read-only "%" " ") t))) diff --git a/lisp/dired.el b/lisp/dired.el index 18480acd968..0e770773197 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -1956,15 +1956,14 @@ You can use it to recover marks, killed lines or subdirs." Actual changes in files cannot be undone by Emacs.")) (defun dired-toggle-read-only () - "Edit dired buffer with Wdired, or set it read-only. -Call `wdired-change-to-wdired-mode' in dired buffers whose editing is -supported by Wdired (the major mode of the dired buffer is `dired-mode'). -Otherwise, for buffers inheriting from dired-mode, call `toggle-read-only'." + "Edit Dired buffer with Wdired, or make it read-only. +If the current buffer can be edited with Wdired, (i.e. the major +mode is `dired-mode'), call `wdired-change-to-wdired-mode'. +Otherwise, call `toggle-read-only'." (interactive) (if (eq major-mode 'dired-mode) (wdired-change-to-wdired-mode) - (with-no-warnings - (toggle-read-only)))) + (toggle-read-only nil t))) (defun dired-next-line (arg) "Move down lines then position at filename. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 755bb4f821b..97d7ab924ed 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -355,7 +355,7 @@ else the global value will be modified." (defvar byte-compile-interactive-only-functions '(beginning-of-buffer end-of-buffer replace-string replace-regexp insert-file insert-buffer insert-file-literally previous-line next-line - goto-line comint-run delete-backward-char toggle-read-only) + goto-line comint-run delete-backward-char) "List of commands that are not meant to be called from Lisp.") (defvar byte-compile-not-obsolete-vars nil diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el index b09f6b6a0e9..59aeb161d8e 100644 --- a/lisp/emacs-lisp/eieio-custom.el +++ b/lisp/emacs-lisp/eieio-custom.el @@ -345,7 +345,7 @@ These groups are specified with the `:group' slot flag." (concat "*CUSTOMIZE " (object-name obj) " " (symbol-name g) "*"))) - (toggle-read-only -1) + (setq buffer-read-only nil) (kill-all-local-variables) (erase-buffer) (let ((all (overlay-lists))) diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index cfba4a84d13..dcd0608ebba 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -3040,7 +3040,7 @@ Optional argument NOESCAPE is passed to `prin1-to-string' when appropriate." ;;; Start of automatically extracted autoloads. ;;;### (autoloads (customize-object) "eieio-custom" "eieio-custom.el" -;;;;;; "9cf80224540c52045d515a4c2c833543") +;;;;;; "928623502e8bf40454822355388542b5") ;;; Generated autoloads from eieio-custom.el (autoload 'customize-object "eieio-custom" "\ diff --git a/lisp/ffap.el b/lisp/ffap.el index a8455189cb9..3d1f402ab6c 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el @@ -1698,9 +1698,11 @@ Only intended for interactive use." (set-window-dedicated-p win wdp)) value)) -(defun ffap--toggle-read-only (buffer) - (with-current-buffer buffer - (with-no-warnings +(defun ffap--toggle-read-only (buffer-or-list) + (dolist (buffer (if (listp buffer-or-list) + buffer-or-list + (list buffer-or-list))) + (with-current-buffer buffer (toggle-read-only 1)))) (defun ffap-read-only () @@ -1710,8 +1712,7 @@ Only intended for interactive use." (let ((value (call-interactively 'ffap))) (unless (or (bufferp value) (bufferp (car-safe value))) (setq value (current-buffer))) - (mapc #'ffap--toggle-read-only - (if (listp value) value (list value))) + (ffap--toggle-read-only value) value)) (defun ffap-read-only-other-window () @@ -1719,8 +1720,7 @@ Only intended for interactive use." Only intended for interactive use." (interactive) (let ((value (ffap-other-window))) - (mapc #'ffap--toggle-read-only - (if (listp value) value (list value))) + (ffap--toggle-read-only value) value)) (defun ffap-read-only-other-frame () @@ -1728,8 +1728,7 @@ Only intended for interactive use." Only intended for interactive use." (interactive) (let ((value (ffap-other-frame))) - (mapc #'ffap--toggle-read-only - (if (listp value) value (list value))) + (ffap--toggle-read-only value) value)) (defun ffap-alternate-file () diff --git a/lisp/files.el b/lisp/files.el index 53b701dbcbe..7fc7ccc8553 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -4824,41 +4824,51 @@ prints a message in the minibuffer. Instead, use `set-buffer-modified-p'." "Modification-flag cleared")) (set-buffer-modified-p arg)) -(defun toggle-read-only (&optional arg) - "Change whether this buffer is read-only. +(defun toggle-read-only (&optional arg message) + "Toggle the read-only state of the current buffer. With prefix argument ARG, make the buffer read-only if ARG is -positive, otherwise make it writable. If buffer is read-only -and `view-read-only' is non-nil, enter view mode. - -This function is usually the wrong thing to use in a Lisp program. -It can have side-effects beyond changing the read-only status of a buffer -\(e.g., enabling view mode), and does not affect read-only regions that -are caused by text properties. To make a buffer read-only in Lisp code, -set `buffer-read-only'. To ignore read-only status (whether due to text -properties or buffer state) and make changes, temporarily bind -`inhibit-read-only'." +positive; otherwise make it writable. + +When making the buffer read-only, enable View mode if +`view-read-only' is non-nil. When making the buffer writable, +disable View mode if View mode is enabled. + +If called interactively, or if called from Lisp with MESSAGE +non-nil, print a message reporting the buffer's new read-only +status. + +Do not call this from a Lisp program unless you really intend to +do the same thing as the \\[toggle-read-only] command, including +possibly enabling or disabling View mode. Also, note that this +command works by setting the variable `buffer-read-only', which +does not affect read-only regions caused by text properties. To +ignore read-only status in a Lisp program (whether due to text +properties or buffer state), bind `inhibit-read-only' temporarily +to a non-nil value." (interactive "P") - (if (and arg - (if (> (prefix-numeric-value arg) 0) buffer-read-only - (not buffer-read-only))) ; If buffer-read-only is set correctly, - nil ; do nothing. - ;; Toggle. - (progn - (cond - ((and buffer-read-only view-mode) - (View-exit-and-edit) - (make-local-variable 'view-read-only) - (setq view-read-only t)) ; Must leave view mode. - ((and (not buffer-read-only) view-read-only - ;; If view-mode is already active, `view-mode-enter' is a nop. - (not view-mode) - (not (eq (get major-mode 'mode-class) 'special))) - (view-mode-enter)) - (t (setq buffer-read-only (not buffer-read-only)) - (force-mode-line-update)))) - (if (called-interactively-p 'interactive) - (message "Read-only %s for this buffer" - (if buffer-read-only "enabled" "disabled"))))) + (cond + ;; Do nothing if `buffer-read-only' already matches the state + ;; specified by ARG. + ((and arg + (if (> (prefix-numeric-value arg) 0) + buffer-read-only + (not buffer-read-only)))) + ;; If View mode is enabled, exit it. + ((and buffer-read-only view-mode) + (View-exit-and-edit) + (set (make-local-variable 'view-read-only) t)) + ;; If `view-read-only' is non-nil, enable View mode. + ((and view-read-only + (not buffer-read-only) + (not view-mode) + (not (eq (get major-mode 'mode-class) 'special))) + (view-mode-enter)) + ;; The usual action: flip `buffer-read-only'. + (t (setq buffer-read-only (not buffer-read-only)) + (force-mode-line-update))) + (if (or message (called-interactively-p 'interactive)) + (message "Read-only %s for this buffer" + (if buffer-read-only "enabled" "disabled")))) (defun insert-file (filename) "Insert contents of file FILENAME into buffer after point. diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 5be5dd8cc56..4d40050acac 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog @@ -1,3 +1,8 @@ +2012-07-13 Chong Yidong + + * smime.el (smime-certificate-info): Set buffer-read-only directly, + instead of calling toggle-read-only with a (bogus) argument. + 2012-07-09 Tassilo Horn * gnus-sum.el (gnus-summary-limit-to-author): Use default value instead diff --git a/lisp/gnus/smime.el b/lisp/gnus/smime.el index 73f4970fcd4..7492142947e 100644 --- a/lisp/gnus/smime.el +++ b/lisp/gnus/smime.el @@ -678,7 +678,7 @@ The following commands are available: "x509" "-in" (expand-file-name certfile) "-text") (fundamental-mode) (set-buffer-modified-p nil) - (toggle-read-only t) + (setq buffer-read-only t) (goto-char (point-min)))) (defun smime-draw-buffer () diff --git a/lisp/help-mode.el b/lisp/help-mode.el index fa7d9b325db..7b6490b6b13 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -30,7 +30,6 @@ ;;; Code: (require 'button) -(require 'view) (eval-when-compile (require 'easymenu)) (defvar help-mode-map @@ -288,10 +287,7 @@ Commands: ;;;###autoload (defun help-mode-finish () (when (eq major-mode 'help-mode) - ;; View mode's read-only status of existing *Help* buffer is lost - ;; by with-output-to-temp-buffer. - (toggle-read-only 1) - + (setq buffer-read-only t) (save-excursion (goto-char (point-min)) (let ((inhibit-read-only t)) diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index 33fab8c9948..d29653c41ae 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el @@ -1283,7 +1283,7 @@ With optional ARG, make read-only only if ARG is positive." (:opstring "toggled read only status in" :interactive "P" :modifier-p t) - (toggle-read-only arg)) + (toggle-read-only arg t)) (define-ibuffer-op ibuffer-do-delete () "Kill marked buffers as with `kill-this-buffer'." diff --git a/lisp/vc/ediff.el b/lisp/vc/ediff.el index a1d778beebc..a1f3b72942f 100644 --- a/lisp/vc/ediff.el +++ b/lisp/vc/ediff.el @@ -152,7 +152,7 @@ ;; Used as a startup hook to set `_orig' patch file read-only. (defun ediff-set-read-only-in-buf-A () (ediff-with-current-buffer ediff-buffer-A - (toggle-read-only 1))) + (setq buffer-read-only t))) ;; Return a plausible default for ediff's first file: ;; In dired, return the file number FILENO (or 0) in the list -- 2.11.4.GIT