I am finding myself editing a lot of files that are read-only. I usually hit C-x C-q
to call toggle-read-only
. Then I hit C-x C-s
to save and get,
File foo.txt is write-protected; try to save anyway? (y or n)
A开发者_StackOverflow社区fter hitting y
, the file is saved and the permissions on the file remain read-only.
Is there a way to shorten this process and make it so that simply saving a file with C-x C-s does the whole thing without prompting? Should I look into inserting chmod
in before-save-hook
and after-save-hook
or is there a better way?
Adding a call to chmod
in before-save-hook
would be clean way to accomplish this. There isn't any setting you can change to avoid the permissions check.
Based on the follow-up question, it sounds like you'd like the files to be changed to writable by you automatically upon opening. This code does the trick:
(defun change-file-permissions-to-writable ()
"to be run from find-file-hook, change write permissions"
(when (not (file-writable-p buffer-file-name))
(chmod buffer-file-name (file-modes-symbolic-to-number "u+w" (nth 8 (file-attributes buffer-file-name))))
(if (not (file-writable-p buffer-file-name))
(message "Unable to make file writable."))))
(add-hook 'find-file-hook 'change-file-permissions-to-writable)
Note: When I tested it on my Windows machine, the file permissions didn't show up until I tried to save the buffer, but it worked as expected. I personally feel uneasy about this customization, but it's your Emacs. :)
I agree with Trey that universally doing a chmod on write is risky -- read-only files are read-only for a reason, IMHO. Here's a way to specifically override things on a per-buffer basis. It's not ideal in that it overrides file-writable-p
for the life of the buffer (or at least until you toggle my-override-mode-on-save
back to nil), but it makes you make a conscious decision on a file-by-file basis (sort-of; it's really a buffer-by-buffer basis, which is fairly similar). Of course since you're looking to automatically toggle the read-only flag when the file is visited, you might not be interested in this distinction. Still, here it is; enjoy it or ignore it as you will.
(make-variable-buffer-local
(defvar my-override-mode-on-save nil
"Can be set to automatically ignore read-only mode of a file when saving."))
(defadvice file-writable-p (around my-overide-file-writeable-p act)
"override file-writable-p if `my-override-mode-on-save' is set."
(setq ad-return-value (or
my-override-mode-on-save
ad-do-it)))
(defun my-override-toggle-read-only ()
"Toggle buffer's read-only status, keeping `my-override-mode-on-save' in sync."
(interactive)
(setq my-override-mode-on-save (not my-override-mode-on-save))
(toggle-read-only))
P.S. Thanks to Trey for the ad-return-value
pointer in the other SO question.
Since I find it useful to be constantly reminded that I am about to edit a file I do not have permissions to, when I open a file in a buffer I want to force myself to proactively make the buffer writable wit C-x q
. Opening it with tramp by hand however is quite tedious so I advise save-buffer
to prompt me for password if it fails to write. I totally recommend you put this snippet in your .emacs
(defadvice save-buffer (around save-buffer-as-root-around activate)
"Use sudo to save the current buffer."
(interactive "p")
(if (and (buffer-file-name) (not (file-writable-p (buffer-file-name))))
(let ((buffer-file-name (format "/sudo::%s" buffer-file-name)))
ad-do-it)
ad-do-it))
For a reason I could no determine the Trey Jackson solution does not work on my gnu emacs 25.2 under windows: the file-modes-rights-to-number
called from file-modes-rights-to-number
fails.
If someone is stuck with the same problem he could use a less elegant but working solution replace block :
(chmod buffer-file-name (file-modes-symbolic-to-number "u+w" (nth 8 (file-attributes buffer-file-name))))
with block :
(cond ((or (eq system-type 'ms-dos) (eq system-type 'windows-nt))
(progn
(shell-command-to-string (concat "attrib -R " (buffer-file-name (current-buffer))))
(message "Setting file and buffer to writeable (%s style)" system-type)
))
((eq system-type 'gnu/linux)
(progn
(shell-command-to-string (concat "chmod u+w " (buffer-file-name (current-buffer))))
(message "Setting file and buffer to writeable (%s style)" system-type)
))
(t (message "file permission change not handle for OS %s" system-type))
)
精彩评论