branch: elpa/hyperdrive
commit ad6c7b90abf6748a8c47ea0d9db27233a55dd503
Merge: 0d04b9b2ea 2f1aebbe04
Author: Joseph Turner <jos...@ushin.org>
Commit: Joseph Turner <jos...@ushin.org>

    Add hyperdrive-forget-file command
---
 CHANGELOG.org       |   2 +
 doc/hyperdrive.org  |  18 +++++++
 doc/hyperdrive.texi |  22 ++++++++
 hyperdrive-diff.el  |   2 +
 hyperdrive-dir.el   |   1 +
 hyperdrive-lib.el   | 153 ++++++++++++++++++++++++++++------------------------
 hyperdrive-menu.el  |   6 ++-
 hyperdrive-vars.el  |   2 +-
 hyperdrive.el       | 100 ++++++++++++++++++++++++----------
 9 files changed, 206 insertions(+), 100 deletions(-)

diff --git a/CHANGELOG.org b/CHANGELOG.org
index aa026e75d1..b98a26a2ba 100644
--- a/CHANGELOG.org
+++ b/CHANGELOG.org
@@ -28,6 +28,8 @@ installation with ~M-x hyperdrive-install~, and a faster 
directory UI!
 - When visiting an old version of a hyperdrive file, press ~n~ and ~p~ to
   traverse the version history.  Press ~q~ to kill the current buffer.
 - View hyperdrive disk usage with ~hyperdrive-describe~ and ~hyperdrive-menu~.
+- Delete the local copy of a file or directory with
+  ~hyperdrive-forget-file~, also bound in ~hyperdrive-menu~ and menu bar.
 
 ** Changed
 
diff --git a/doc/hyperdrive.org b/doc/hyperdrive.org
index 260e172406..06419a74f3 100644
--- a/doc/hyperdrive.org
+++ b/doc/hyperdrive.org
@@ -267,6 +267,10 @@ available inside the directory view by default:
 
   Delete the file or directory (recursively) at point.
 
+- Key: F (hyperdrive-forget-file) ::
+
+  Delete your local copy of the file for the current buffer.
+
 - Key: H (hyperdrive-dir-history) ::
 
   Open the version history (see [[*View the hyperdrive version history]])
@@ -457,6 +461,20 @@ version of the hyperdrive (see [[*View the hyperdrive 
version history]]).*
 This command also has a keybinding in the directory view (see
 [[*Directory view]]).
 
+** Forget a hyperdrive file
+
+It is possible to "forget" your local copy of a hyperdrive file in
+order to save disk space.  "Forgetting" a file does not delete the
+file from the hyperdrive and does not increment the hyperdrive's
+version number.
+
+- Command: hyperdrive-forget-file ::
+
+  Delete your local copy of the file for the current buffer.
+
+This command also has a keybinding in the directory view (see
+[[*Directory view]]).
+
 ** View the hyperdrive version history
 
 Hyperdrives are versioned, meaning that you can explore the history of
diff --git a/doc/hyperdrive.texi b/doc/hyperdrive.texi
index ceba76ef70..4572a6e60b 100644
--- a/doc/hyperdrive.texi
+++ b/doc/hyperdrive.texi
@@ -84,6 +84,7 @@ Usage
 * Write to a hyperdrive::
 * Link to a hyperdrive::
 * Delete a hyperdrive file::
+* Forget a hyperdrive file::
 * View the hyperdrive version history::
 * Describe a hyperdrive::
 * Name a hyperdrive::
@@ -286,6 +287,7 @@ On the network it still may be there.
 * Write to a hyperdrive::
 * Link to a hyperdrive::
 * Delete a hyperdrive file::
+* Forget a hyperdrive file::
 * View the hyperdrive version history::
 * Describe a hyperdrive::
 * Name a hyperdrive::
@@ -502,6 +504,11 @@ Download the file at point to disk.
 @findex hyperdrive-delete
 Delete the file or directory (recursively) at point.
 
