Added news+acknowledgements to manual.
[elpher.git] / elpher.el
index ed0b02a..9d30254 100644 (file)
--- a/elpher.el
+++ b/elpher.el
@@ -61,8 +61,8 @@
 ;; Full instructions can be found in the Elpher info manual.
 
 ;; Elpher is under active development.  Any suggestions for
-;; improvements are welcome, and can be made on the official
-;; project page, gopher://thelambdalab.xyz/elpher, or via the
+;; improvements are welcome, and can be made on the official project
+;; page, gopher://thelambdalab.xyz/1/projects/elpher, or via the
 ;; project mailing list at https://lists.sr.ht/~michel-slm/elpher.
 
 ;;; Code:
       (lambda (s)
         (let ((_xterm-color-render nil))
           (xterm-color-filter s)))
-    'ansi-color-filter-apply)
+    #'ansi-color-filter-apply)
   "A function to filter out ANSI escape sequences.")
 
 (defalias 'elpher-color-apply
   (if (fboundp 'xterm-color-filter)
-      'xterm-color-filter
-    'ansi-color-apply)
+      #'xterm-color-filter
+    #'ansi-color-apply)
   "A function to apply ANSI escape sequences.")
 
 ;;; Global constants
   "Association list from types to getters, renderers, margin codes and index faces.")
 
 
-;;; Internal variables
-;;
-
-;; buffer-local
-(defvar elpher--gemini-page-headings nil
-  "List of headings on the page.")
-
-
 ;;; Declarations to avoid compiler warnings.
 ;;
 
@@ -397,11 +389,6 @@ requiring gopher-over-TLS."
   "Create an ADDRESS object corresponding to the given special address symbol TYPE."
   type)
 
