diff --git a/etc/init.lisp b/etc/init.lisp index 9661014..740ef7c 100644 --- a/etc/init.lisp +++ b/etc/init.lisp @@ -299,6 +299,8 @@ (define-key "l" #'open-message-link *gemini-message-keymap*) +(define-key "b" #'gemini-history-back *gemini-message-keymap*) + ;; tags keymap (define-key "up" #'tag-go-up *tags-keymap*) diff --git a/src/gemini-viewer.lisp b/src/gemini-viewer.lisp index b28fe12..4a5a264 100644 --- a/src/gemini-viewer.lisp +++ b/src/gemini-viewer.lisp @@ -17,8 +17,25 @@ (in-package :gemini-viewer) +(defstruct gemini-metadata + (links) + (history)) + +(defun add-url-to-history (window url) + (let* ((metadata (message-window:metadata window)) + (history (reverse (gemini-metadata-history metadata)))) + (setf (gemini-metadata-history metadata) + (reverse (push url history))))) + +(defun maybe-initialize-metadata (window) + (when (not (gemini-metadata-p (message-window:metadata window))) + (setf (message-window:metadata window) + (make-gemini-metadata))) + (message-window:metadata window)) + (defun request (url) (let ((parsed-uri (puri:parse-uri url))) + (maybe-initialize-metadata specials:*message-window*) (if (null parsed-uri) (ui:error-message (format nil (_ "Could not understand the address ~s") @@ -36,6 +53,7 @@ :query query :port port) (declare (ignore x)) + (add-url-to-history specials:*message-window* url) (cond ((gemini-client:response-redirect-p status) (flet ((on-input-complete (maybe-accepted) @@ -72,7 +90,7 @@ (gemini-text (setf (message-window:source-text *message-window*) gemini-text) - (setf (message-window:metadata *message-window*) + (setf (gemini-metadata-links (message-window:metadata *message-window*)) gemini-links) (setf (keybindings *message-window*) keybindings:*gemini-message-keymap*) @@ -106,3 +124,11 @@ url e) :as-error t))))))) + +(defun history-back (window) + (when-let* ((metadata (message-window:metadata window)) + (history (misc:safe-all-but-last-elt (gemini-metadata-history metadata))) + (last (last-elt history))) + (setf (gemini-metadata-history metadata) + (misc:all-but-last-elt history)) + (request last))) diff --git a/src/package.lisp b/src/package.lisp index 3fc69e5..f1e2f33 100644 --- a/src/package.lisp +++ b/src/package.lisp @@ -1197,6 +1197,7 @@ :add-crypto-data-event :poll-vote-event :gemini-request-event + :gemini-back-event :function-event :dispatch-program-events :add-pagination-status-event @@ -1888,6 +1889,13 @@ :tui-utils) (:shadowing-import-from :misc :random-elt :shuffle) (:export + :gemini-metadata-p + :make-gemini-metadata + :gemini-metadata-links + :gemini-metadata-p + :copy-gemini-metadata + :add-url-to-history + :history-back :request)) (defpackage :main-window @@ -2042,7 +2050,8 @@ :show-about-window :reset-timeline-pagination :poll-vote - :open-gemini-address)) + :open-gemini-address + :gemini-history-back)) (defpackage :modules (:use diff --git a/src/program-events.lisp b/src/program-events.lisp index c7d5e10..c648ff0 100644 --- a/src/program-events.lisp +++ b/src/program-events.lisp @@ -901,6 +901,11 @@ (ui:focus-to-message-window) (gemini-viewer:request url))) +(defclass gemini-back-event (program-event) ()) + +(defmethod process-event ((object gemini-back-event)) + (gemini-viewer:history-back specials:*message-window*)) + (defclass function-event (program-event) ()) (defmethod process-event ((object function-event)) diff --git a/src/ui-goodies.lisp b/src/ui-goodies.lisp index bada45b..ed8b921 100644 --- a/src/ui-goodies.lisp +++ b/src/ui-goodies.lisp @@ -922,7 +922,9 @@ Force the checking for new message in the thread the selected message belong." (close-window-and-return-to-threads specials:*open-attach-window*)) (defun open-gemini-message-link-window () - (let ((links (message-window:metadata specials:*message-window*))) + (let* ((window specials:*message-window*) + (metadata (message-window:metadata window)) + (links (gemini-viewer:gemini-metadata-links metadata))) (open-message-link-window:init-gemini-links links) (focus-to-open-message-link-window))) @@ -1333,7 +1335,7 @@ This command will remove those limits so that we can just jump to the last messa "Ask for a gemini addresss and try to load it" (flet ((on-input-complete (url) (if (gemini-parser:gemini-uri-p url) - (let* ((event (make-instance 'program-events:gemini-request-event + (let* ((event (make-instance 'gemini-request-event :url url))) (program-events:push-event event)) (error-message (_ "This is not a valid gemini address"))))) @@ -1341,3 +1343,7 @@ This command will remove those limits so that we can just jump to the last messa (ask-string-input #'on-input-complete :prompt prompt :complete-fn (complete:make-complete-gemini-uri-fn prompt))))) + +(defun gemini-history-back () + "Reopen a previous visited gemini address" + (push-event (make-instance 'gemini-back-event)))