;; Author: Tim Vaughan <tgvaughan@gmail.com>
;; Created: 11 April 2019
-;; Version: 2.3.2
+;; Version: 2.3.5
;; Keywords: comm gopher
;; Homepage: https://github.com/tgvaughan/elpher
;; Package-Requires: ((emacs "26"))
;;; Global constants
;;
-(defconst elpher-version "2.3.2"
+(defconst elpher-version "2.3.5"
"Current version of elpher.")
(defconst elpher-margin-width 6
(elpher-with-clean-buffer
(insert (propertize "\n---- ERROR -----\n\n" 'face 'error)
"When attempting to retrieve " (elpher-address-to-url address) ":\n"
- (error-message-string error) ".\n"
+ (error-message-string error) "\n"
(propertize "\n----------------\n\n" 'face 'error)
"Press 'u' to return to the previous page.")))
(setq elpher-selector-string
(concat elpher-selector-string string))))
(set-process-sentinel proc after)
- (process-send-string proc
- (concat (elpher-gopher-address-selector address) "\n")))
+ (let ((inhibit-eol-conversion t))
+ (process-send-string proc
+ (concat (elpher-gopher-address-selector address) "\r\n"))))
(error
(if (and (consp the-error)
(eq (car the-error) 'gnutls-error)
The response is stored in the variable ‘elpher-gemini-response’."
(setq elpher-gemini-response "")
(if (not (gnutls-available-p))
- (error "Cannot retrieve TLS selector: GnuTLS not available")
+ (error "Cannot establish gemini connection: GnuTLS not available")
(condition-case the-error
(let* ((kill-buffer-query-functions nil)
(proc (open-network-stream "elpher-process"
(setq elpher-gemini-response
(concat elpher-gemini-response string))))
(set-process-sentinel proc after)
- (process-send-string proc
- (concat (elpher-address-to-url address) "\r\n")))
+ (let ((inhibit-eol-conversion t))
+ (process-send-string proc
+ (concat (elpher-address-to-url address) "\r\n"))))
(error
(error "Error initiating connection to server")))))
(string-trim (substring rest (+ idx 1)))
"")))
+(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 "/"))
+ (path-reversed-normalized
+ (seq-reduce (lambda (a b)
+ (cond ((and a (equal b "..") (cdr a)))
+ ((and (not a) (equal b "..")) a) ;leading .. are dropped
+ ((equal b ".") a)
+ (t (cons b a))))
+ path nil)))
+ (string-join (reverse path-reversed-normalized) "/")))
+
(defun elpher-address-from-gemini-url (url)
"Extract address from URL with defaults as per gemini map files."
(let ((address (url-generic-parse-url url)))
(url-filename (elpher-node-address elpher-current-node)))
(url-filename address)))))
(unless (url-type address)
- (setf (url-type address) "gemini")))
+ (setf (url-type address) "gemini"))
+ (if (equal (url-type address) "gemini")
+ (setf (url-filename address)
+ (elpher-collapse-dot-sequences (url-filename address)))))
address))
(defun elpher-render-gemini-map (data _parameters)
(message "No current site.")))
(defun elpher-toggle-tls ()
- "Toggle TLS encryption mode."
+ "Toggle TLS encryption mode for gopher."
(interactive)
(setq elpher-use-tls (not elpher-use-tls))
(if elpher-use-tls
(address (elpher-node-address node)))
(if (elpher-address-special-p address)
(message "Special page: %s" display-string)
- (message (elpher-address-to-url address)))))
+ (message "%s" (elpher-address-to-url address)))))
(defun elpher-info-link ()
"Display information on node corresponding to link at point."