(defvar elpher--gemini-page-headings nil
"List of headings on the page.")
-(defvar elpher--gemini-page-links nil
- "List of links on the page.")
-
-(defvar elpher--gemini-page-links-cache (make-hash-table :test 'equal)
- "Hash of addresses and page links.")
;;; Customization group
;;
Otherwise, the SOCKS proxy is only used for connections to onion services."
:type '(boolean))
-(defcustom elpher-gemini-number-links nil
- "If non-nil, number links in gemini pages when rendering.
-Links can be accessed by pressing `v' ('visit') followed by the link number."
+(defcustom elpher-number-links nil
+ "If non-nil, number links in pages when rendering.
+Links can be followed numerically by pressing `M' and entering by the link number."
:type '(boolean))
;; Face customizations
unless NO-HISTORY is non-nil."
(elpher-save-pos)
(elpher-process-cleanup)
+ (elpher-reset-link-number-counter)
(unless (or no-history
(equal (elpher-page-address elpher-current-page)
(elpher-page-address page)))
(type-record (cdr (assoc type elpher-type-map)))
(page-links nil))
(if type-record
- (progn
- (funcall (car type-record)
- (if renderer
- renderer
- (cadr type-record)))
- (setq page-links (gethash address elpher--gemini-page-links-cache))
- (if page-links
- (setq elpher--gemini-page-links page-links)))
+ (funcall (car type-record)
+ (if renderer
+ renderer
+ (cadr type-record)))
(elpher-visit-previous-page)
(pcase type
(`(gopher ,type-char)
address
(elpher-address-to-url address))))))))
+(defvar elpher--link-number-counter 0)
+(defun elpher-reset-link-number-counter ()
+ (setq-local elpher--link-number-counter 0))
+
+(defun elpher--insert-text-button (label &rest properties)
+ "Inserts a potentially-numbered button into the current buffer.
+The text for the button is provided by LABEL, while the button
+properties in PROPERTIES are as per `insert-text-button'."
+
+ (if elpher-number-links
+ (setq-local elpher--link-number-counter (+ elpher--link-number-counter 1)))
+ (let ((pref (if elpher-number-links
+ (concat "[" (number-to-string elpher--link-number-counter) "] ")
+ "")))
+ (apply #'insert-text-button (cons (concat pref label) properties))))
+
(defun elpher-insert-index-record (display-string &optional address)
"Function to insert an index record into the current buffer.
The contents of the record are dictated by DISPLAY-STRING and ADDRESS.
(filtered-display-string (elpher-color-filter-apply display-string))
(page (elpher-make-page filtered-display-string address)))
(elpher-insert-margin margin-code)
- (insert-text-button filtered-display-string
- 'face face
- 'elpher-page page
- 'action #'elpher-click-link
- 'follow-link t
- 'help-echo #'elpher--page-button-help))
+ (elpher--insert-text-button filtered-display-string
+ 'face face
+ 'elpher-page page
+ 'action #'elpher-click-link
+ 'follow-link t
+ 'help-echo #'elpher--page-button-help))
(pcase type
('nil ;; Information
(elpher-insert-margin)
(address (elpher-address-from-gemini-url url))
(type (if address (elpher-address-type address) nil))
(type-map-entry (cdr (assoc type elpher-type-map))))
- (setq elpher--gemini-page-links (append elpher--gemini-page-links `(,address)))
(when display-string
(insert elpher-gemini-link-string)
(if type-map-entry
(let* ((face (elt type-map-entry 3))
(filtered-display-string (elpher-color-filter-apply display-string))
(page (elpher-make-page filtered-display-string address)))
- (insert-text-button filtered-display-string
- 'face face
- 'elpher-page page
- 'action #'elpher-click-link
- 'follow-link t
- 'help-echo #'elpher--page-button-help))
+ (elpher--insert-text-button filtered-display-string
+ 'face face
+ 'elpher-page page
+ 'action #'elpher-click-link
+ 'follow-link t
+ 'help-echo #'elpher--page-button-help))
(insert (propertize display-string 'face 'elpher-unknown)))
(insert "\n"))))
"Render DATA as a gemini map file, PARAMETERS is currently unused."
(elpher-with-clean-buffer
(setq elpher--gemini-page-headings nil)
- (let ((preformatted nil)
- (link-counter 1))
+ (let ((preformatted nil))
(auto-fill-mode 1)
(setq-local fill-column (min (window-width) elpher-gemini-max-fill-width))
- (setq elpher--gemini-page-links '())
(dolist (line (split-string data "\n"))
(cond
((string-prefix-p "```" line) (setq preformatted (not preformatted)))
(propertize line 'face 'elpher-gemini-preformatted))
"\n"))
((string-prefix-p "=>" line)
- (progn
- (if elpher-gemini-number-links
- (insert
- (concat
- "["
- (number-to-string link-counter)
- "] ")))
- (setq link-counter (1+ link-counter))
- (elpher-gemini-insert-link line)))
+ (elpher-gemini-insert-link line))
((string-prefix-p "#" line) (elpher-gemini-insert-header line))
(t (elpher-gemini-insert-text line)))))
(setq elpher--gemini-page-headings (nreverse elpher--gemini-page-headings))
(elpher-cache-content
(elpher-page-address elpher-current-page)
- (buffer-string))
- (puthash
- (elpher-page-address elpher-current-page)
- elpher--gemini-page-links
- elpher--gemini-page-links-cache)))
+ (buffer-string))))
(defun elpher-render-gemini-plain-text (data _parameters)
"Render DATA as plain text file. PARAMETERS is currently unused."
"\n"
" - TAB/Shift-TAB: next/prev item on current page\n"
" - RET/mouse-1: open item under cursor\n"
- " - m: select an item on current page by name (autocompletes)\n"
+ " - m/M: select an item on current page by name (autocompletes) or number\n"
" - u/mouse-3/U: return to previous page or to the start page\n"
" - o/O: visit different selector or the root menu of the current server\n"
" - g: go to a particular address (gopher, gemini, finger)\n"
- " - v: visit a numbered link on a gemini page\n"
" - d/D: download item under cursor or current page\n"
" - i/I: info on item under cursor or current page\n"
" - c/C: copy URL representation of item under cursor or current page\n"
(insert "\n"
"** Refer to the ")
(let ((help-string "RET,mouse-1: Open Elpher info manual (if available)"))
- (insert-text-button "Elpher info manual"
- 'face 'link
- 'action (lambda (_)
- (interactive)
- (info "(elpher)"))
- 'follow-link t
- 'help-echo help-string))
+ (elpher--insert-text-button "Elpher info manual"
+ 'face 'link
+ 'action (lambda (_)
+ (interactive)
+ (info "(elpher)"))
+ 'follow-link t
+ 'help-echo help-string))
(insert " for the full documentation. **\n")
(insert (propertize
(concat " (This should be available if you have installed Elpher using\n"
(elpher-address-to-url address)))))
(elpher-visit-page (elpher-make-page url (elpher-address-from-url url))))))
-(defun elpher-visit-gemini-numbered-link (n)
- "Visit link designated by a number N."
- (interactive "nLink number: ")
- (if (or (> n (length elpher--gemini-page-links))
- (< n 1))
- (user-error "Invalid link number"))
- (let ((address (nth (1- n) elpher--gemini-page-links)))
- (elpher-go (url-recreate-url address))))
-
(defun elpher-redraw ()
"Redraw current page."
(interactive)
(goto-char (button-start b))
(button-activate b)))))))
+(defun elpher-jump-to-number (n)
+ "Jump to directory entry number N."
+ (interactive "nDirectory item/link number: ")
+ (let* ((link-map (reverse (elpher-build-link-map))))
+ (if link-map
+ (if (<= 1 n (length link-map))
+ (let ((b (cdr (elt link-map (- n 1)))))
+ (goto-char (button-start b))
+ (button-activate b))
+ (error "No link with that number.")))))
+
(defun elpher-root-dir ()
"Visit root of current server."
(interactive)
(define-key map (kbd "<backtab>") 'elpher-prev-link)
(define-key map (kbd "C-M-i") 'elpher-prev-link)
(define-key map (kbd "u") 'elpher-back)
- (define-key map (kbd "U") 'elpher-back-to-start)
+ (define-key map (kbd "-") 'elpher-back)
+ (define-key map (kbd "^") 'elpher-back)
(define-key map [mouse-3] 'elpher-back)
+ (define-key map (kbd "U") 'elpher-back-to-start)
(define-key map (kbd "O") 'elpher-root-dir)
(define-key map (kbd "g") 'elpher-go)
(define-key map (kbd "o") 'elpher-go-current)
(define-key map (kbd "d") 'elpher-download)
(define-key map (kbd "D") 'elpher-download-current)
(define-key map (kbd "m") 'elpher-jump)
+ (define-key map (kbd "M") 'elpher-jump-to-number)
(define-key map (kbd "i") 'elpher-info-link)
(define-key map (kbd "I") 'elpher-info-current)
(define-key map (kbd "c") 'elpher-copy-link-url)
(define-key map (kbd "B") 'bookmark-bmenu-list)
(define-key map (kbd "S") 'elpher-set-gopher-coding-system)
(define-key map (kbd "F") 'elpher-forget-current-certificate)
- (define-key map (kbd "v") 'elpher-visit-gemini-numbered-link)
(when (fboundp 'evil-define-key*)
(evil-define-key*
'motion map
(kbd "u") 'elpher-back
(kbd "-") 'elpher-back
(kbd "^") 'elpher-back
- (kbd "U") 'elpher-back-to-start
[mouse-3] 'elpher-back
+ (kbd "U") 'elpher-back-to-start
(kbd "o") 'elpher-go
(kbd "O") 'elpher-go-current
(kbd "r") 'elpher-redraw
(kbd ".") 'elpher-view-raw
(kbd "d") 'elpher-download
(kbd "D") 'elpher-download-current
- (kbd "J") 'elpher-jump
+ (kbd "m") 'elpher-jump
+ (kbd "M") 'elpher-jump-to-number
(kbd "i") 'elpher-info-link
(kbd "I") 'elpher-info-current
(kbd "c") 'elpher-copy-link-url
(kbd "A") 'bookmark-set-no-overwrite
(kbd "B") 'bookmark-bmenu-list
(kbd "S") 'elpher-set-gopher-coding-system
- (kbd "F") 'elpher-forget-current-certificate
- (kbd "v") 'elpher-visit-gemini-numbered-link))
+ (kbd "F") 'elpher-forget-current-certificate))
map)
"Keymap for gopher client.")