X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?p=elpher.git;a=blobdiff_plain;f=elpher.el;h=29687f1b62bc1c32e7bd9e79255117904f10a972;hp=1e46dd989465c77cf3edd38a2a3d18b74dac18f7;hb=a2074b070a34f3d424638df01bd86dc7dc934cb3;hpb=8f9cc21451fd78358e2b7fd05123026d87b5722d diff --git a/elpher.el b/elpher.el index 1e46dd9..29687f1 100644 --- a/elpher.el +++ b/elpher.el @@ -2013,7 +2013,7 @@ functions which initialize the gopher client, namely (defun elpher-menu (&optional arg) "Show a list of all your `elpher' buffers. With an optional argument, add all the history items, too." - (interactive) + (interactive "P") (switch-to-buffer (get-buffer-create "*Elpher Menu*")) (elpher-menu-mode) (elpher-menu-refresh arg) @@ -2028,9 +2028,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) @@ -2064,10 +2064,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] @@ -2104,17 +2104,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. @@ -2134,6 +2137,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 () @@ -2152,76 +2192,116 @@ 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" 35 t) - '("Name" 35 t)) + '("Name" 30 t) + '("URL" 40 t)) tabulated-list-sort-key nil) ;; Collect info for each buffer we're interested in. (let (entries) (dolist (buf (buffer-list)) (with-current-buffer buf - (when (memq major-mode '(elpher-mode eww-mode)) - (setq entries - (nconc (if arg - (elpher-menu-refresh-current) - (elpher-menu-refresh-history)) - entries))))) + (when (memq major-mode '(elpher-mode eww-mode gemini-mode)) + (if arg + (setq entries (nconc (elpher-menu-refresh-history) entries)) + (push (elpher-menu-refresh-current) entries))))) (setq tabulated-list-entries (nreverse entries))) (tabulated-list-init-header)) (defun elpher-menu-refresh-current () - "Return current entries for `elpher-menu-refresh'. -If we're only interested in the current entries, then this -function can only return a list of a single item per buffer." - (list buf - (vector - (cond ((eq major-mode 'elpher-mode) "E") - ((eq major-mode 'eww-mode) "W")) - (cond ((eq major-mode 'elpher-mode) - (or (elpher-address-to-url - (elpher-page-address elpher-current-page)) - "none")) - ((eq major-mode 'eww-mode) - (eww-current-url))) - (cond ((eq major-mode 'elpher-mode) - (or (elpher-find-title) - (elpher-page-display-string elpher-current-page))) - ((eq major-mode 'eww-mode) - (plist-get eww-data :title)))))) + "Returns an item for `elpher-menu-refresh' +based on the current buffer. + +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'." + (list (current-buffer) + (cond ((eq major-mode 'elpher-mode) + (vector "G" + (or (elpher-find-title) + (elpher-page-display-string elpher-current-page) + (buffer-name)) + (or (elpher-address-to-url + (elpher-page-address elpher-current-page)) + "none"))) + ((eq major-mode 'gemini-mode) + (vector "E" + (or (elpher-page-display-string elpher-current-page) + (buffer-name)) + (or (elpher-address-to-url + (elpher-page-address elpher-current-page)) + "none"))) + ((eq major-mode 'eww-mode) + (vector "W" + (or (plist-get eww-data :title) + (buffer-name)) + (or (eww-current-url) + "none")))))) (defun elpher-menu-refresh-history () "Return current entries for `elpher-menu-refresh'. -If we're only interested in the current entries, then this -function can only return a list of a single item per buffer." - (let ((separator (list (current-buffer) - (vector - "E" - (make-string 25 ?-) - (make-string 25 ?-))))) - (if (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) - (vector - "E" - (or (elpher-address-to-url - (elpher-page-address page)) "none") - (or (elpher-page-display-string page) "?"))) - separator)) - (cons elpher-current-page elpher-history)) - (nconc (mapcar (lambda (data) - (list (current-buffer) - (vector - "W" - (plist-get data :url) - (plist-get data :title)))) - (cons eww-data eww-history)) - (list separator))))) +This returns a list of items for the current buffer, based on the +buffer's history. + +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'." + ;; 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) + ;; 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-page-display-string (cdr pair)) "?") + (or (elpher-address-to-url + (elpher-page-address (cdr pair))) "none"))) + separator)) + (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. Add a separator. + (list (list (current-buffer) + (vector "E" + (or (elpher-page-display-string elpher-current-page) + (buffer-name)) + (or (elpher-address-to-url + (elpher-page-address elpher-current-page))))) + separator)) + ((eq major-mode 'eww-mode) + ;; 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 :title) "none") + (or (plist-get eww-data :url) "none"))) + (mapcar (lambda (data) + (list + (list (current-buffer) 'eww-restore-history data) + (vector "W" + (or (plist-get data :title) "none") + (or (plist-get data :url) "none")))) + eww-history)) + (list separator)))))) ;;; Main start procedure ;;