[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Missing `with' macro?
Stuart D. Herring
Re: Missing `with' macro?
Mon, 31 Jul 2006 18:06:10 -0700 (PDT)
> * This macro has two separate args REUSE and WRITE.
> But I think only two combinations make sense: t nil, and nil t.
> It is always wrong to reuse an existing buffer if you're going
> to modify the file. And if you're not going to modify it,
> there is never any point in not reusing one.
If we use REUSE nil and WRITE t, then if the user has visited the file
(which could easily be a file for which WRITE t makes sense, e.g.
~/.emacs.d/.whatever-package-rc) and has unsaved changes in it, those are
effectively lost because they may clash with the updated file. Even if
the user has not modified the buffer, the odd result is that the buffer is
out of date as a result of actions within Emacs.
Moreover, using REUSE nil can be useful if we want to read the actual file
on disk and not whatever is in a buffer that is visiting the file (which
could be a temporary modification, or an unstable version, or...). It
also avoids any complications of file-local variables and so forth (so
long as VISIT is nil or 'raw), or subsequent buffer-but-not-file effects
(selective-display with ^M, user-added buffer-local variables, etc.).
> * This is a horrible kludge
> ;; We need to pretend that any other visiting buffer
> ;; doesn't actually exist.
> (if ,extant-sym
> (with-current-buffer ,extant-sym
> (setq buffer-file-name nil)))
> (find-file-noselect ,file-sym t))
> and without an unwind-protect it will permanently ruin the other buffer
> if an error occurs. How about this instead?
I'll grant that it's a kludge, but I don't know of a better way (I respond
to your suggestion below). There is in fact an unwind-protect on the
majority of the code that will undo that effect; however, I realize now
that it will not run if `find-file-noselect' exits abnormally. Failing a
complete rewrite of this mechanism, I'll make sure that the kludge is
protected more thoroughly.
> ;; Create a new buffer.
> (setq buf (create-file-buffer filename))
> ;; find-file-noselect-1 may use a different buffer.
> (find-file-noselect-1 buf filename nowarn
> rawfile truename number))))))
1. Thanks for pointing me at `find-file-noselect-1'; I didn't realize it
before, but it's exactly what I want here. I'll certainly use it.
2. Should we call `set-buffer-major-mode' here, like `find-file-noselect'
3. This does allow visiting a buffer repeatedly, but it doesn't entirely
obviate the need for the kludge because the code that checks for a file
being modified on disk since you read it when you try to edit it (my
apologies that I don't know a name for this code) will notice another
buffer visiting the file and will react if -its- modtime is out of date,
even if the modtime of the edited buffer is recent. I discovered this
while testing; I should have mentioned it in comments.
Of course, I guess my kludge just reduces it to a race condition, where if
the file is modified externally during the execution of `with-file' and
another modification is made, the warning will appear anyway. Then again,
is there anywhere in Emacs that we attempt to avoid that?
Anyway, is there a better way to avoid the modtime problems?
`find-file-noselect-1' solves everything else.
> * This seems like a mistake:
> ;; We don't just let-bind buffer-read-only because that
> ;; interacts poorly with switching buffers.
> (setq buffer-read-only (not ,write-sym))
> What is the problem you're concerned about?
See (elisp)Intro to Buffer-Local; I was avoiding the problems discussed
with the text "you can get Emacs very confused by binding the variable"
near the bottom. I realize now, re-reading that, that a `save-excursion'
(or even just `save-current-buffer', I guess) can prevent problems here...
but what happens if the buffer is killed before exiting the `let'? A
quick test on the 21.3 I have in front of me now seems to indicate that
nothing bad happens, but I'd like some more assurance if I can get it. If
it's true that nothing will get hurt then, I'll just let-bind
`buffer-read-only' inside the `prog1' there and around the
> * Use 'silent with prefix ARG. Use 'raw with two C-u's."
> Please write `silent' and `raw'; that is our convention.
Sorry. It was a quick docstring for a testing function, written without
thought, told by an idiot, full of sound and fury, signifying nothing.
This product is sold by volume, not by mass. If it appears too dense or
too sparse, it is because mass-energy conversion has occurred during