Added URL support to elpher-go.
[elpher.git] / elpher.el
index 449bef4..6049d0d 100644 (file)
--- a/elpher.el
+++ b/elpher.el
@@ -4,7 +4,7 @@
 
 ;; Author: Tim Vaughan <tgvaughan@gmail.com>
 ;; Created: 11 April 2019
 
 ;; Author: Tim Vaughan <tgvaughan@gmail.com>
 ;; Created: 11 April 2019
-;; Version: 1.0.0
+;; Version: 1.1.0
 ;; Keywords: comm gopher
 ;; Homepage: https://github.com/tgvaughan/elpher
 ;; Package-Requires: ((emacs "25"))
 ;; Keywords: comm gopher
 ;; Homepage: https://github.com/tgvaughan/elpher
 ;; Package-Requires: ((emacs "25"))
@@ -36,9 +36,8 @@
 ;; - (m)enu key support, similar to Emacs' info browser,
 ;; - clickable web and gopher links in plain text.
 
 ;; - (m)enu key support, similar to Emacs' info browser,
 ;; - clickable web and gopher links in plain text.
 
-;; The caching mechanism works by maintaining a hierarchy of visited
-;; pages rather than a linear history, meaning that it is quick and
-;; easy to navigate this history.
+;; Visited pages are stored as a hierarchy rather than a linear history,
+;; meaning that navigation between these pages is quick and easy.
 
 ;; To launch Elpher, simply use 'M-x elpher'.  This will open a start
 ;; page containing information on key bindings and suggested starting
 
 ;; To launch Elpher, simply use 'M-x elpher'.  This will open a start
 ;; page containing information on key bindings and suggested starting
@@ -164,8 +163,7 @@ Otherwise, use the system browser via the BROWSE-URL function."
   :type '(boolean))
 
 (defcustom elpher-buttonify-urls-in-directories nil
   :type '(boolean))
 
 (defcustom elpher-buttonify-urls-in-directories nil
-  "If non-nil, turns URLs matched in \"i\" item types in directories
-into clickable buttons."
+  "If non-nil, turns URLs matched in directories into clickable buttons."
   :type '(boolean))
 
 (defcustom elpher-cache-images nil
   :type '(boolean))
 
 (defcustom elpher-cache-images nil
@@ -201,9 +199,6 @@ use as the start page."
 
 ;; Node
 
 
 ;; Node
 
-(defvar elpher-seen-nodes (make-hash-table :test 'equal)
-  "Table mapping addresses to existing (seen) node objects.")
-
 (defun elpher-make-node (parent address getter &optional content pos)
   "Create a node in the gopher page hierarchy.
 
 (defun elpher-make-node (parent address getter &optional content pos)
   "Create a node in the gopher page hierarchy.
 
@@ -212,16 +207,8 @@ the gopher page, GETTER provides the getter function used to obtain this
 page.
 
 The optional arguments CONTENT and POS can be used to fill the cached
 page.
 
 The optional arguments CONTENT and POS can be used to fill the cached
-content and cursor position fields of the node.
-
-If the hash table `elpher-seen-nodes' contains a key equal to ADDRESS,
-the node contained as its value will be returned instead."
-  (let ((existing-node (gethash address elpher-seen-nodes)))
-    (if existing-node
-        existing-node
-      (let ((new-node (list parent address getter content pos)))
-        (puthash address new-node elpher-seen-nodes)
-        new-node))))
+content and cursor position fields of the node."
+  (list parent address getter content pos))
 
 (defun elpher-node-parent (node)
   "Retrieve the parent node of NODE."
 
 (defun elpher-node-parent (node)
   "Retrieve the parent node of NODE."
@@ -438,7 +425,9 @@ The result is stored as a string in the variable ‘elpher-selector-string’."
             (protocol (downcase (match-string 1))))
         (if (string= protocol "gopher")
             (let* ((host (match-string 2))
             (protocol (downcase (match-string 1))))
         (if (string= protocol "gopher")
             (let* ((host (match-string 2))
-                   (port 70)
+                   (port (if (match-string 3)
+                             (string-to-number (substring (match-string 3) 1))
+                           70))
                    (type-and-selector (match-string 4))
                    (type (if (> (length type-and-selector) 1)
                              (elt type-and-selector 1)
                    (type-and-selector (match-string 4))
                    (type (if (> (length type-and-selector) 1)
                              (elt type-and-selector 1)
@@ -635,16 +624,35 @@ The result is stored as a string in the variable ‘elpher-selector-string’."
 (defun elpher-go ()
   "Go to a particular gopher site."
   (interactive)
 (defun elpher-go ()
   "Go to a particular gopher site."
   (interactive)
-  (switch-to-buffer "*elpher*")
-  (let* (
-         (hostname (read-string "Gopher host: "))
-         (selector (read-string "Selector (default none): " nil nil ""))
-         (port (read-string "Port (default 70): " nil nil 70))
-         (address (list selector hostname port)))
-    (elpher-visit-node
-     (elpher-make-node elpher-current-node
-                        address
-                        #'elpher-get-index-node))))
+  (let ((node
+         (let ((host-or-url (read-string "Gopher host or URL: ")))
+           (if (string-match elpher-url-regex host-or-url)
+               (if (not (string= (downcase (match-string 1 host-or-url)) "gopher"))
+                   (error "Only gopher URLs acceptable.")
+                 (let* ((host (match-string 2 host-or-url))
+                        (port (if (match-string 3 host-or-url)
+                                  (string-to-number (substring (match-string 3 host-or-url) 1))
+                                70))
+                        (type-and-selector (match-string 4 host-or-url))
+                        (type (if (> (length type-and-selector) 1)
+                                  (elt type-and-selector 1)
+                                ?1))
+                        (selector (if (> (length type-and-selector) 1)
+                                      (substring type-and-selector 2)
+                                    ""))
+                        (address (elpher-make-address selector host port))
+                        (getter (car (alist-get type elpher-type-map))))
+                   (elpher-make-node elpher-current-node
+                                     address
+                                     getter)))
+             (let* ((selector (read-string "Selector (default none): " nil nil ""))
+                    (port (read-string "Port (default 70): " nil nil 70))
+                    (address (list selector host-or-url port)))
+               (elpher-make-node elpher-current-node
+                                 address
+                                 #'elpher-get-index-node))))))
+    (switch-to-buffer "*elpher*")
+    (elpher-visit-node node)))
 
 (defun  elpher-redraw ()
   "Redraw current page."
 
 (defun  elpher-redraw ()
   "Redraw current page."