-
-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancing denote-rewrite-front-matter
to save and kill buffer when it's safe to do so
#273
Comments
The latest versions of those functions have a |
That's good, but I'd rarely want to simply unconditionally save the buffer, because
So this only reduces my wrapper like this: (defun fixed-denote-rewrite-front-matter
(denote-rewrite-front-matter path &rest arguments)
(let* ((buffers (buffer-list))
(buffer (find-file-noselect path))
(_ (refresh-modified-state buffer))
(had-unsaved-changes (buffer-modified-p buffer)))
- (apply denote-rewrite-front-matter path arguments)
+ (apply denote-rewrite-front-matter path :save-buffer (not had-unsaved-changes) arguments)
(unless had-unsaved-changes
- (with-current-buffer buffer
- (basic-save-buffer))
(unless (memq buffer buffers)
(kill-buffer buffer))))) |
Re: buffers: I think there's several good reasons, most not applicable here (but it's not like I would be against a parameter to keep the buffers open unconditionally if someone wanted that):
There's probably other reasons, but I think that covers almost all of them. And I don't think any of that applies to buffers of files only opened automatically in the background to do the front matter part of the rename, if they're also automatically saved. |
Actually, you could just add a Then I can simplify my wrapper down to (let* ((buffer (find-buffer-visiting path))
(unsaved-changes (when buffer
(refresh-modified-state buffer)
(buffer-modified-p buffer))))
(denote-whatever
...
:save-buffer (not unsaved-changes)
:kill-buffer (not buffer)))
|
Here's a huuuge (for me) UX enhancement that I monkey-patch in from my config:
Big-picture overview:
If the buffer and file were the same before we rewrote the frontmatter, it's safe and nicer UX to automatically save it,
if the file was also not even open before we rewrote the frontmatter, it's safe and nicer UX to automatically close it after saving it.
Obviously "safe" here just means as safe as me manually doing that right after, and "nicer UX" here means that I always would manually do that right after.
Now the key piece here for correctness is
refresh-modified-state
. That's my own invention - it forces Emacs to re-check if buffer contents differ from the visited file. This, in my view, is essential. If the file changed on disk andbuffer-modified-p
is out of sync, automatically saving would be unacceptably prone to data loss. But once we can force a refresh of that state, we get better safety against data-losing race conditions than a manual check of the same (because the time it takes for a human to manually save the file after checking for buffer-vs-file differences is orders of magnitude longer than the time it takes for the code to both modify the frontmatter and save).Anyway, my joy using Denote (and especially building other things with Denote as a building block) went up a lot ever since I implemented this wrapper. I've been using this for several months now with no issues, never looked back, don't want to ever go back. Hopefully it helps others too.
If there's interest in upstreaming this, I have some intent to eventually publish
buffer-differs-from-visited-file-p
andrefresh-modified-state
to ELPA, but I haven't yet signed GNU papers. In the meantime, the default license on code posted to StackOverflow/Exchange is permissive (MIT iirc) and I also offer all of that code under 0BSD, which is widely recognized as public-domain-equivalent.If not, feel free to close it and it can just help people who come searching/asking for this feature.
The text was updated successfully, but these errors were encountered: