From c3492c06c1dcb982478a7cf7813ac4ff31dcaec0 Mon Sep 17 00:00:00 2001 From: cage Date: Sat, 6 Nov 2021 12:32:03 +0100 Subject: [PATCH] - [gemini] added 'search-message-gemini-fragment-event' When a fragment is present in a uri/iri it is used as a regular expression to search in the *source* of the text, the window's content is moved to shows the *rendered* line where matching occurred. --- etc/shared.conf | 3 --- src/gemini-viewer.lisp | 19 +++++++++---------- src/message-window.lisp | 4 ++-- src/package.lisp | 4 +++- src/program-events.lisp | 6 ++++++ 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/etc/shared.conf b/etc/shared.conf index cd8bf3c..36e2cbf 100644 --- a/etc/shared.conf +++ b/etc/shared.conf @@ -210,7 +210,4 @@ open ".gpub$" with "tinmop" # E.g. gemini://foo/bar.gmi#baz will jump to the first occurence of "baz" # the fragment is used as a regular expressions -# Note: incomplete implementation, works fine for headers, preformatted text, -# and likely links, broken for the rest. - experimental.gemini.iri.fragment.regex = no \ No newline at end of file diff --git a/src/gemini-viewer.lisp b/src/gemini-viewer.lisp index 77e70b0..387ba57 100644 --- a/src/gemini-viewer.lisp +++ b/src/gemini-viewer.lisp @@ -442,12 +442,14 @@ (setf (stream-status wrapper-object) :completed) (when (and fragment (swconf:config-gemini-fragment-as-regex-p)) - (let ((regex (if (text-utils:percent-encoded-p fragment) - (text-utils:percent-encode fragment) - fragment)) - (priority program-events:+standard-event-priority+)) - (ui::message-search-regex-callback regex - :priority priority))))) + (let* ((regex (if (text-utils:percent-encoded-p fragment) + (text-utils:percent-decode fragment) + fragment)) + (priority program-events:+standard-event-priority+) + (event (make-instance 'program-events:search-message-gemini-fragment-event + :priority priority + :payload regex))) + (program-events:push-event event))))) ;; (allow-downloading wrapper-object) (gemini-client:close-ssl-socket download-socket)))))))) ;; (fs:delete-file-if-exists support-file))))) @@ -727,10 +729,7 @@ :as-error t)) #-debug-mode (error (e) - (ui:notify (format nil - (_ "Error getting ~s: ~a") - url - e) + (ui:notify (format nil (_ "Error getting ~s: ~a") url e) :as-error t))))) (defun history-back (window) diff --git a/src/message-window.lisp b/src/message-window.lisp index 732325d..b1a88a3 100644 --- a/src/message-window.lisp +++ b/src/message-window.lisp @@ -741,7 +741,7 @@ fragment matches- move the window to the line when matching occurred." finally (setf rest-blanks (subseq blanks ct))) (values (reverse res) rest-blanks)))) (with-accessors ((row-selected-index row-selected-index)) window - (let ((rest-rows (rows-safe-subseq window row-selected-index)) + (let ((rest-rows (rest (rows-safe-subseq window row-selected-index))) (matching-source-line nil) (matching-source-id nil) (matching-source-position nil) @@ -772,7 +772,7 @@ fragment matches- move the window to the line when matching occurred." (reconstructed-rows (reconstruct-source-lines text-rows matching-source-blanks)) (line-matched (loop for reconstructed-row in reconstructed-rows - for line from 0 + for line from 1 for length-accum = (length reconstructed-row) then (+ length-accum (length reconstructed-row)) diff --git a/src/package.lisp b/src/package.lisp index 7de97f6..715f7db 100644 --- a/src/package.lisp +++ b/src/package.lisp @@ -1429,6 +1429,7 @@ :fetch-remote-status-event :process-event :search-next-event + :search-message-gemini-fragment-event :search-regex-message-content-event :thread-search-message-body-event :search-direction @@ -2118,7 +2119,8 @@ :generate-gemini-toc :gemini-toc-entry :gemini-toc-group-id - :init)) + :init + :search-gemini-fragment)) (defpackage :open-attach-window (:use diff --git a/src/program-events.lisp b/src/program-events.lisp index fd406ac..41ac977 100644 --- a/src/program-events.lisp +++ b/src/program-events.lisp @@ -453,6 +453,12 @@ (cl-ppcre:ppcre-syntax-error () (ui:error-message (_ "Invalid regular expression"))))))) +(defclass search-message-gemini-fragment-event (search-event) ()) + +(defmethod process-event ((object search-message-gemini-fragment-event)) + (let ((fragment (payload object))) + (message-window:search-gemini-fragment specials:*message-window* fragment))) + (defclass thread-search-event (search-event) ((search-direction :initform nil