branch: elpa/hyperdrive commit bcfc7adaf7ed9a58ea33881413c602eaa193fedb Merge: 4cd3643f6e 708fa6096e Author: Joseph Turner <jos...@ushin.org> Commit: Joseph Turner <jos...@ushin.org>
Merge: Mark hyperdrive as "safe", "unsafe", or "unknown" --- doc/hyperdrive.org | 16 ++++++++++------ doc/hyperdrive.texi | 16 ++++++++++------ hyperdrive-describe.el | 4 ++-- hyperdrive-lib.el | 30 ++++++++++++++++++++++++------ hyperdrive-menu.el | 13 ++++--------- hyperdrive-vars.el | 9 +++++++++ hyperdrive.el | 33 ++++++++++++++------------------- 7 files changed, 73 insertions(+), 48 deletions(-) diff --git a/doc/hyperdrive.org b/doc/hyperdrive.org index 7ba5486314..e519061501 100644 --- a/doc/hyperdrive.org +++ b/doc/hyperdrive.org @@ -741,15 +741,19 @@ The following keybindings are available in ~hyperdrive-mirror-mode~: ** Mark a hyperdrive as safe -For security reasons, ~hyperdrive.el~ does not enable major modes based -on file extension unless the hyperdrive has been marked as "safe." +For security reasons, ~hyperdrive.el~ does not enable major modes +based on file extension unless the hyperdrive has been marked as +"safe." When opening a file in a hyperdrive marked as "unknown" (the +default), ~hyperdrive.el~ will prompt you to mark the drive as "safe", +"unsafe", or "unknown". Files in hyperdrives which are marked as +"safe" are always opened in the appropriate major mode with +~set-auto-mode~. Files in hyperdrives which are marked as "unsafe" +are opened in ~fundamental-mode~ (no major mode). - Command: hyperdrive-mark-as-safe :: - Mark a hyperdrive as "safe," which will cause major modes to be - automatically be enabled based on file extension when opening files - within that hyperdrive. Files in hyperdrives which are "unsafe" - (the default) are opened in ~fundamental-mode~. + Mark a hyperdrive as "safe", "unsafe", or "unknown". This command + can also be invoked from ~hyperdrive-menu-hyperdrive~ and the menu bar. ** Purge a hyperdrive diff --git a/doc/hyperdrive.texi b/doc/hyperdrive.texi index 575656c44a..fe8a4298e7 100644 --- a/doc/hyperdrive.texi +++ b/doc/hyperdrive.texi @@ -1068,14 +1068,18 @@ Fold or unfold the section at point. @node Mark a hyperdrive as safe @section Mark a hyperdrive as safe -For security reasons, @code{hyperdrive.el} does not enable major modes based -on file extension unless the hyperdrive has been marked as ``safe.'' +For security reasons, @code{hyperdrive.el} does not enable major modes +based on file extension unless the hyperdrive has been marked as +``safe.'' When opening a file in a hyperdrive marked as ``unknown'' (the +default), @code{hyperdrive.el} will prompt you to mark the drive as ``safe'', +``unsafe'', or ``unknown''. Files in hyperdrives which are marked as +``safe'' are always opened in the appropriate major mode with +@code{set-auto-mode}. Files in hyperdrives which are marked as ``unsafe'' +are opened in @code{fundamental-mode} (no major mode). @deffn Command hyperdrive-mark-as-safe -Mark a hyperdrive as ``safe,'' which will cause major modes to be -automatically be enabled based on file extension when opening files -within that hyperdrive. Files in hyperdrives which are ``unsafe'' -(the default) are opened in @code{fundamental-mode}. +Mark a hyperdrive as ``safe'', ``unsafe'', or ``unknown''. This command +can also be invoked from @code{hyperdrive-menu-hyperdrive} and the menu bar. @end deffn @node Purge a hyperdrive diff --git a/hyperdrive-describe.el b/hyperdrive-describe.el index 80c146cd34..298ea421a0 100644 --- a/hyperdrive-describe.el +++ b/hyperdrive-describe.el @@ -56,7 +56,7 @@ Universal prefix argument \\[universal-argument] forces (setq-local h/describe-current-hyperdrive hyperdrive) (pcase-let* (((cl-struct hyperdrive metadata writablep etc) hyperdrive) - ((map disk-usage safep) etc)) + ((map disk-usage) etc)) (erase-buffer) (insert (propertize "Hyperdrive: \n" 'face 'bold) @@ -65,7 +65,7 @@ Universal prefix argument \\[universal-argument] forces (h//format hyperdrive "Petname: %P\n" h/raw-formats) (h//format hyperdrive "Nickname: %N\n" h/raw-formats) (h//format hyperdrive "Domains: %D\n" h/raw-formats) - (format "Safe: %s\n" (if safep "yes" "no")) + (format "Safe: %s\n" (h/safe-string hyperdrive)) (format "Latest version: %s\n" (h/latest-version hyperdrive)) (format "Writable: %s\n" (if writablep "yes" "no")) (format "Disk usage: %s\n" diff --git a/hyperdrive-lib.el b/hyperdrive-lib.el index 113dccca43..4f8c20c201 100644 --- a/hyperdrive-lib.el +++ b/hyperdrive-lib.el @@ -94,7 +94,10 @@ Passes ARGS to `format-message'." ;; TODO: Consider adding gv-setters for etc slot keys (etc nil :documentation "Alist of extra data. - disk-usage :: Number of bytes occupied locally by the drive. -- safep :: Whether or not to treat this hyperdrive as safe.")) +- safep :: Whether or not to treat this hyperdrive as safe. + + t :: safe + + nil :: unsafe + + \\+`unknown' (or unset) :: unknown")) (defun h/url (hyperdrive) "Return a \"hyper://\"-prefixed URL from a HYPERDRIVE struct. @@ -1366,6 +1369,7 @@ Otherwise, return nil. SLOT may be one of (declare-function h/org--link-goto "hyperdrive-org") (declare-function h/blob-mode "hyperdrive") +(declare-function h/mark-as-safe "hyperdrive") (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." @@ -1390,11 +1394,12 @@ If then, then call THEN with no arguments. Default handler." (or (not (h/writablep hyperdrive)) version)) (set-buffer-modified-p nil) (set-visited-file-modtime (current-time)))) - (if (map-elt (hyperdrive-etc hyperdrive) 'safep) - (let ((buffer-file-name (he/name entry))) - (set-auto-mode)) - (h/message "Mark hyperdrive `%s' as safe to auto-enable major mode." - (h//format-hyperdrive hyperdrive))) + (when (eq 'unknown (h/safe-p hyperdrive)) + (call-interactively #'h/mark-as-safe)) + ;; Check safe-p again after potential call to `h/mark-as-safe'. + (when (eq t (h/safe-p hyperdrive)) + (let ((buffer-file-name (he/name entry))) + (set-auto-mode t))) (when target (pcase major-mode ('org-mode @@ -1723,6 +1728,19 @@ Compares their public keys." (h/latest-version (he/hyperdrive entry))) (map-elt (he/etc entry-with-range-end) 'range-end))) +(defun h/safe-p (hyperdrive) + "Return whether HYPERDRIVE is safe or not. +Potential return values are t, nil, or \\+`unknown'. If ETC slot +has no value for \\+`safep', return \\+`unknown'." + (map-elt (h/etc hyperdrive) 'safep 'unknown)) + +(defun h/safe-string (hyperdrive) + "Return propertized string describing HYPERDRIVE safety." + (pcase-exhaustive (h/safe-p hyperdrive) + ('t (propertize "safe" 'face 'h/safe)) + ('nil (propertize "unsafe" 'face 'h/unsafe)) + ('unknown (propertize "unknown" 'face 'h/safe-unknown)))) + (defun h//ensure-dot-slash-prefix-path (path) "Return PATH, ensuring it begins with the correct prefix. Unless PATH starts with \"/\" \"./\" or \"../\", add \"./\"." diff --git a/hyperdrive-menu.el b/hyperdrive-menu.el index 818cfd5b27..63d4ac5c64 100644 --- a/hyperdrive-menu.el +++ b/hyperdrive-menu.el @@ -468,16 +468,11 @@ (h/menu--scope))) (h/set-nickname nickname hyperdrive)) -(transient-define-suffix h/menu-mark-as-safe (hyperdrive safep) +(transient-define-suffix h/menu-mark-as-safe () :description - (lambda () - (format "Safe: %s" - (if (alist-get 'safep (h/etc (h/menu--scope))) - (propertize "Yes" 'face 'success) - (propertize "No" 'face 'error)))) - (interactive - (list (h/menu--scope) (not (alist-get 'safep (h/etc (h/menu--scope)))))) - (h/mark-as-safe hyperdrive safep)) + (lambda () (format "Safe: %s" (h/safe-string (h/menu--scope)))) + (interactive) + (call-interactively #'h/mark-as-safe)) ;;;; Menu Utilities diff --git a/hyperdrive-vars.el b/hyperdrive-vars.el index ac0ac62ddb..343cc6be24 100644 --- a/hyperdrive-vars.el +++ b/hyperdrive-vars.el @@ -314,6 +314,15 @@ value (and should only be present once in the string). Used in (defface h/size '((t (:inherit font-lock-doc-face))) "File sizes.") +(defface h/safe '((t (:inherit success))) + "File sizes for entries which have been fully downloaded.") + +(defface h/unsafe '((t (:inherit error))) + "File sizes for entries which have not been downloaded.") + +(defface h/safe-unknown '((t (:inherit warning))) + "File sizes for entries which have been partially downloaded.") + (defface h/size-fully-downloaded '((t (:inherit success :weight normal))) "File sizes for entries which have been fully downloaded.") diff --git a/hyperdrive.el b/hyperdrive.el index 531a6bfaff..f29b521016 100644 --- a/hyperdrive.el +++ b/hyperdrive.el @@ -156,20 +156,19 @@ hyperdrive, the new hyperdrive's petname will be set to SEED." Interactively, prompt for hyperdrive and action." (interactive (pcase-let* ((hyperdrive (h/complete-hyperdrive)) - ((cl-struct hyperdrive (etc (map safep))) hyperdrive) (mark-safe-p (pcase (read-answer (format "Mark hyperdrive `%s' as: (currently: %s) " (h//format-hyperdrive hyperdrive) - (if safep - (propertize "safe" 'face 'success) - (propertize "unsafe" 'face 'error))) - '(("safe" ?S "Mark as safe") - ("unsafe" ?u "Mark as unsafe") + (h/safe-string hyperdrive)) + '(("safe" ?S "mark as safe") + ("unsafe" ?U "mark as unsafe") + ("unknown" ?u "ask again later") ("info" ?i "show Info manual section about safety") ("quit" ?q "quit"))) ((or ?S "safe") t) - ((or ?u "unsafe") nil) + ((or ?U "unsafe") nil) + ((or ?u "unknown") 'unknown) ((or ?i "info") :info) (_ :quit)))) (list hyperdrive mark-safe-p))) @@ -180,9 +179,7 @@ Interactively, prompt for hyperdrive and action." (h/persist hyperdrive) (message "Marked hyperdrive `%s' as %s." (h//format-hyperdrive hyperdrive) - (if safep - (propertize "safe" 'face 'success) - (propertize "unsafe" 'face 'error)))))) + (h/safe-string hyperdrive))))) (defun h/forget-file (entry) "Delete local copy of the file or directory contents of ENTRY. @@ -512,12 +509,12 @@ use, see `hyperdrive-write'." (with-current-buffer buffer (unless h/mode (h//clean-buffer) - (if (map-elt (hyperdrive-etc hyperdrive) 'safep) - (let ((buffer-file-name (he/name entry))) - (set-auto-mode)) - (h/message - "Mark hyperdrive `%s' as safe to auto-enable major mode." - (h//format-hyperdrive hyperdrive))) + (when (eq 'unknown (h/safe-p hyperdrive)) + (call-interactively #'h/mark-as-safe)) + ;; Check safe-p again after potential call to `h/mark-as-safe'. + (when (eq t (h/safe-p hyperdrive)) + (let ((buffer-file-name (he/name entry))) + (set-auto-mode t))) (h/mode)) (he//fill entry (plz-response-headers response)) ;; PUT responses only include ETag and Last-Modified @@ -1018,9 +1015,7 @@ The return value of this function is the retrieval buffer." :help "Mark hyperdrive as safe or not" :label (format-message "Mark as Safe: `%s'" - (if (alist-get 'safep (h/etc drive)) - "safe" - "unsafe"))) + (h/safe-string drive))) "---" (vector "Purge" `(lambda ()