+@item @kbd{F} (@code{hyperdrive-forget-file})
+@kindex F
+@findex hyperdrive-forget-file
+Delete your local copy of the file for the current buffer.
+
 @item @kbd{H} (@code{hyperdrive-dir-history})
 @kindex H
 @findex hyperdrive-dir-history
@@ -728,6 +735,21 @@ Delete the hyperdrive file in the current buffer.
 This command also has a keybinding in the directory view (see
 @ref{Directory view}).
 
+@node Forget a hyperdrive file
+@section Forget a hyperdrive file
+
+It is possible to ``forget'' your local copy of a hyperdrive file in
+order to save disk space.  ``Forgetting'' a file does not delete the
+file from the hyperdrive and does not increment the hyperdrive's
+version number.
+
+@deffn Command hyperdrive-forget-file
+Delete your local copy of the file for the current buffer.
+@end deffn
+
+This command also has a keybinding in the directory view (see
+@ref{Directory view}).
+
 @node View the hyperdrive version history
 @section View the hyperdrive version history
 
diff --git a/hyperdrive-diff.el b/hyperdrive-diff.el
index 44caa5b1a7..9885d00aa5 100644
--- a/hyperdrive-diff.el
+++ b/hyperdrive-diff.el
@@ -106,10 +106,12 @@ This function is intended to diff files, not directories."
     (h/api 'get (he/url old-entry)
       :queue queue :as 'response :else #'ignore
       :then (lambda (response)
+              (h//fill old-entry (plz-response-headers response))
               (setf old-response response)))
     (h/api 'get (he/url new-entry)
       :queue queue :as 'response :else #'ignore
       :then (lambda (response)
+              (h//fill new-entry (plz-response-headers response))
               (setf new-response response)))))
 
 ;;;; Mode
diff --git a/hyperdrive-dir.el b/hyperdrive-dir.el
index ef3b0f3df9..b379422f6b 100644
--- a/hyperdrive-dir.el
+++ b/hyperdrive-dir.el
@@ -217,6 +217,7 @@ With point on header, returns directory entry."
   "d"   #'h/download
   "^"   #'h/up
   "D"   #'h/delete
+  "F"   #'h/forget-file
   "H"   #'h/dir-history
   "s"   #'h/dir-sort
   "?"   #'h/menu
