emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 9ea5a91 2/2: Make `C-c C-w' copy the executable bits to the new f


From: Lars Ingebrigtsen
Subject: master 9ea5a91 2/2: Make `C-c C-w' copy the executable bits to the new file
Date: Thu, 2 Dec 2021 07:22:02 -0500 (EST)

branch: master
commit 9ea5a915bd1b9458af1587d63170888346e8baec
Author: Lars Ingebrigtsen <larsi@gnus.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    Make `C-c C-w' copy the executable bits to the new file
    
    * lisp/files.el (write-file): When visiting an executable file,
    make the new file executable, too (bug#18915).
---
 etc/NEWS      |  6 ++++++
 lisp/files.el | 66 ++++++++++++++++++++++++++++++++++-------------------------
 2 files changed, 44 insertions(+), 28 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 55733c6..eda1214 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -75,6 +75,12 @@ time.
 
 * Changes in Emacs 29.1
 
+---
+** 'write-file' will now copy some file mode bits.
+If the current buffer is visiting a file that is executable, the
+'C-c C-w' command will now make the new file executable, too.
+
++++
 ** New user option 'process-error-pause-time'.
 This determines how long to pause Emacs after a process
 filter/sentinel error has been handled.
diff --git a/lisp/files.el b/lisp/files.el
index 07279c4..9ed63a6 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -4745,7 +4745,6 @@ using \\<minibuffer-local-map>\\[next-history-element].
 If optional second arg CONFIRM is non-nil, this function
 asks for confirmation before overwriting an existing file.
 Interactively, confirmation is required unless you supply a prefix argument."
-;;  (interactive "FWrite file: ")
   (interactive
    (list (if buffer-file-name
             (read-file-name "Write file: "
@@ -4756,33 +4755,44 @@ Interactively, confirmation is required unless you 
supply a prefix argument."
                            default-directory)
                           nil nil))
         (not current-prefix-arg)))
-  (or (null filename) (string-equal filename "")
-      (progn
-       ;; If arg is a directory name,
-       ;; use the default file name, but in that directory.
-       (if (directory-name-p filename)
-           (setq filename (concat filename
-                                  (file-name-nondirectory
-                                   (or buffer-file-name (buffer-name))))))
-       (and confirm
-            (file-exists-p filename)
-            ;; NS does its own confirm dialog.
-            (not (and (eq (framep-on-display) 'ns)
-                      (listp last-nonmenu-event)
-                      use-dialog-box))
-            (or (y-or-n-p (format-message
-                            "File `%s' exists; overwrite? " filename))
-                (user-error "Canceled")))
-       (set-visited-file-name filename (not confirm))))
-  (set-buffer-modified-p t)
-  ;; Make buffer writable if file is writable.
-  (and buffer-file-name
-       (file-writable-p buffer-file-name)
-       (setq buffer-read-only nil))
-  (save-buffer)
-  ;; It's likely that the VC status at the new location is different from
-  ;; the one at the old location.
-  (vc-refresh-state))
+  (let ((old-modes
+         (and buffer-file-name
+              ;; File may have gone away; ignore errors in that case.
+              (ignore-errors (file-modes buffer-file-name)))))
+    (or (null filename) (string-equal filename "")
+        (progn
+         ;; If arg is a directory name,
+         ;; use the default file name, but in that directory.
+         (if (directory-name-p filename)
+             (setq filename (concat filename
+                                    (file-name-nondirectory
+                                     (or buffer-file-name (buffer-name))))))
+         (and confirm
+              (file-exists-p filename)
+              ;; NS does its own confirm dialog.
+              (not (and (eq (framep-on-display) 'ns)
+                        (listp last-nonmenu-event)
+                        use-dialog-box))
+              (or (y-or-n-p (format-message
+                              "File `%s' exists; overwrite? " filename))
+                  (user-error "Canceled")))
+         (set-visited-file-name filename (not confirm))))
+    (set-buffer-modified-p t)
+    ;; Make buffer writable if file is writable.
+    (and buffer-file-name
+         (file-writable-p buffer-file-name)
+         (setq buffer-read-only nil))
+    (save-buffer)
+    ;; If the old file was executable, then make the new file
+    ;; executable, too.
+    (when (and old-modes
+               (not (zerop (logand #o111 old-modes))))
+      (set-file-modes buffer-file-name
+                      (logior (logand #o111 old-modes)
+                              (file-modes buffer-file-name))))
+    ;; It's likely that the VC status at the new location is different from
+    ;; the one at the old location.
+    (vc-refresh-state)))
 
 (defun file-extended-attributes (filename)
   "Return an alist of extended attributes of file FILENAME.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]