X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?p=elpher.git;a=blobdiff_plain;f=elpher.el;h=1dfdded8b0f75f5a9e360601f3baf65c4740e85e;hp=1178bfccb2d0c0e1b0f269d93d1d8f12bbb8881b;hb=8eb8d6707f84064d3a3cd2947ca04fe17fc3f22e;hpb=c8c2d1acec623fc9f634a8cfc0b28d72f22295ad diff --git a/elpher.el b/elpher.el index 1178bfc..1dfdded 100644 --- a/elpher.el +++ b/elpher.el @@ -20,7 +20,7 @@ ;; Author: Tim Vaughan ;; Created: 11 April 2019 -;; Version: 3.2.1 +;; Version: 3.2.2 ;; Keywords: comm gopher ;; Homepage: https://thelambdalab.xyz/elpher ;; Package-Requires: ((emacs "27.1")) @@ -85,7 +85,7 @@ ;;; Global constants ;; -(defconst elpher-version "3.2.1" +(defconst elpher-version "3.2.2" "Current version of elpher.") (defconst elpher-margin-width 6 @@ -225,7 +225,7 @@ Otherwise, \\[elpher-show-bookmarks] will visit a special elpher bookmark page within which all of the standard elpher keybindings are active." :type '(boolean)) -(defcustom elpher-start-page "about:welcome" +(defcustom elpher-start-page-url "about:welcome" "Specify the page displayed initially by elpher. The default welcome screen is \"about:welcome\", while the bookmarks list is \"about:bookmarks\". You can also specify local files via \"file:\". @@ -340,6 +340,8 @@ the start page." (if (cdr p) (concat "/" (mapconcat #'identity (cdr p) "/")) "")))) + (when (url-host url) + (setf (url-host url) (puny-encode-domain (url-host url)))) (when (or (equal "gopher" (url-type url)) (equal "gophers" (url-type url))) ;; Gopher defaults @@ -482,9 +484,9 @@ If no address is defined, returns 0. (This is for compatibility with the URL li (list display-string address)) (defun elpher-make-start-page () - "Create the welcome page." + "Create the start page." (elpher-make-page "Start Page" - (elpher-address-from-url elpher-start-page))) + (elpher-address-from-url elpher-start-page-url))) (defun elpher-page-display-string (page) "Retrieve the display string corresponding to PAGE." @@ -502,9 +504,25 @@ If no address is defined, returns 0. (This is for compatibility with the URL li "Create a page with address and display string defined by URL. The URL is unhexed prior to its use as a display string to improve readability." - (elpher-make-page (elpher-decode (url-unhex-string url)) + (elpher-make-page (elpher-url-to-iri url) (elpher-address-from-url url))) +(defun elpher-url-to-iri (url) + "Return an IRI for URL. +Decode percent-escapes and handle punycode in the domain name. +Drop the password, if any." + (let ((data (match-data))) ; Prevent parsing clobbering match data + (unwind-protect + (let* ((address (elpher-address-from-url (elpher-decode (url-unhex-string url)))) + (host (url-host address)) + (pass (url-password address))) + (when host + (setf (url-host address) (puny-decode-domain host))) + (when pass ; RFC 3986 says we should not render + (setf (url-password address) nil)) ; the password as clear text + (url-recreate-url address)) + (set-match-data data)))) + (defvar elpher-current-page nil "The current page for this Elpher buffer.") @@ -582,7 +600,7 @@ previously-visited pages,unless NO-HISTORY is non-nil." (defun elpher-update-header () "If `elpher-use-header' is true, display current page info in window header." - (if elpher-use-header + (if (and elpher-use-header elpher-current-page) (let* ((display-string (elpher-page-display-string elpher-current-page)) (sanitized-display-string (replace-regexp-in-string "%" "%%" display-string)) (address (elpher-page-address elpher-current-page)) @@ -1053,9 +1071,7 @@ displayed. The _WINDOW argument is currently unused." (when button (let* ((page (button-get button 'elpher-page)) (address (elpher-page-address page))) - (format "mouse-1, RET: open '%s'" (if (elpher-address-about-p address) - address - (elpher-address-to-url address)))))))) + (format "mouse-1, RET: open '%s'" (elpher-address-to-url address))))))) (defun elpher-insert-index-record (display-string &optional address) "Function to insert an index record into the current buffer. @@ -1431,17 +1447,20 @@ Returns the url portion in the event that the display-string portion is empty." rest)))) (defun elpher-collapse-dot-sequences (filename) - "Collapse dot sequences in FILENAME. -For instance, the filename /a/b/../c/./d will reduce to /a/c/d" - (let* ((path (split-string filename "/")) + "Collapse dot sequences in the (absolute) FILENAME. +For instance, the filename \"/a/b/../c/./d\" will reduce to \"/a/c/d\"" + (let* ((path (split-string filename "/" t)) + (is-directory (string-match-p (rx (: (or "." ".." "/") line-end)) filename)) (path-reversed-normalized (seq-reduce (lambda (a b) - (cond ((and a (equal b "..") (cdr a))) - ((and (not a) (equal b "..")) a) ;leading .. are dropped + (cond ((equal b "..") (cdr a)) ((equal b ".") a) (t (cons b a)))) - path nil))) - (string-join (reverse path-reversed-normalized) "/"))) + path nil)) + (path-normalized (reverse path-reversed-normalized))) + (if path-normalized + (concat "/" (string-join path-normalized "/") (and is-directory "/")) + "/"))) (defun elpher-address-from-gemini-url (url) "Extract address from URL with defaults as per gemini map files. @@ -1461,6 +1480,8 @@ treatment that a separate function is warranted." (setf (url-filename address) (concat (file-name-directory (url-filename current-address)) (url-filename address))))) + (when (url-host address) + (setf (url-host address) (puny-encode-domain (url-host address)))) (unless (url-type address) (setf (url-type address) (url-type current-address))) (when (equal (url-type address) "gemini") @@ -1721,11 +1742,12 @@ Assumes UTF-8 encoding for all text files." (let ((help-string "RET,mouse-1: Open bookmark list")) (insert-text-button "bookmark list" 'face 'link - 'action (lambda (_) - (interactive) - (call-interactively #'elpher-show-bookmarks)) + 'action #'elpher-click-link 'follow-link t - 'help-echo help-string)) + 'help-echo #'elpher--page-button-help + 'elpher-page + (elpher-make-page "Elpher Bookmarks" + (elpher-make-about-address 'bookmarks)))) (insert ".\n") (insert (propertize "(Bookmarks from legacy elpher-bookmarks files will be automatically imported.)\n"