;; Author: Tim Vaughan <plugd@thelambdalab.xyz>
;; Created: 11 April 2019
-;; Version: 3.5.1
+;; Version: 3.6.0
;; Keywords: comm gopher gemini
;; Homepage: https://thelambdalab.xyz/elpher
;; Package-Requires: ((emacs "27.1"))
;;; Global constants
;;
-(defconst elpher-version "3.5.1"
+(defconst elpher-version "3.6.0"
"Current version of elpher.")
(defconst elpher-margin-width 6
(defun elpher-remove-redundant-ports (address)
"Remove redundant port specifiers from ADDRESS.
-Here 'redundant' means that the specified port matches the default
+Here `redundant' means that the specified port matches the default
for that protocol, eg 70 for gopher."
(if (and (not (elpher-address-about-p address))
(eq (url-portspec address) ; (url-port) is too slow!
(replace-match string))
(set-match-data data))))))
+;;; Link button definitions
+;;
+
+(defvar elpher-link-keymap
+ (let ((map (make-sparse-keymap)))
+ (keymap-set map "S-<down-mouse-1>" 'ignore) ;Prevent buffer face popup
+ (keymap-set map "S-<mouse-1>" #'elpher--open-link-new-buffer-mouse)
+ (keymap-set map "S-<return>" #'elpher--open-link-new-buffer)
+ (set-keymap-parent map button-map)
+ map))
+
+(defun elpher--click-link (button)
+ "Function called when the gopher link BUTTON is activated."
+ (let ((page (button-get button 'elpher-page)))
+ (elpher-visit-page page)))
+
+(defun elpher--open-link-new-buffer ()
+ "Internal function used by Elpher to open links in a new buffer."
+ (interactive)
+ (let ((page (button-get (button-at (point)) 'elpher-page))
+ (new-buf (generate-new-buffer (default-value 'elpher-buffer-name))))
+ (pop-to-buffer new-buf)
+ (elpher-mode)
+ (elpher-visit-page page)))
+
+(defun elpher--open-link-new-buffer-mouse (event)
+ "Internal function used by Elpher to open links in a new buffer.
+The EVENT argument is the mouse event which caused this function to be
+called."
+ (interactive "e")
+ (mouse-set-point event)
+ (elpher--open-link-new-buffer))
+
+(defun elpher--page-button-help (_window buffer pos)
+ "Function called by Emacs to generate mouse-over text.
+The arguments specify the BUFFER and the POS within the buffer of the item
+for which help is required. The function returns the help to be
+displayed. The _WINDOW argument is currently unused."
+ (with-current-buffer buffer
+ (let ((button (button-at pos)))
+ (when button
+ (let* ((page (button-get button 'elpher-page))
+ (address (elpher-page-address page)))
+ (format "mouse-1, RET: open '%s'" (elpher-address-to-url address)))))))
+
+(define-button-type 'elpher-link
+ 'action #'elpher--click-link
+ 'keymap elpher-link-keymap
+ 'follow-link t
+ 'help-echo #'elpher--page-button-help
+ 'face 'button)
;;; Text Processing
;;
(let ((page (elpher-page-from-url (substring-no-properties (match-string 0)))))
(make-text-button (match-beginning 0)
(match-end 0)
- 'elpher-page page
- 'action #'elpher-click-link
- 'follow-link t
- 'help-echo #'elpher--page-button-help
- 'face 'button)))
+ 'elpher-page page
+ :type 'elpher-link)))
(buffer-string)))
(insert " "))
(insert (make-string elpher-margin-width ?\s))))
-(defun elpher--page-button-help (_window buffer pos)
- "Function called by Emacs to generate mouse-over text.
-The arguments specify the BUFFER and the POS within the buffer of the item
-for which help is required. The function returns the help to be
-displayed. The _WINDOW argument is currently unused."
- (with-current-buffer buffer
- (let ((button (button-at pos)))
- (when button
- (let* ((page (button-get button 'elpher-page))
- (address (elpher-page-address page)))
- (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.
The contents of the record are dictated by DISPLAY-STRING and ADDRESS.
If ADDRESS is not supplied or nil the record is rendered as an
-'information' line."
+`information' line."
(let* ((type (if address (elpher-address-type address) nil))
(type-map-entry (cdr (assoc type elpher-type-map))))
(if type-map-entry
(insert-text-button filtered-display-string
'face face
'elpher-page page
- 'action #'elpher-click-link
- 'follow-link t
- 'help-echo #'elpher--page-button-help))
+ :type 'elpher-link))
(pcase type
('nil ;; Information
(elpher-insert-margin)
'face 'elpher-unknown)))))
(insert "\n")))
-(defun elpher-click-link (button)
- "Function called when the gopher link BUTTON is activated."
- (let ((page (button-get button 'elpher-page)))
- (elpher-visit-page page)))
-
(defun elpher-render-index (data &optional _mime-type-string)
"Render DATA as an index. MIME-TYPE-STRING is unused."
(elpher-with-clean-buffer
(insert-text-button display-string
'face face
'elpher-page page
- 'action #'elpher-click-link
- 'follow-link t
- 'help-echo #'elpher--page-button-help))
+ :type 'elpher-link))
(newline))))))
(defun elpher-gemini-insert-header (header-line)
"Default bindings:\n"
"\n"
" - TAB/Shift-TAB: next/prev item on current page\n"
- " - RET/mouse-1: open item under cursor\n"
+ " - RET/mouse-1: open item under cursor (with Shift to open in new buffer)\n"
" - m: select an item on current page by name (autocompletes)\n"
" - u/mouse-3/U: return to previous page or to the start page\n"
" - g: go to a particular address (gopher, gemini, finger)\n"
(elpher-insert-index-record "Floodgap Systems Gopher Server"
(elpher-make-gopher-address ?1 "" "gopher.floodgap.com" 70))
(elpher-insert-index-record "Project Gemini home page"
- (elpher-address-from-url "gemini://gemini.circumlunar.space/"))
+ (elpher-address-from-url "gemini://geminiprotocol.net/"))
(insert "\n"
"Alternatively, select a search engine and enter some search terms:\n")
(elpher-insert-index-record "Gopher Search Engine (Veronica-2)"
"Your bookmarks are stored in your ")
(insert-text-button "bookmark list"
'face 'link
- 'action #'elpher-click-link
- 'follow-link t
- 'help-echo #'elpher--page-button-help
'elpher-page
(elpher-make-page "Elpher Bookmarks"
- (elpher-make-about-address 'bookmarks)))
+ (elpher-make-about-address 'bookmarks))
+ :type 'elpher-link)
(insert ".\n")
(insert (propertize
"(Bookmarks from legacy elpher-bookmarks files will be automatically imported.)\n"
(defun elpher-follow-current-link ()
"Open the link or url at point."
(interactive)
- (push-button))
+ (elpher--click-link (button-at (point))))
+
+(defun elpher-follow-current-link-new-buffer ()
+ "Open the link or url at point."
+ (interactive)
+ (elpher--open-link-new-buffer))
;;;###autoload
(defun elpher-go (host-or-url)
(define-key map (kbd "F") 'elpher-forget-current-certificate)
(when (fboundp 'evil-define-key*)
(evil-define-key*
- 'motion map
- (kbd "TAB") 'elpher-next-link
- (kbd "C-") 'elpher-follow-current-link
- (kbd "C-t") 'elpher-back
- (kbd "u") 'elpher-back
- (kbd "-") 'elpher-back
- (kbd "^") 'elpher-back
- [mouse-3] 'elpher-back
- (kbd "U") 'elpher-back-to-start
- (kbd "g") 'elpher-go
- (kbd "o") 'elpher-go-current
- (kbd "O") 'elpher-root-dir
- (kbd "s") 'elpher-show-history
- (kbd "S") 'elpher-show-visited-pages
- (kbd "r") 'elpher-redraw
- (kbd "R") 'elpher-reload
- (kbd "T") 'elpher-toggle-tls
- (kbd ".") 'elpher-view-raw
- (kbd "d") 'elpher-download
- (kbd "D") 'elpher-download-current
- (kbd "m") 'elpher-jump
- (kbd "i") 'elpher-info-link
- (kbd "I") 'elpher-info-current
- (kbd "c") 'elpher-copy-link-url
- (kbd "C") 'elpher-copy-current-url
- (kbd "a") 'elpher-bookmark-link
- (kbd "A") 'elpher-bookmark-current
- (kbd "B") 'elpher-show-bookmarks
- (kbd "!") 'elpher-set-gopher-coding-system
- (kbd "F") 'elpher-forget-current-certificate))
+ 'motion map
+ (kbd "TAB") 'elpher-next-link
+ (kbd "C-t") 'elpher-back
+ (kbd "u") 'elpher-back
+ (kbd "-") 'elpher-back
+ (kbd "^") 'elpher-back
+ [mouse-3] 'elpher-back
+ (kbd "U") 'elpher-back-to-start
+ (kbd "g") 'elpher-go
+ (kbd "o") 'elpher-go-current
+ (kbd "O") 'elpher-root-dir
+ (kbd "s") 'elpher-show-history
+ (kbd "S") 'elpher-show-visited-pages
+ (kbd "r") 'elpher-redraw
+ (kbd "R") 'elpher-reload
+ (kbd "T") 'elpher-toggle-tls
+ (kbd ".") 'elpher-view-raw
+ (kbd "d") 'elpher-download
+ (kbd "D") 'elpher-download-current
+ (kbd "m") 'elpher-jump
+ (kbd "i") 'elpher-info-link
+ (kbd "I") 'elpher-info-current
+ (kbd "c") 'elpher-copy-link-url
+ (kbd "C") 'elpher-copy-current-url
+ (kbd "a") 'elpher-bookmark-link
+ (kbd "A") 'elpher-bookmark-current
+ (kbd "B") 'elpher-show-bookmarks
+ (kbd "!") 'elpher-set-gopher-coding-system
+ (kbd "F") 'elpher-forget-current-certificate))
map)
"Keymap for gopher client.")
\input texinfo @c -*-texinfo-*-
@setfilename elpher.info
-@settitle Elpher Manual v3.5.0
+@settitle Elpher Manual v3.6.0
@dircategory Emacs
@direntry
News
+* v3.6.0::
* v3.5.0::
* v3.4.0::
* v3.3.0::
described by the following command:
@table @asis
-@keycmd{@key{RET}\, @key{mouse-1}, elpher-follow-link}
+@keycmd{@key{RET}\, @key{mouse-1}, elpher-follow-current-link}
Follow the menu item or link at point (or selected with the mouse).
Exactly what is meant by ``follow'' depends on the kind of item selected:
Once a text, menu or query response page has been displayed, its contents are
cached for the duration of the Emacs session.
+@keycmd{S-@key{RET}\, S-@key{mouse-1}, elpher-follow-current-link-new-buffer}
+Create a new Elpher buffer and follow the menu item or link at point
+in the new buffer.
+
@keycmd{@key{g}, elpher-go}
Open a particular page by specifying either its full URL or just
entering a gopher host name. (The protocol defaults to gopher, so gemini
This chapter documents the major changes introduced by Elpher releases.
@menu
+* v3.6.0::
* v3.5.0::
* v3.4.0::
* v3.3.0::
* v3.0.0::
@end menu
-@node v3.5.0, v3.4.0, News, News
+@node v3.6.0, v3.5.0, News, News
+@section v3.6.0
+
+@subsection Easily open links in new buffer
+
+This version includes the ability to open all link types in
+Elpher documents in a new buffer. By default, this is bound
+to S-@key{RET} and S-@key{mouse-1}, but this can be modified
+by adding adjusting the bindings in @code{elpher-link-keymap}.
+
+@node v3.5.0, v3.4.0, v3.6.0, News
@section v3.5.0
@subsection Automatic activation of client certificates in gemini