From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Eric Abrahamsen Newsgroups: gmane.emacs.devel Subject: Re: Proposal: move write-contents-functions higher up in basic-save-buffer Date: Thu, 25 May 2017 15:42:04 +0800 Message-ID: <87wp95idrn.fsf@ericabrahamsen.net> References: <87zie4yr9s.fsf@ericabrahamsen.net> <83y3tnmn88.fsf@gnu.org> <87wp97xjak.fsf@ericabrahamsen.net> <83h90bm11c.fsf@gnu.org> <87poeyyht2.fsf@ericabrahamsen.net> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1495698190 13950 195.159.176.226 (25 May 2017 07:43:10 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 25 May 2017 07:43:10 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.50 (gnu/linux) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu May 25 09:43:04 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dDnQF-0003Ni-I2 for ged-emacs-devel@m.gmane.org; Thu, 25 May 2017 09:43:03 +0200 Original-Received: from localhost ([::1]:58714 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dDnQI-0000SN-2e for ged-emacs-devel@m.gmane.org; Thu, 25 May 2017 03:43:06 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:43237) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dDnQ8-0000Pi-DT for emacs-devel@gnu.org; Thu, 25 May 2017 03:42:57 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dDnQ5-0001qD-77 for emacs-devel@gnu.org; Thu, 25 May 2017 03:42:56 -0400 Original-Received: from [195.159.176.226] (port=48695 helo=blaine.gmane.org) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dDnQ4-0001pU-S4 for emacs-devel@gnu.org; Thu, 25 May 2017 03:42:53 -0400 Original-Received: from list by blaine.gmane.org with local (Exim 4.84_2) (envelope-from ) id 1dDnPx-000337-Cs for emacs-devel@gnu.org; Thu, 25 May 2017 09:42:45 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 209 Original-X-Complaints-To: usenet@blaine.gmane.org Cancel-Lock: sha1:0f4JCcQrgAhEyzag031CB5PPpoM= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 195.159.176.226 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:215196 Archived-At: --=-=-= Content-Type: text/plain Stefan Monnier writes: > I haven't looked at basic-save-buffer recently, but in the worst case we > could keep the current code and add a > > (if (null buffer-file-name) > (run-hook-... 'write-contents-functions) > ...) > > but admittedly, it's better if we can move the single call to > write-contents-functions so it's shared by the file and the > non-file cases. Eli Zaretskii writes: >> From: Eric Abrahamsen >> Date: Wed, 24 May 2017 12:55:53 +0800 >> I can try to produce a patch, if this is acceptable in principle. > > Yes, please. Richard Stallman writes: > Please try using write-contents-functions for this, and you'll see if it > does the job. If not, you'll see what more change is needed. Okay, here's a first stab at it. I think it should work correctly: all the short-circuit hooks get a chance to run in all cases, but the function only insists on the presence of a file if `write-contents-functions' are not present, or if they fail with a nil value. I'd like to specify in the docs that those functions should fail with an error. If this looks okay I'll spend a bit more time testing it, then make docstring and manual edits. Eric --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-First-whack-at-write-contents-functions-for-non-file.patch >From af4f811439785113fe2be71f499006776958755b Mon Sep 17 00:00:00 2001 From: Eric Abrahamsen Date: Thu, 25 May 2017 15:28:19 +0800 Subject: [PATCH] First whack at write-contents-functions for non-file buffers --- lisp/files.el | 106 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 50 deletions(-) diff --git a/lisp/files.el b/lisp/files.el index 8ac1993754..c074fa7995 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -4943,29 +4943,14 @@ basic-save-buffer (if (buffer-base-buffer) (set-buffer (buffer-base-buffer))) (if (or (buffer-modified-p) - ;; handle the case when no modification has been made but - ;; the file disappeared since visited + ;; Handle the case when no modification has been made but + ;; the file disappeared since visited. (and buffer-file-name (not (file-exists-p buffer-file-name)))) (let ((recent-save (recent-auto-save-p)) setmodes) - ;; If buffer has no file name, ask user for one. - (or buffer-file-name - (let ((filename - (expand-file-name - (read-file-name "File to save in: " - nil (expand-file-name (buffer-name)))))) - (if (file-exists-p filename) - (if (file-directory-p filename) - ;; Signal an error if the user specified the name of an - ;; existing directory. - (error "%s is a directory" filename) - (unless (y-or-n-p (format-message - "File `%s' exists; overwrite? " - filename)) - (error "Canceled")))) - (set-visited-file-name filename))) - (or (verify-visited-file-modtime (current-buffer)) + (or (null buffer-file-name) + (verify-visited-file-modtime (current-buffer)) (not (file-exists-p buffer-file-name)) (yes-or-no-p (format @@ -4977,6 +4962,7 @@ basic-save-buffer (save-excursion (and (> (point-max) (point-min)) (not find-file-literally) + (null buffer-read-only) (/= (char-after (1- (point-max))) ?\n) (not (and (eq selective-display t) (= (char-after (1- (point-max))) ?\r))) @@ -4989,41 +4975,60 @@ basic-save-buffer (save-excursion (goto-char (point-max)) (insert ?\n)))) - ;; Support VC version backups. - (vc-before-save) ;; Don't let errors prevent saving the buffer. (with-demoted-errors (run-hooks 'before-save-hook)) - (or (run-hook-with-args-until-success 'write-contents-functions) - (run-hook-with-args-until-success 'local-write-file-hooks) - (run-hook-with-args-until-success 'write-file-functions) - ;; If a hook returned t, file is already "written". - ;; Otherwise, write it the usual way now. - (let ((dir (file-name-directory - (expand-file-name buffer-file-name)))) - (unless (file-exists-p dir) - (if (y-or-n-p - (format-message - "Directory `%s' does not exist; create? " dir)) - (make-directory dir t) - (error "Canceled"))) - (setq setmodes (basic-save-buffer-1)))) + ;; Give `write-contents-functions' a chance to + ;; short-circuit the whole process. + (unless (run-hook-with-args-until-success 'write-contents-functions) + ;; If buffer has no file name, ask user for one. + (or buffer-file-name + (let ((filename + (expand-file-name + (read-file-name "File to save in: " + nil (expand-file-name (buffer-name)))))) + (if (file-exists-p filename) + (if (file-directory-p filename) + ;; Signal an error if the user specified the name of an + ;; existing directory. + (error "%s is a directory" filename) + (unless (y-or-n-p (format-message + "File `%s' exists; overwrite? " + filename)) + (error "Canceled")))) + (set-visited-file-name filename))) + ;; Support VC version backups. + (vc-before-save) + (or (run-hook-with-args-until-success 'local-write-file-hooks) + (run-hook-with-args-until-success 'write-file-functions) + ;; If a hook returned t, file is already "written". + ;; Otherwise, write it the usual way now. + (let ((dir (file-name-directory + (expand-file-name buffer-file-name)))) + (unless (file-exists-p dir) + (if (y-or-n-p + (format-message + "Directory `%s' does not exist; create? " dir)) + (make-directory dir t) + (error "Canceled"))) + (setq setmodes (basic-save-buffer-1))))) ;; Now we have saved the current buffer. Let's make sure ;; that buffer-file-coding-system is fixed to what ;; actually used for saving by binding it locally. - (if save-buffer-coding-system - (setq save-buffer-coding-system last-coding-system-used) - (setq buffer-file-coding-system last-coding-system-used)) - (setq buffer-file-number - (nthcdr 10 (file-attributes buffer-file-name))) - (if setmodes - (condition-case () - (progn - (unless - (with-demoted-errors - (set-file-modes buffer-file-name (car setmodes))) - (set-file-extended-attributes buffer-file-name - (nth 1 setmodes)))) - (error nil)))) + (when buffer-file-name + (if save-buffer-coding-system + (setq save-buffer-coding-system last-coding-system-used) + (setq buffer-file-coding-system last-coding-system-used)) + (setq buffer-file-number + (nthcdr 10 (file-attributes buffer-file-name))) + (if setmodes + (condition-case () + (progn + (unless + (with-demoted-errors + (set-file-modes buffer-file-name (car setmodes))) + (set-file-extended-attributes buffer-file-name + (nth 1 setmodes)))) + (error nil))))) ;; If the auto-save file was recent before this command, ;; delete it now. (delete-auto-save-file-if-necessary recent-save) @@ -5255,7 +5260,8 @@ save-some-buffers (and pred (progn (set-buffer buffer) - (and buffer-offer-save (> (buffer-size) 0))))) + (and buffer-offer-save (> (buffer-size) 0)))) + write-contents-functions) (or (not (functionp pred)) (with-current-buffer buffer (funcall pred))) (if arg -- 2.13.0 --=-=-=--