-(defun elpher-make-start-page ()
-  "Create the start page."
-  (elpher-make-page "Elpher Start Page"
-                    (elpher-make-special-address 'start)))
-
 (defun elpher-address-to-url (address)
   "Get string representation of ADDRESS, or nil if ADDRESS is special."
   (if (elpher-address-special-p address)
@@ -501,6 +488,11 @@ If no address is defined, returns 0.  (This is for compatibility with the URL li
   "Create a page with DISPLAY-STRING and ADDRESS."
   (list display-string address))
 
+(defun elpher-make-start-page ()
+  "Create the start page."
+  (elpher-make-page "Elpher Start Page"
+                    (elpher-make-special-address 'start)))
+
 (defun elpher-page-display-string (page)
   "Retrieve the display string corresponding to PAGE."
   (elt page 0))
@@ -608,7 +600,8 @@ previously-visited pages,unless NO-HISTORY is non-nil."
      (unless (eq major-mode 'elpher-mode)
        ;; avoid resetting buffer-local variables
        (elpher-mode))
-     (let ((inhibit-read-only t))
+     (let ((inhibit-read-only t)
+           (ansi-color-context nil)) ;; clean ansi interpreter state
        (setq-local network-security-level
                    (default-value 'network-security-level))
        (erase-buffer)
@@ -685,6 +678,15 @@ ERROR can be either an error object or a string."
   (if (timerp elpher-network-timer)
       (cancel-timer elpher-network-timer)))
 
+(defun elpher-make-network-timer (thunk)
+  "Creates a timer to run the THUNK after `elpher-connection-timeout' seconds.
+This is just a wraper around `run-at-time' which additionally sets the
+buffer-local variable `elpher-network-timer' to allow
+`elpher-process-cleanup' to also clear the timer."
+  (let ((timer (run-at-time elpher-connection-timeout nil thunk)))
+    (setq-local elpher-network-timer timer)
+    timer))
+
 (defun elpher-get-host-response (address default-port query-string response-processor
                                          &optional use-tls force-ipv4)
   "Generic function for retrieving data from ADDRESS.
@@ -711,13 +713,17 @@ the host operating system and the local network capabilities.)"
     (condition-case nil
         (let* ((kill-buffer-query-functions nil)
                (port (elpher-address-port address))
-               (service (if (> port 0) port default-port))
                (host (elpher-address-host address))
-               (socks (or elpher-socks-always (string-suffix-p ".onion" host)))
+               (service (if (> port 0) port default-port))
                (response-string-parts nil)
                (bytes-received 0)
                (hkbytes-received 0)
-               (timer (run-at-time elpher-connection-timeout nil
+               (socks (or elpher-socks-always (string-suffix-p ".onion" host)))
+               (gnutls-params (list :type 'gnutls-x509pki
+                                    :hostname host
+                                    :keylist
+                                    (elpher-get-current-keylist address)))
+               (timer (elpher-make-network-timer
                                    (lambda ()
                                      (elpher-process-cleanup)
                                      (cond
@@ -740,8 +746,6 @@ the host operating system and the local network capabilities.)"
                                                                  nil force-ipv4))
                                       (t
                                        (elpher-network-error address "Connection time-out."))))))
-               (gnutls-params (list :type 'gnutls-x509pki :hostname host
-                                    :keylist (elpher-get-current-keylist address)))
                (proc (if socks (socks-open-network-stream "elpher-process" nil host service)
                        (make-network-process :name "elpher-process"
                                              :host host
@@ -810,6 +814,7 @@ the host operating system and the local network capabilities.)"
             (if use-tls (apply #'gnutls-negotiate :process proc gnutls-params))
             (funcall (process-sentinel proc) proc "open\n")))
       (error
+       (elpher-process-cleanup)
        (error "Error initiating connection to server")))))
 
 
@@ -1066,7 +1071,7 @@ If ADDRESS is not supplied or nil the record is rendered as an
 
 (defconst elpher-url-regex
   "\\([a-zA-Z]+\\)://\\([a-zA-Z0-9.-]*[a-zA-Z0-9-]\\|\\[[a-zA-Z0-9:]+\\]\\)\\(:[0-9]+\\)?\\(/\\([0-9a-zA-Z_~?/@|:.%#=&-]*[0-9a-zA-Z_~?/@|#-]\\)?\\)?"
-  "Regexp used to locate and buttinofy URLs in text files loaded by elpher.")
+  "Regexp used to locate and buttonify URLs in text files loaded by elpher.")
 
 (defun elpher-buttonify-urls (string)
   "Turn substrings which look like urls in STRING into clickable buttons."
@@ -1085,9 +1090,6 @@ If ADDRESS is not supplied or nil the record is rendered as an
                           'face 'button)))
     (buffer-string)))
 
-(defconst elpher-ansi-regex "\x1b\\[[^m]*m"
-  "Incomplete regexp used to strip out some troublesome ANSI escape sequences.")
-
 (defun elpher-process-text-for-display (string)
   "Perform any desired processing of STRING prior to display as text.
 Currently includes buttonifying URLs and processing ANSI escape codes."
@@ -1466,6 +1468,9 @@ treatment that a separate function is warranted."
         (insert (propertize display-string 'face 'elpher-unknown)))
       (insert "\n"))))
 
+(defvar elpher--gemini-page-headings nil
+  "List of headings on the page.")
+
 (defun elpher-gemini-insert-header (header-line)
   "Insert header described by HEADER-LINE into a text/gemini document.
 The gemini map file line describing the header is given
@@ -1666,26 +1671,35 @@ The result is rendered using RENDERER."
             "(Bookmarks from legacy elpher-bookmarks files will be automatically imported.)\n"
             'face 'shadow))
    (insert "\n"
-           "For Elpher release news or to leave feedback, visit:\n")
+           "The gopher home of the Elpher project is here:\n")
    (elpher-insert-index-record "The Elpher Project Page"
                                (elpher-make-gopher-address ?1
                                                            "/projects/elpher/"
                                                            "thelambdalab.xyz"
                                                            70))
-   (insert "\n"
-           "** Refer to the ")
    (let ((help-string "RET,mouse-1: Open Elpher info manual (if available)"))
-     (insert-text-button "Elpher info manual"
+     (insert "\n"
+             "The following info documentation is available:\n"
+             "   - ")
+     (insert-text-button "Elpher Manual"
                          'face 'link
                          'action (lambda (_)
                                    (interactive)
                                    (info "(elpher)"))
                          'follow-link t
-                         'help-echo help-string))
-   (insert " for the full documentation. **\n")
+                         'help-echo help-string)
+     (insert "\n   - ")
+     (insert-text-button "Changes introduced by the latest release"
+                       'face 'link
+                       'action (lambda (_)
+                                 (interactive)
+                                 (info "(elpher)News"))
+                       'follow-link t
+                       'help-echo help-string))
+   (insert "\n")
    (insert (propertize
-            (concat "  (This should be available if you have installed Elpher using\n"
-                    "   MELPA. Otherwise you will have to install the manual yourself.)\n")
+            (concat "  (These documents should be available if you have installed Elpher \n"
+                    "   using MELPA. Otherwise you may have to install the manual yourself.)\n")
             'face 'shadow))
    (elpher-restore-pos)))