X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=blobdiff_plain;f=elpher.el;h=09fdb6fc556cfe8fb35599a70675d81aaf2d499a;hb=345b1efd480972459be1e569b242647d03d808db;hp=f54d18342ea43b80d558de775a60bd61b6ae40fe;hpb=a4c54eb1a28d27902f9d99ee961545dbc68e2965;p=elpher.git diff --git a/elpher.el b/elpher.el index f54d183..09fdb6f 100644 --- a/elpher.el +++ b/elpher.el @@ -4,7 +4,7 @@ ;; Author: Tim Vaughan ;; Created: 11 April 2019 -;; Version: 2.7.5 +;; Version: 2.7.8 ;; Keywords: comm gopher ;; Homepage: http://thelambdalab.xyz/elpher ;; Package-Requires: ((emacs "26")) @@ -70,7 +70,7 @@ ;;; Global constants ;; -(defconst elpher-version "2.7.5" +(defconst elpher-version "2.7.8" "Current version of elpher.") (defconst elpher-margin-width 6 @@ -152,6 +152,11 @@ the time when the text is rendered." "Specify the name of the file where elpher bookmarks will be saved." :type '(file)) +(defcustom elpher-force-ipv4 nil + "If non-nil, force elpher to use ipv4 instead of trying an ipv6 address +and falling back to an ipv4 address" + :type '(boolean)) + ;; Face customizations (defgroup elpher-faces nil @@ -222,6 +227,10 @@ the time when the text is rendered." '((t :inherit bold :height 1.2)) "Face used for gemini heading level 3.") +(defface elpher-gemini-preformatted + '((t :inherit fixed-pitch)) + "Face used for pre-formatted gemini text blocks.") + ;;; Model ;; @@ -354,7 +363,7 @@ If no address is defined, returns 0. (This is for compatibility with the URL li "Retrieve gopher selector from ADDRESS object." (if (member (url-filename address) '("" "/")) "" - (substring (url-filename address) 2))) + (url-unhex-string (substring (url-filename address) 2)))) ;; Cache @@ -547,6 +556,7 @@ to ADDRESS." (error "Cannot retrieve gopher selector: port number > 65536")) (condition-case nil (let* ((kill-buffer-query-functions nil) + (gnutls-verify-error nil) ; We use the NSM for verification (port (elpher-address-port address)) (host (elpher-address-host address)) (selector-string-parts nil) @@ -571,7 +581,7 @@ to ADDRESS." (progn (message "Disabling TLS mode.") (setq elpher-use-tls nil) - (elpher-get-selector address renderer)) + (elpher-get-selector address renderer elpher-force-ipv4)) (elpher-network-error address "Could not establish encrypted connection"))) ('connect (elpher-process-cleanup) @@ -635,7 +645,7 @@ once they are retrieved from the gopher server." (elpher-with-clean-buffer (insert "LOADING... (use 'u' to cancel)\n")) (condition-case the-error - (elpher-get-selector address renderer) + (elpher-get-selector address renderer elpher-force-ipv4) (error (elpher-network-error address the-error)))))) @@ -808,7 +818,7 @@ The response is rendered using the rendering function RENDERER." (elpher-with-clean-buffer (insert "LOADING RESULTS... (use 'u' to cancel)")) - (elpher-get-selector search-address renderer)) + (elpher-get-selector search-address renderer elpher-force-ipv4)) (if aborted (elpher-visit-previous-page)))))) @@ -875,6 +885,7 @@ to ADDRESS." (error "Cannot establish gemini connection: port number > 65536")) (condition-case nil (let* ((kill-buffer-query-functions nil) + (gnutls-verify-error nil) ; We use the NSM for verification (port (elpher-address-port address)) (host (elpher-address-host address)) (response-string-parts nil) @@ -954,7 +965,7 @@ that the response was malformed." (meta (string-trim (substring header 2)))) (list code meta body)) (error "Malformed response: No response status found in header %s" header))) - (error "Malformed response: No CRLF-delimited header found")))) + (error "Malformed response: No CRLF-delimited header found in response %s" response)))) (defun elpher-process-gemini-response (response-string renderer) "Process the gemini response RESPONSE-STRING and pass the result to RENDERER." @@ -1140,6 +1151,18 @@ by HEADER-LINE." (_ 'default))) "\n")))) +(defun elpher-gemini-insert-text (text-line) + "Insert a plain non-preformatted TEXT-LINE into a text/gemini document. +This function uses Emacs' auto-fill to wrap text sensibly to a maximum +width defined by elpher-gemini-max-fill-width." + (insert (elpher-process-text-for-display text-line)) + (let* ((prefix-end-idx (string-match "[^ \t*]" text-line)) + (fill-prefix (if prefix-end-idx + (let ((raw-prefix (substring text-line 0 prefix-end-idx))) + (replace-regexp-in-string "\*" " " raw-prefix)) + nil))) + (newline))) + (defun elpher-render-gemini-map (data _parameters) "Render DATA as a gemini map file, PARAMETERS is currently unused." (elpher-with-clean-buffer @@ -1149,10 +1172,12 @@ by HEADER-LINE." (dolist (line (split-string data "\n")) (cond ((string-prefix-p "```" line) (setq preformatted (not preformatted))) - (preformatted (insert (elpher-process-text-for-display line) "\n")) + (preformatted (insert (elpher-process-text-for-display + (propertize line 'face 'elpher-gemini-preformatted)) + "\n")) ((string-prefix-p "=>" line) (elpher-gemini-insert-link line)) ((string-prefix-p "#" line) (elpher-gemini-insert-header line)) - (t (insert (elpher-process-text-for-display line)) (newline))))) + (t (elpher-gemini-insert-text line))))) (elpher-cache-content (elpher-page-address elpher-current-page) (buffer-string)))) @@ -1771,6 +1796,7 @@ functions which initialize the gopher client, namely (switch-to-buffer "*elpher*") (switch-to-buffer "*elpher*") (setq elpher-current-page nil) + (setq elpher-history nil) (let ((start-page (elpher-make-page "Elpher Start Page" (elpher-make-special-address 'start)))) (elpher-visit-page start-page)))