[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/hyperdrive 310a9974bb 2/2: Add: (hyperdrive-entry-next) Sp
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/hyperdrive 310a9974bb 2/2: Add: (hyperdrive-entry-next) Split out of hyperdrive-next-version |
Date: |
Sun, 10 Sep 2023 21:59:55 -0400 (EDT) |
branch: elpa/hyperdrive
commit 310a9974bb463100cca03bdbfda590534782c7fa
Author: Joseph Turner <joseph@ushin.org>
Commit: Joseph Turner <joseph@ushin.org>
Add: (hyperdrive-entry-next) Split out of hyperdrive-next-version
This commit also simplifies the behavior of hyperdrive-next-version.
Previously, when ENTRY's version was nil or inside the final version
range, we'd warn about already being at the latest-version. Now, we
only warn when ENTRY's version is nil.
---
hyperdrive-lib.el | 51 ++++++++++++++++++++++++++++++++++
hyperdrive.el | 82 ++++++++++++++-----------------------------------------
2 files changed, 71 insertions(+), 62 deletions(-)
diff --git a/hyperdrive-lib.el b/hyperdrive-lib.el
index 863201fd10..9c7cbe7c55 100644
--- a/hyperdrive-lib.el
+++ b/hyperdrive-lib.el
@@ -406,6 +406,57 @@ When VERSION is nil, return latest version of ENTRY."
(404 nil)
(_ (signal (car err) (cdr err))))))))
+(cl-defun hyperdrive-entry-next (entry)
+ "Return unfilled ENTRY at its hyperdrive's next version.
+
+If next version is known nonexistent, return nil.
+If next version's existence is unknown, return \\+`unknown'.
+If ENTRY's version is nil, return value is `eq' to ENTRY.
+
+Sends a request to the gateway for hyperdrive's latest version."
+ (let ((next-entry (hyperdrive-copy-tree entry t))
+ (latest-version (hyperdrive-fill-latest-version
+ (hyperdrive-entry-hyperdrive entry))))
+ ;; ENTRY's version is nil: return ENTRY.
+ (unless (hyperdrive-entry-version entry)
+ (cl-return-from hyperdrive-entry-next entry))
+
+ ;; ENTRY version is the latest version: return ENTRY with nil version.
+ (when (eq latest-version (hyperdrive-entry-version entry))
+ (setf (hyperdrive-entry-version next-entry) nil)
+ (cl-return-from hyperdrive-entry-next next-entry))
+
+ ;; ENTRY is a directory: increment the version number by one.
+ (when (hyperdrive--entry-directory-p entry)
+ (cl-incf (hyperdrive-entry-version next-entry))
+ (cl-return-from hyperdrive-entry-next next-entry))
+
+ ;; ENTRY is a file...
+ (pcase-let* ((`(,_range-start . ,(map (:range-end range-end)))
(hyperdrive-entry-version-range entry))
+ (next-range-start (1+ range-end))
+ ((map (:existsp next-range-existsp) (:range-end
next-range-end))
+ ;; TODO: If cl struct copiers are extended like this:
+ ;;
https://lists.gnu.org/archive/html/help-gnu-emacs/2021-10/msg00797.html
+ ;; replace following sexp with
+ ;; (hyperdrive-entry-version-range
(hyperdrive-entry-copy :version next-range-start))
+ (map-elt (hyperdrive-entry-version-ranges-no-gaps entry)
next-range-start)))
+ ;; ENTRY is in the last version range: return ENTRY with nil version.
+ (when (eq latest-version range-end)
+ (setf (hyperdrive-entry-version next-entry) nil)
+ (cl-return-from hyperdrive-entry-next next-entry))
+
+ ;; Check existence of ENTRY's next version range...
+ (pcase-exhaustive next-range-existsp
+ ('t
+ (setf (hyperdrive-entry-version next-entry)
+ (if (eq next-range-end latest-version)
+ ;; This is the latest version: remove version number.
+ nil
+ next-range-start))
+ next-entry)
+ ('nil nil)
+ ('unknown 'unknown)))))
+
(declare-function hyperdrive-history "hyperdrive-history")
(cl-defun hyperdrive-open (entry &key then recurse (createp t))
"Open hyperdrive ENTRY.
diff --git a/hyperdrive.el b/hyperdrive.el
index a0a390be18..20e8dfa0d1 100644
--- a/hyperdrive.el
+++ b/hyperdrive.el
@@ -511,70 +511,28 @@ hyperdrive directory listing or a `hyperdrive-mode' file
buffer."
(hyperdrive-open previous-entry)
(hyperdrive-message "At earliest known version of %s"
(hyperdrive-entry-description entry :with-version nil))))
-(defun hyperdrive-next-version (entry &optional no-recurse)
- "Show next version of ENTRY.
-When NO-RECURSE is non-nil and the next version range's :EXISTSP
-value is unknown, call `hyperdrive-fill-version-ranges' and
-recurse, passing NO-RECURSE t to `hyperdrive-next-version'."
+(defun hyperdrive-next-version (entry)
+ "Show next version of ENTRY."
(declare (modes hyperdrive-mode))
(interactive (list hyperdrive-current-entry))
- ;; TODO: Consider splitting this logic into `hyperdrive-entry-next'.
- (cl-flet ((open-at-version (version &optional message)
- (let ((copy (hyperdrive-copy-tree entry t)))
- (setf (hyperdrive-entry-version copy) version)
- (hyperdrive-open copy)
- (when message
- (hyperdrive-message message))))
- (already-latest-error ()
- (hyperdrive-user-error
- "Already at latest version of entry; consider reverting buffer
with %s to check for newer versions"
- (substitute-command-keys
- (if (fboundp 'revert-buffer-quick)
- "\\[revert-buffer-quick]"
- "\\[revert-buffer]")))))
- (unless (hyperdrive-entry-version entry)
- (already-latest-error))
- (let ((latest-version (hyperdrive-fill-latest-version
(hyperdrive-entry-hyperdrive entry))))
- (when (eq latest-version (hyperdrive-entry-version entry))
- ;; NOTE: There is an unlikely race condition here. It's possible that
after
- ;; the `hyperdrive-fill-latest-version' call, this entry was updated.
- (open-at-version nil)
- (already-latest-error))
- (if (hyperdrive--entry-directory-p entry)
- ;; For directories, increment the version number by one.
- (let ((next-version (1+ (hyperdrive-entry-version entry))))
- (open-at-version (if (eq next-version latest-version)
- ;; Remove version number upon reaching the
end of the history.
- nil
- next-version)))
- (pcase-let* ((`(,_range-start . ,(map (:range-end range-end)))
(hyperdrive-entry-version-range entry))
- (next-range-start (1+ range-end))
- ((map (:existsp next-range-existsp) (:range-end
next-range-end))
- (map-elt (hyperdrive-entry-version-ranges-no-gaps entry)
next-range-start)))
- (when (eq latest-version range-end)
- ;; NOTE: There is an unlikely race condition here. It's possible
that after
- ;; the `hyperdrive-fill-latest-version' call, this entry was
updated.
- (open-at-version nil)
- (already-latest-error))
- (pcase next-range-existsp
- ('t
- ;; Known existent, open it:
- (if (eq next-range-end latest-version)
- ;; This is the latest version: remove version number
- (open-at-version nil)
- (open-at-version next-range-start)))
- ('nil
- ;; Known nonexistent, warn:
- (hyperdrive-message (substitute-command-keys
- "Entry deleted after this version. Try
\\[hyperdrive-history]")))
- ('unknown
- ;; Unknown existence, either warn or recurse:
- (if no-recurse
- (hyperdrive-message (substitute-command-keys
- "Next version unknown. Try
\\[hyperdrive-history]"))
- (hyperdrive-message "Loading history to find next version...")
- (hyperdrive-fill-version-ranges entry
- :then (lambda () (hyperdrive-next-version entry t)))))))))))
+ (pcase-exhaustive (hyperdrive-entry-next entry)
+ ((and (pred (eq entry)) next-entry)
+ ;; ENTRY already at latest version: open and say `revert-buffer'.
+ (hyperdrive-open next-entry)
+ (hyperdrive-message
+ "Already at latest version of entry; consider reverting buffer with %s
to check for newer versions"
+ (substitute-command-keys
+ (if (fboundp 'revert-buffer-quick)
+ "\\[revert-buffer-quick]"
+ "\\[revert-buffer]"))))
+ ('nil ;; Known nonexistent: suggest `hyperdrive-history'.
+ (hyperdrive-message (substitute-command-keys
+ "Entry deleted after this version. Try
\\[hyperdrive-history]")))
+ ('unknown ;; Unknown existence: suggest `hyperdrive-history'.
+ (hyperdrive-message (substitute-command-keys
+ "Next version unknown. Try \\[hyperdrive-history]")))
+ ((and (pred hyperdrive-entry-p) next-entry)
+ (hyperdrive-open next-entry))))
;;;; Bookmark support