diff --git a/hyperdrive-lib.el b/hyperdrive-lib.el
index 00ffcbcd3c..c2ff1f70d2 100644
--- a/hyperdrive-lib.el
+++ b/hyperdrive-lib.el
@@ -166,11 +166,13 @@ REST may include the argument `:queue', a `plz-queue' in 
which to
 make the request."
   ;; TODO: Document that the request/queue is returned.
   ;; TODO: Should we create a wrapper for `h/api' which calls
-  ;;  `h//fill-latest-version' for requests to
-  ;;  directories/requests which modify the drive (and therefore
-  ;;  always return the latest version number). If we did this, we
-  ;;  could remove redundant calls to
-  ;;  `h//fill-latest-version' everywhere else.
+  ;; `h//fill-latest-version' for requests to directories/requests which modify
+  ;; the drive (and therefore always return the latest version number).  If we
+  ;; did this, we could remove redundant calls to `h//fill-latest-version'
+  ;; everywhere else.  X-Drive-Size is returned by many types of requests, and 
it
+  ;; would simplify the code to handle updating the hyperdrive disk-usage in 
one
+  ;; place.  Once implemented, go through each call to `h/api' to verify that
+  ;; disk-usage is updated correctly.
   (declare (indent defun))
   (pcase method
     ((and (or 'get 'head)
@@ -466,7 +468,7 @@ When VERSION is nil, return latest version of ENTRY."
     (setf (he/version entry) version)
     (condition-case err
         ;; FIXME: Requests to out of range version currently hang.
-        (h/fill entry :then 'sync)
+        (h/fill entry)
       (plz-error
        (pcase (plz-response-status (plz-error-response (caddr err)))
          ;; FIXME: If plz-error is a curl-error, this block will fail.
@@ -620,7 +622,7 @@ echo area when the request for the file is made."
     (when messagep
       (h/message "Opening <%s>..." (he/url entry)))))
 
-(cl-defun h/fill (entry &key queue then else)
+(cl-defun h/fill (entry &key queue (then 'sync) else)
   "Fill ENTRY's metadata and call THEN.
 If THEN is `sync', return the filled entry and ignore ELSE.
 Otherwise, make request asynchronously and call THEN with the
@@ -723,17 +725,18 @@ Returns filled ENTRY."
             ;; but no public-key.
             (cl-pushnew domain (h/domains (he/hyperdrive entry)) :test 
#'equal)))
       (setf (h/public-key hyperdrive) public-key))
-    (if (and (h//entry-directory-p entry)
-             (null (he/version entry)))
-        ;; Version-less directory HEAD/GET request ETag header always have the
-        ;; hyperdrive's latest version. We don't currently store
-        ;; version ranges for directories (since they don't
-        ;; technically have versions in hyperdrive).
-        (h//fill-latest-version hyperdrive headers)
-      ;; File HEAD/GET request ETag header does not retrieve the
-      ;; hyperdrive's latest version, so `h/update-existent-version-range'
-      ;; will not necessarily fill in the entry's last range.
-      (h/update-existent-version-range entry (string-to-number etag)))
+    (when etag
+      (if (and (h//entry-directory-p entry)
+               (null (he/version entry)))
+          ;; Version-less directory HEAD/GET request ETag header always have 
the
+          ;; hyperdrive's latest version. We don't currently store
+          ;; version ranges for directories (since they don't
+          ;; technically have versions in hyperdrive).
+          (h//fill-latest-version hyperdrive headers)
+        ;; File HEAD/GET request ETag header does not retrieve the
+        ;; hyperdrive's latest version, so `h/update-existent-version-range'
+        ;; will not necessarily fill in the entry's last range.
+        (h/update-existent-version-range entry (string-to-number etag))))
     entry))
 
 (defun h//fill-listing-entries (listing hyperdrive version)
@@ -966,14 +969,18 @@ HYPERDRIVE's public metadata file."
                ;; NOTE: Don't attempt to fill hyperdrive struct with old 
metadata
                :version nil))
        (metadata (condition-case err
-                     (h/api 'get (he/url entry)
-                       :as (lambda ()
-                             (condition-case nil
-                                 (json-read)
-                               (json-error
-                                (h/message "Error parsing JSON metadata file: 
%s"
-                                           (he/url entry)))))
-                       :noquery t)
+                     ;; TODO: Refactor to use :as 'response-with-buffer and 
call h/fill
+                     (pcase-let
+                         (((cl-struct plz-response headers body)
+                           (h/api 'get (he/url entry) :as 'response :noquery 
t)))
+                       (h//fill entry headers)
+                       (with-temp-buffer
+                         (insert body)
+                         (goto-char (point-min))
+                         (json-read)))
+                   (json-error
+                    (h/message "Error parsing JSON metadata file: %s"
+                               (he/url entry)))
                    (plz-error
                     (pcase (plz-response-status (plz-error-response (caddr 
err)))
                       ;; FIXME: If plz-error is a curl-error, this block will 
fail.
@@ -1314,13 +1321,15 @@ With PURGE, delete hash table entry for HYPERDRIVE."
 That is, if the SEED has been used to create a local
 hyperdrive."
   (condition-case err
-      (pcase (h/api 'get (format "hyper://localhost/?key=%s"
-                                 (url-hexify-string seed))
-               :as 'response :noquery t)
-        ((and (pred plz-response-p)
-              response
-              (guard (= 200 (plz-response-status response))))
-         (plz-response-body response)))
+      (pcase-let
+          (((cl-struct plz-response (body url))
+            (h/api 'get (format "hyper://localhost/?key=%s"
+                                (url-hexify-string seed))
+              :as 'response :noquery t)))
+        ;; TODO: Update hyperdrive disk-usage.  The following doesn't work
+        ;; because the response doesn't have the proper ETag header:
+        ;; (h//fill (h/url-entry url) headers)
+        url)
     (plz-error (if (= 400 (plz-response-status (plz-error-response (caddr 
err))))
                    ;; FIXME: If plz-error is a curl-error, this block will 
fail.
                    nil
@@ -1348,47 +1357,51 @@ Otherwise, return nil.  SLOT may be one of
 (cl-defun h/handler-default (entry &key then)
   "Load ENTRY's file into an Emacs buffer.
 If then, then call THEN with no arguments.  Default handler."
-  (h/api 'get (he/url entry)
-    :noquery t
-    :as (lambda ()
-          (pcase-let*
-              (((cl-struct hyperdrive-entry hyperdrive version etc) entry)
-               ((map target) etc)
-               (response-buffer (current-buffer)))
-            (with-current-buffer (h//get-buffer-create entry)
-              ;; TODO: Don't reload if we're jumping to a link on the
-              ;; same page (but ensure that reverting still works).
-              (if (buffer-modified-p)
-                  (h/message "Buffer modified: %S" (current-buffer))
-                (save-excursion
-                  (with-silent-modifications
-                    (erase-buffer)
-                    (insert-buffer-substring response-buffer))
-                  (setf buffer-undo-list nil)
-                  (setf buffer-read-only
-                        (or (not (h/writablep hyperdrive)) version))
-                  (set-buffer-modified-p nil)
-                  (set-visited-file-modtime (current-time))))
-              (when (map-elt (hyperdrive-etc hyperdrive) 'safep)
-                (let ((buffer-file-name (he/name entry)))
-                  (set-auto-mode)))
-              (when target
-                (pcase major-mode
-                  ('org-mode
-                   (require 'hyperdrive-org)
-                   (h/org--link-goto target))
-                  ('markdown-mode
-                   ;; TODO: Handle markdown link
-                   )))
-              (h/blob-mode (if version +1 -1))
-              (when then
-                (funcall then)))))))
+  (pcase-let*
+      (((cl-struct plz-response headers body)
+        ;; TODO: Handle errors
+        ;; TODO: When plz adds :as 'response-with-buffer, use that.
+        (h/api 'get (he/url entry) :noquery t :as 'response))
+       ;; Filling entry is necessary in order to update hyperdrive disk-usage.
+       (_ (h//fill entry headers))
+       ((cl-struct hyperdrive-entry hyperdrive version etc) entry)
+       ((map target) etc))
+    (with-current-buffer (h//get-buffer-create entry)
+      ;; TODO: Don't reload if we're jumping to a link on the
+      ;; same page (but ensure that reverting still works).
+      (if (buffer-modified-p)
+          (h/message "Buffer modified: %S" (current-buffer))
+        (save-excursion
+          (with-silent-modifications
+            (erase-buffer)
+            (insert body))
+          (setf buffer-undo-list nil)
+          (setf buffer-read-only
+                (or (not (h/writablep hyperdrive)) version))
+          (set-buffer-modified-p nil)
+          (set-visited-file-modtime (current-time))))
+      (when (map-elt (hyperdrive-etc hyperdrive) 'safep)
+        (let ((buffer-file-name (he/name entry)))
+          (set-auto-mode)))
+      (when target
+        (pcase major-mode
+          ('org-mode
+           (require 'hyperdrive-org)
+           (h/org--link-goto target))
+          ('markdown-mode
+           ;; TODO: Handle markdown link
+           )))
+      (h/blob-mode (if version +1 -1))
+      (when then
+        (funcall then)))))
 
 (cl-defun h/handler-streamable (entry &key _then)
   ;; TODO: Is there any reason to not pass THEN through?
   "Stream ENTRY."
-  (h/message "Streaming %s..." (h//format-entry-url entry))
-  (pcase-let ((`(,command . ,args) (split-string h/stream-player-command)))
+  ;; NOTE: Since data is streamed to an external process, disk usage will not 
be
+  ;; updated until a later request.
+  (h/message "Streaming %s..."  (h//format-entry-url entry))
+  (pcase-let ((`(,command .  ,args) (split-string h/stream-player-command)))
     (apply #'start-process "hyperdrive-stream-player"
            nil command (cl-substitute (h//httpify-url
                                        (he/url entry))
diff --git a/hyperdrive-menu.el b/hyperdrive-menu.el
index adefba958c..7a7164f95b 100644
--- a/hyperdrive-menu.el
+++ b/hyperdrive-menu.el
@@ -71,7 +71,7 @@
         "Hyperdrive"))
     ("h" "Hyperdrive" h/menu-hyperdrive)
     ("N" "New drive" h/new)
-    ("L" "Open Link" h/open-url)]
+    ("L" "Open link" h/open-url)]
    ["Version"
     :if (lambda ()
           (and (h/menu--scope)
@@ -166,7 +166,9 @@
                                   (h/menu--scope)))
                        (or version (not (h/writablep hyperdrive))))))
         ("d" "Download" h/download
-         :if-not-mode h/dir-mode)]
+         :if-not-mode h/dir-mode)
+        ("F" "Forget file" h/forget-file
+         :transient t)]
        ;; TODO: Consider adding a defcustom to hide the "Selected" and
        ;; "Current" groups when in a directory buffer.
        [;; Selected
diff --git a/hyperdrive-vars.el b/hyperdrive-vars.el
index 31bf171e53..2c9c26ebef 100644
--- a/hyperdrive-vars.el
+++ b/hyperdrive-vars.el
@@ -380,7 +380,7 @@ values are alists mapping version range starts to plists 
with
 ;;;;; Internals
 
 (defvar h/gateway-version-expected
-  '(:name "hyper-gateway-ushin" :version "3.8.0"))
+  '(:name "hyper-gateway-ushin" :version "3.9.2"))
 
 (defvar h/gateway-version-checked-p nil
   "Non-nil if the gateway's version has been checked.
diff --git a/hyperdrive.el b/hyperdrive.el
index 561c5947c9..65213e96e8 100644
--- a/hyperdrive.el
+++ b/hyperdrive.el
@@ -135,19 +135,16 @@ Return version if gateway is running; otherwise signal an 
error."
 If SEED is not currently used as the petname for another
 hyperdrive, the new hyperdrive's petname will be set to SEED."
   (interactive (list (h/read-name :prompt "New hyperdrive seed")))
-  (let* ((response (h/api 'post (concat "hyper://localhost/?key=" 
(url-hexify-string seed))))
-         (url (progn
-                ;; NOTE: Working around issue in plz whereby the
-                ;; stderr process sentinel sometimes leaves "stderr
-                ;; finished" garbage in the response body in older
-                ;; Emacs versions.  See: 
<https://github.com/alphapapa/plz.el/issues/23>.
-                (string-match (rx bos (group "hyper://" (1+ nonl))) response)
-                (match-string 1 response)))
-         (hyperdrive (he/hyperdrive (h/url-entry url))))
+  (pcase-let* (((cl-struct plz-response (body url))
+                (h/api 'post (concat "hyper://localhost/?key="
+                                     (url-hexify-string seed))
+                       :as 'response))
+               (hyperdrive (he/hyperdrive (h/url-entry url))))
     (setf (h/seed hyperdrive) seed)
     (setf (h/writablep hyperdrive) t)
     (unwind-protect
         (h/set-petname seed hyperdrive)
+      ;; TODO: Hyperdrive disk usage should be set here.
       (h/persist hyperdrive)
       (h/open (h/url-entry url)))))
 
@@ -185,6 +182,33 @@ Interactively, prompt for hyperdrive and action."
                     (propertize "safe" 'face 'success)
                   (propertize "unsafe" 'face 'error))))))
 
+(defun h/forget-file (entry)
+  "Delete local copy of the file or directory contents of ENTRY.
+Only delete the blob(s) for the file or directory at ENTRY's
+version; other versions of the file or directory are not cleared.
+If ENTRY is a directory, recursively delete blobs for all files
+within the directory.  Hyperdrive directory contents are not
+modified; file blobs may be recoverable from other peers."
+  ;; TODO: Consider supporting an :all-versions key for clearing the cache for
+  ;; all versions of the file/directory.
+  (interactive (list (h//context-entry)))
+  (when (yes-or-no-p
+         (format-message
+          "Clear local copy of entry (data may not be recoverable—see 
manual):`%s'?  "
+          (h//format-entry entry)))
+    (let ((url (he/url entry)))
+      (h/api 'post url
+        :headers '(("Cache-Control" . "no-store"))
+        :as 'response
+        :else (lambda (err)
+                (h/error "Unable to clear cache for `%s': %S" url err))
+        :then (lambda (response)
+                (h//fill entry (plz-response-headers response))
+                (h/message "Cleared `%s'" (h//format-entry entry))
+                ;; TODO: When file sizes in hyperdrive-dir-mode are colorized
+                ;; based locally downloaded sizes, refresh ewoc entry here.
+                )))))
+
 ;;;###autoload
 (defun hyperdrive-purge (hyperdrive)
   "Purge all data corresponding to HYPERDRIVE."
@@ -449,7 +473,11 @@ in a directory.  Otherwise, or with universal prefix 
argument
     (when (file-exists-p filename)
       ;; plz.el will not overwrite existing files: ensure there's no file 
there.
       (delete-file filename))
-    (h/api 'get url :as `(file ,filename))))
+    (h/api 'get url :as `(file ,filename))
+    ;; TODO: If plz adds support for getting response headers when downloading
+    ;; as a file, use it here.
+    ;; Filling entry is necessary in order to update hyperdrive disk-usage.
+    (h/fill (h/url-entry url))))
 
 ;;;###autoload
 (defun hyperdrive-write-buffer (entry &optional overwritep)
@@ -696,6 +724,7 @@ After successful upload, call THEN.  When QUEUE, use it."
       :body `(file ,filename)
       :headers `(("Last-Modified" . ,last-modified))
       :then then)
+    ;; TODO: Hyperdrive disk usage should be set here.
     (unless queue
       (h/message "Uploading to \"%s\"..." url))))
 
@@ -776,6 +805,8 @@ Universal prefix argument \\[universal-argument] forces
 
 (require 'url)
 
+;; TODO: EWW buffers end up being marked as modified, and Emacs prompts to save
+;; them before exiting.  Emacs should not prompt to save *eww* buffers.
 (defun h/url-loader (parsed-url)
   "Retrieve URL synchronously.
 PARSED-URL must be a URL-struct like the output of
@@ -783,12 +814,17 @@ PARSED-URL must be a URL-struct like the output of
 
 The return value of this function is the retrieval buffer."
   (cl-check-type parsed-url url "Need a pre-parsed URL.")
-  (let* ((url (url-recreate-url parsed-url))
-         ;; response-buffer will contain the loaded HTML, and will be deleted 
at the end of `eww-render'.
-         (response-buffer (h/api 'get url :as 'buffer)))
-    (with-current-buffer response-buffer
+  (pcase-let* ((url (url-recreate-url parsed-url))
+               ;; TODO: When `plz.el' adds :as 'response-with-buffer, use that.
+               ;; response-buffer will contain the loaded HTML, and will be 
deleted at the end of `eww-render'.
+               ((cl-struct plz-response headers body)
+                (h/api 'get url :as 'response)))
+    ;; Filling entry is necessary in order to update hyperdrive disk-usage.
+    (h//fill (h/url-entry url) headers)
+    (with-current-buffer (generate-new-buffer " *hyperdrive-eww*")
       (widen)
       (goto-char (point-min))
+      (insert body)
       (while (search-forward (string ?\C-m) nil t)
         ;; Strip CRLF from headers so that `eww-parse-headers' works correctly.
         ;; MAYBE: As an alternative, look at buffer coding systems to
@@ -1205,7 +1241,12 @@ The return value of this function is the retrieval 
buffer."
               ;; TODO: Add `hyperdrive--parent-entry-p'
               (not (string= ".."  (alist-get 'display-name
                                              (he/etc selected-entry))))))
-       :help "Delete file/directory at point"])
+       :help "Delete file/directory at point"]
+      ["Forget file" (lambda ()
+                       (interactive)
+                       (call-interactively #'h/forget-file))
+       :help "Delete local copy of file/directory contents at point"]
+      )
      ("Version"
       :label (let* ((version (he/version h/current-entry))
                     (existsp (he/exists-p h/current-entry))
@@ -1356,21 +1397,26 @@ Intended for relative (i.e. non-full) URLs."
 ;;;;; Installation
 
 (defvar h/gateway-urls-and-hashes
+  ;; TODO: sr.ht build (<https://builds.sr.ht/~ushin/job/1247130#task-setup>)
+  ;; fail due to a kernel issue: https://github.com/nodejs/node/issues/53051
   '((gnu/linux
-     ( :url 
"https://codeberg.org/USHIN/hyper-gateway-ushin/releases/download/v3.8.0/hyper-gateway-ushin-linux";
-       :sha256 
"8ff669bd378e88a3c80d65861f4088071852afaedf7bba56c88c1a162ed9e4f3")
-     ( :url 
"https://git.sr.ht/~ushin/hyper-gateway-ushin/refs/download/v3.8.0/hyper-gateway-linux-v3.8.0";
-       :sha256 ""))
+     ( :url 
"https://codeberg.org/USHIN/hyper-gateway-ushin/releases/download/v3.9.2/hyper-gateway-ushin-linux";
+       :sha256 
"f0cb3e793b3d27ce159e8e034e03b5a14cbdc53d47bd8f0761310792d5b6a7aa")
+     ;; ( :url 
"https://git.sr.ht/~ushin/hyper-gateway-ushin/refs/download/v3.9.2/hyper-gateway-linux-v3.9.2";
+     ;;   :sha256 
"331dbc0048decd42d197667f96aabdaf25306ba4e7ba0451dd9a2f31868fa86c")
+     )
     (darwin
-     ( :url 
"https://codeberg.org/USHIN/hyper-gateway-ushin/releases/download/v3.8.0/hyper-gateway-ushin-macos";
-       :sha256 
"22f6131f48d740f429690f16baac19b20a2211250360a89580db95415398d03c")
-     ( :url 
"https://git.sr.ht/~ushin/hyper-gateway-ushin/refs/download/v3.8.0/hyper-gateway-macos-v3.8.0";
-       :sha256 ""))
+     ( :url 
"https://codeberg.org/USHIN/hyper-gateway-ushin/releases/download/v3.9.2/hyper-gateway-ushin-macos";
+       :sha256 
"bb472bf7a536eb30bc2443ce90cfca1bf2aa71177afdc1377f4fc9b61414c24c")
+     ;; ( :url 
"https://git.sr.ht/~ushin/hyper-gateway-ushin/refs/download/v3.9.2/hyper-gateway-macos-v3.9.2";
+     ;;   :sha256 
"e78d3c1394774fc49212d86827eb615d46ae1a04c82fc0328ac31bbbdb201aa0")
+     )
     (windows-nt
-     ( :url 
"https://codeberg.org/USHIN/hyper-gateway-ushin/releases/download/v3.8.0/hyper-gateway-ushin-windows.exe";
-       :sha256 
"c347255d3fc5e6499fc10bea4d20e62798fb5968960dbbe26d507d11688326bb")
-     ( :url 
"https://git.sr.ht/~ushin/hyper-gateway-ushin/refs/download/v3.8.0/hyper-gateway-windows-v3.8.0.exe";
-       :sha256 "")))
+     ( :url 
"https://codeberg.org/USHIN/hyper-gateway-ushin/releases/download/v3.9.2/hyper-gateway-ushin-windows.exe";
+       :sha256 
"7a72010cd7bc1b0357673838f5ccb069e58bf3c229bc873bedd0ee9faa805188")
+     ;; ( :url 
"https://git.sr.ht/~ushin/hyper-gateway-ushin/refs/download/v3.9.2/hyper-gateway-windows-v3.9.2.exe";
+     ;;   :sha256 
"d4fa29aca473148e2d13215d042e4be40657080035caa2d3a699b741b6a45845")
+     ))
   "Alist mapping `system-type' to URLs where the gateway can be downloaded.")
 
 ;;;###autoload

Reply via email to