X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=blobdiff_plain;f=elpher.el;h=b57f2b83a269ad58ab6be28a1db805698ac87cb0;hb=a2966e515f0fb0c9b803ead48a00bab8fa42be4f;hp=1da26a6a0d5945a58e0bdad970335b3f1e99707b;hpb=856ff39c8e611791a9bc786a5c8072751a102ef8;p=elpher.git diff --git a/elpher.el b/elpher.el index 1da26a6..b57f2b8 100644 --- a/elpher.el +++ b/elpher.el @@ -1368,17 +1368,20 @@ treatment that a separate function is warranted." The gemini map file line describing the header is given by HEADER-LINE." (when (string-match "^\\(#+\\)[ \t]*" header-line) - (let ((level (length (match-string 1 header-line))) - (header (substring header-line (match-end 0)))) + (let* ((level (length (match-string 1 header-line))) + (header (substring header-line (match-end 0))) + (face (pcase level + (1 'elpher-gemini-heading1) + (2 'elpher-gemini-heading2) + (3 'elpher-gemini-heading3) + (_ 'default))) + (fill-column (/ (* fill-column + (font-get (font-spec :name (face-font 'default)) :size)) + (font-get (font-spec :name (face-font face)) :size)))) (unless (display-graphic-p) (insert (make-string level ?#) " ")) - (insert (propertize header 'face - (pcase level - (1 'elpher-gemini-heading1) - (2 'elpher-gemini-heading2) - (3 'elpher-gemini-heading3) - (_ 'default))) - "\n")))) + (insert (propertize header 'face face)) + (newline)))) (defun elpher-gemini-insert-text (text-line) "Insert a plain non-preformatted TEXT-LINE into a text/gemini document. @@ -2023,9 +2026,9 @@ With an optional argument, add all the history items, too." (define-key map "1" 'Buffer-menu-1-window) (define-key map "f" 'Buffer-menu-this-window) (define-key map "e" 'Buffer-menu-this-window) - (define-key map "\C-m" 'Buffer-menu-this-window) - (define-key map "o" 'Buffer-menu-other-window) - (define-key map "\C-o" 'Buffer-menu-switch-other-window) + (define-key map "\C-m" 'elpher-menu-this-window) + (define-key map "o" 'elpher-menu-other-window) + (define-key map "\C-o" 'elpher-menu-switch-other-window) (define-key map "d" 'Buffer-menu-delete) (define-key map "k" 'Buffer-menu-delete) (define-key map "\C-k" 'Buffer-menu-delete) @@ -2059,10 +2062,10 @@ With an optional argument, add all the history items, too." '(menu-item "Select Current" Buffer-menu-1-window :help "Select this line's buffer, alone, in full frame")) (bindings--define-key menu-map [ow] - '(menu-item "Select in Other Window" Buffer-menu-other-window + '(menu-item "Select in Other Window" elpher-menu-other-window :help "Select this line's buffer in other window, leaving buffer menu visible")) (bindings--define-key menu-map [tw] - '(menu-item "Select in Current Window" Buffer-menu-this-window + '(menu-item "Select in Current Window" elpher-menu-this-window :help "Select this line's buffer in this window")) (bindings--define-key menu-map [s2] menu-bar-separator) (bindings--define-key menu-map [is] @@ -2099,17 +2102,20 @@ With an optional argument, add all the history items, too." (define-derived-mode elpher-menu-mode tabulated-list-mode "Elpher Menu" "Major mode for Elpher Menu buffers. -The Elpher Menu is invoked by the command \\[elpher-menu]. +The Elpher Menu is invoked by the command \\[elpher-menu]. When +invoked with a prefix, the command also shows history items. +Since history items are no longer showing in a buffer, many of +the commands shown below will not work on them. In Elpher Menu mode, the following commands are defined: \\ \\[quit-window] Remove the Buffer Menu from the display. -\\[tabulated-list-sort] sorts buffers according to the current +\\[tabulated-list-sort] Sorts buffers according to the current column. With a numerical argument, sort by that column. -\\[Buffer-menu-this-window] Select current line's buffer in place of the buffer menu. -\\[Buffer-menu-other-window] Select that buffer in another window, +\\[elpher-menu-this-window] Select current line's buffer in place of the buffer menu. +\\[elpher-menu-other-window] Select that buffer in another window, so the Buffer Menu remains visible in its window. -\\[Buffer-menu-switch-other-window] Make another window display that buffer. +\\[elpher-menu-switch-other-window] Make another window display that buffer. \\[Buffer-menu-mark] Mark current line's buffer to be displayed. \\[Buffer-menu-select] Select current line's buffer. Also show buffers marked with m, in other windows. @@ -2129,6 +2135,43 @@ In Elpher Menu mode, the following commands are defined: \\[Buffer-menu-bury] Bury the buffer listed on this line." (add-hook 'tabulated-list-revert-hook 'elpher-menu-refresh nil t)) +(defun elpher-menu-this-window () + "Select this line’s buffer in this window. +Switch to the buffer, if possible. If there is no buffer, chances +are that we're looking at a history item. Let's visit the item +instead of complaining that their buffers have been killed." + (interactive) + (elpher-menu-handle-buffer-or-data 'switch-to-buffer)) + +(defun elpher-menu-other-window () + "Select this line’s buffer in other window, leaving buffer menu visible." + (interactive) + (elpher-menu-handle-buffer-or-data 'switch-to-buffer-other-window)) + +(defun elpher-menu-switch-other-window () + "Make the other window select this line's buffer. +The current window remains selected." + (interactive) + (elpher-menu-handle-buffer-or-data + (lambda (buf) (display-buffer buf t)))) + +(defun elpher-menu-handle-buffer-or-data (buffer-func) + "Handle an item in `elpher-menu-mode'. +Determine the entry ID of the Tabulated List entry at point. If +ID is a buffer, invoke BUFFER-FUNC on it. Otherwise, ID is a +list (BUFFER FUNC ARGS...). Switch to BUFFER using BUFFER-FUNC +and apply FUNC to ARGS." + (let ((data (tabulated-list-get-id))) + (cond ((bufferp data) + (funcall buffer-func data)) + ((and (listp data) + (buffer-live-p (nth 0 data)) + (fboundp (nth 1 data))) + (funcall buffer-func (nth 0 data)) + (apply (nth 1 data) (nthcdr 2 data))) + (t + (error "There's no entry on this line of the menu"))))) + (defvar elpher-title nil) (defun elpher-find-title () @@ -2147,8 +2190,9 @@ In Elpher Menu mode, the following commands are defined: (defun elpher-menu-refresh (&optional arg) "Refresh the list of buffers. -With an optional argument, add all the history items, too." - ;; Set up `tabulated-list-format'. +With an optional argument, add all the history items, too. Note +that there are no buffers for history items so many of the buffer +menu commands won't work on them." (setq tabulated-list-format (vector '("T" 1 t) '("URL" 40 t) @@ -2205,38 +2249,56 @@ An item is a list (BUFFER VECTOR) where BUFFER is the buffer this item refers to and VECTOR is what to display in the tabulated list established by `elpher-menu-refresh'. See `tabulated-list-format'." - (let ((separator (list (current-buffer) - (vector - "-" - (make-string 25 ?-) - (make-string 25 ?-))))) + ;; Every section starts with the current page, followed by some + ;; history items, and ends with the separator. + (let ((separator (list nil + (vector "-" + (make-string 25 ?-) + (make-string 25 ?-))))) (cond ((eq major-mode 'elpher-mode) - ;; every section starts with the current page and ends with - ;; the separator - (mapcar (lambda (page) - (if page - (list (current-buffer) + ;; A pair is (BUFFER-OR-DATA . PAGE) where BUFFER-OR-DTA is + ;; the current buffer, if possible, or list (BUFFER FUNC + ;; &rest ARGS) telling us which BUFFER to switch to, and + ;; what function to call. The last item of elpher-history + ;; has a nil page, so when that shows up, use the separator + (mapcar (lambda (pair) + (if (cdr pair) + (list (car pair) (vector "G" (or (elpher-address-to-url - (elpher-page-address page)) "none") - (or (elpher-page-display-string page) "?"))) + (elpher-page-address (cdr pair))) "none") + (or (elpher-page-display-string (cdr pair)) "?"))) separator)) - (cons elpher-current-page elpher-history))) + (cons (cons (current-buffer) elpher-current-page) + (mapcar (lambda (page) + (cons (list (current-buffer) 'elpher-visit-page page) + page)) + elpher-history)))) ((eq major-mode 'gemini-mode) - ;; no history means a list of one item + ;; No history means a list of one item. Add a separator. (list (list (current-buffer) (vector "E" (or (elpher-address-to-url (elpher-page-address elpher-current-page))) (or (elpher-page-display-string elpher-current-page) - (buffer-name)))))) + (buffer-name)))) + separator)) ((eq major-mode 'eww-mode) - (nconc (mapcar (lambda (data) - (list (current-buffer) - (vector "W" - (or (plist-get data :url) "none") - (or (plist-get data :title) "none")))) - (cons eww-data eww-history)) + ;; A pair is (BUFFER-OR-DATA . PAGE) where BUFFER-OR-DTA is + ;; the current buffer, if possible, or list (BUFFER FUNC + ;; &rest ARGS) telling us which BUFFER to switch to, and + ;; what function to call. Add the separator at the end. + (nconc (cons (list (current-buffer) + (vector "W" + (or (plist-get eww-data :url) "none") + (or (plist-get eww-data :title) "none"))) + (mapcar (lambda (data) + (list + (list (current-buffer) 'eww-restore-history data) + (vector "W" + (or (plist-get data :url) "none") + (or (plist-get data :title) "none")))) + eww-history)) (list separator)))))) ;;; Main start procedure