diff options
Diffstat (limited to 'lisp/+tab-bar.el')
-rw-r--r-- | lisp/+tab-bar.el | 314 |
1 files changed, 157 insertions, 157 deletions
diff --git a/lisp/+tab-bar.el b/lisp/+tab-bar.el index 3e6968e..7ff991c 100644 --- a/lisp/+tab-bar.el +++ b/lisp/+tab-bar.el | |||
@@ -12,8 +12,8 @@ | |||
12 | 12 | ||
13 | (defface +tab-bar-extra | 13 | (defface +tab-bar-extra |
14 | '((t :inherit (tab-bar font-lock-comment-face))) | 14 | '((t :inherit (tab-bar font-lock-comment-face))) |
15 | "Tab bar face for extra information, like the menu-bar and time." | 15 | "Tab bar face for extra information, like the menu-bar and time." |
16 | :group 'basic-faces) | 16 | :group 'basic-faces) |
17 | 17 | ||
18 | 18 | ||
19 | ;; Common | 19 | ;; Common |
@@ -35,97 +35,97 @@ | |||
35 | (defun +tab-bar-tracking-mode () | 35 | (defun +tab-bar-tracking-mode () |
36 | "Display `tracking-mode-line-buffers' in the tab-bar." | 36 | "Display `tracking-mode-line-buffers' in the tab-bar." |
37 | ;; TODO: write something to convert a mode-line construct to a tab-bar | 37 | ;; TODO: write something to convert a mode-line construct to a tab-bar |
38 | ;; construct. | 38 | ;; construct. |
39 | (when (and (bound-and-true-p tracking-mode) | 39 | (when (and (bound-and-true-p tracking-mode) |
40 | (not (and +tracking-hide-when-org-clocking | 40 | (not (and +tracking-hide-when-org-clocking |
41 | (bound-and-true-p org-clock-current-task)))) | 41 | (bound-and-true-p org-clock-current-task)))) |
42 | (cons (when (> (length tracking-mode-line-buffers) 0) | 42 | (cons (when (> (length tracking-mode-line-buffers) 0) |
43 | '(track-mode-line-separator menu-item " " ignore)) | 43 | '(track-mode-line-separator menu-item " " ignore)) |
44 | (cl-loop for i from 0 below (length tracking-mode-line-buffers) | 44 | (cl-loop for i from 0 below (length tracking-mode-line-buffers) |
45 | as item = (nth i tracking-mode-line-buffers) | 45 | as item = (nth i tracking-mode-line-buffers) |
46 | collect (append (list (intern (format "tracking-mode-line-%s" i)) | 46 | collect (append (list (intern (format "tracking-mode-line-%s" i)) |
47 | 'menu-item | 47 | 'menu-item |
48 | (string-trim (format-mode-line item))) | 48 | (string-trim (format-mode-line item))) |
49 | (if-let ((keymap (plist-get item 'keymap))) | 49 | (if-let ((keymap (plist-get item 'keymap))) |
50 | (list (alist-get 'down-mouse-1 (cdadr keymap))) | 50 | (list (alist-get 'down-mouse-1 (cdadr keymap))) |
51 | (list #'ignore)) | 51 | (list #'ignore)) |
52 | (when-let ((help (plist-get item 'help-echo))) | 52 | (when-let ((help (plist-get item 'help-echo))) |
53 | (list :help help))))))) | 53 | (list :help help))))))) |
54 | 54 | ||
55 | (defun +tab-bar-timer () | 55 | (defun +tab-bar-timer () |
56 | "Display `+timer-string' in the tab-bar." | 56 | "Display `+timer-string' in the tab-bar." |
57 | (when +timer-string | 57 | (when (> (length (bound-and-true-p +timer-string)) 0) |
58 | `((timer-string menu-item | 58 | `((timer-string menu-item |
59 | ,(concat " " +timer-string) | 59 | ,(concat " " +timer-string) |
60 | (lambda (ev) | 60 | (lambda (ev) |
61 | (interactive "e") | 61 | (interactive "e") |
62 | (cond ((not +timer-timer) nil) | 62 | (cond ((not +timer-timer) nil) |
63 | ((equal +timer-string +timer-running-string) | 63 | ((equal +timer-string +timer-running-string) |
64 | (popup-menu | 64 | (popup-menu |
65 | '("Running timer" | 65 | '("Running timer" |
66 | ["Cancel timer" +timer-cancel t]) | 66 | ["Cancel timer" +timer-cancel t]) |
67 | ev)) | 67 | ev)) |
68 | (t (setq +timer-string "")))))))) | 68 | (t (setq +timer-string "")))))))) |
69 | 69 | ||
70 | (defun +tab-bar-date () | 70 | (defun +tab-bar-date () |
71 | "Display `display-time-string' in the tab-bar." | 71 | "Display `display-time-string' in the tab-bar." |
72 | (when display-time-mode | 72 | (when display-time-mode |
73 | `((date-time-string menu-item | 73 | `((date-time-string menu-item |
74 | ,(substring-no-properties (concat " " (string-trim display-time-string))) | 74 | ,(substring-no-properties (concat " " (string-trim display-time-string))) |
75 | (lambda (ev) | 75 | (lambda (ev) |
76 | (interactive "e") | 76 | (interactive "e") |
77 | (popup-menu | 77 | (popup-menu |
78 | (append '("Timer") | 78 | (append '("Timer") |
79 | (let (r) | 79 | (let (r) |
80 | (dolist (time '(3 5 10)) | 80 | (dolist (time '(3 5 10)) |
81 | (push (vector (format "Timer for %d minutes" time) | 81 | (push (vector (format "Timer for %d minutes" time) |
82 | `(lambda () (interactive) | 82 | `(lambda () (interactive) |
83 | (+timer ,time)) | 83 | (+timer ,time)) |
84 | :active t) | 84 | :active t) |
85 | r)) | 85 | r)) |
86 | (nreverse r)) | 86 | (nreverse r)) |
87 | '(["Timer for ..." +timer t])) | 87 | '(["Timer for ..." +timer t])) |
88 | ev)) | 88 | ev)) |
89 | :help (discord-date-string))))) | 89 | :help (discord-date-string))))) |
90 | 90 | ||
91 | (defun +tab-bar-notmuch-count () | 91 | (defun +tab-bar-notmuch-count () |
92 | "Display a notmuch count in the tab-bar." | 92 | "Display a notmuch count in the tab-bar." |
93 | (when (and (executable-find "notmuch") | 93 | (when (and (executable-find "notmuch") |
94 | (featurep 'notmuch)) | 94 | (featurep 'notmuch)) |
95 | (let* ((counts (ignore-errors (notmuch-hello-query-counts notmuch-saved-searches))) | 95 | (let* ((counts (ignore-errors (notmuch-hello-query-counts notmuch-saved-searches))) |
96 | (next (cl-find "inbox" counts :key (lambda (l) (plist-get l :name)) :test 'equal)) | 96 | (next (cl-find "inbox+unread" counts :key (lambda (l) (plist-get l :name)) :test 'equal)) |
97 | (next-count (plist-get next :count))) | 97 | (next-count (plist-get next :count))) |
98 | (when (and next-count (> next-count 0)) | 98 | (when (and next-count (> next-count 0)) |
99 | `((notmuch-count menu-item | 99 | `((notmuch-count menu-item |
100 | ,(format " |%s|" next-count) | 100 | ,(format " |%s|" next-count) |
101 | ignore | 101 | ignore |
102 | :help ,(format "%s mails requiring attention." next-count))))))) | 102 | :help ,(format "%s mails requiring attention." next-count))))))) |
103 | 103 | ||
104 | (defun +tab-bar-org-clock () | 104 | (defun +tab-bar-org-clock () |
105 | "Display `org-mode-line-string' in the tab-bar." | 105 | "Display `org-mode-line-string' in the tab-bar." |
106 | (when (and (fboundp 'org-clocking-p) | 106 | (when (and (fboundp 'org-clocking-p) |
107 | (org-clocking-p)) | 107 | (org-clocking-p)) |
108 | ;; org-mode-line-string | 108 | ;; org-mode-line-string |
109 | `((org-clocking menu-item | 109 | `((org-clocking menu-item |
110 | ,org-mode-line-string | 110 | ,org-mode-line-string |
111 | (lambda (ev) | 111 | (lambda (ev) |
112 | (interactive "e") | 112 | (interactive "e") |
113 | (let ((menu (make-sparse-keymap | 113 | (let ((menu (make-sparse-keymap |
114 | (or org-clock-current-task "Org-Clock")))) | 114 | (or org-clock-current-task "Org-Clock")))) |
115 | (map-keymap (lambda (key binding) | 115 | (map-keymap (lambda (key binding) |
116 | (when (consp binding) | 116 | (when (consp binding) |
117 | (define-key-after menu (vector key) | 117 | (define-key-after menu (vector key) |
118 | (copy-sequence binding)))) | 118 | (copy-sequence binding)))) |
119 | (org-clock-menu)) | 119 | (org-clock-menu)) |
120 | (message "%S" ev) | 120 | (message "%S" ev) |
121 | (popup-menu menu ev))) | 121 | (popup-menu menu ev))) |
122 | :help ,(or (replace-regexp-in-string | 122 | :help ,(or (replace-regexp-in-string |
123 | (rx "[[" (group (* (not "]"))) | 123 | (rx "[[" (group (* (not "]"))) |
124 | "][" (group (* (not "]"))) | 124 | "][" (group (* (not "]"))) |
125 | "]]") | 125 | "]]") |
126 | "\\2" | 126 | "\\2" |
127 | org-clock-current-task) | 127 | org-clock-current-task) |
128 | "Org-Clock"))))) | 128 | "Org-Clock"))))) |
129 | 129 | ||
130 | (defcustom +tab-bar-emms-max-length 24 | 130 | (defcustom +tab-bar-emms-max-length 24 |
131 | "Maximum length of `+tab-bar-emms'." | 131 | "Maximum length of `+tab-bar-emms'." |
@@ -139,8 +139,8 @@ | |||
139 | (- +tab-bar-emms-max-length 2)))) | 139 | (- +tab-bar-emms-max-length 2)))) |
140 | `(emms-now-playing menu-item | 140 | `(emms-now-playing menu-item |
141 | ,(concat "{" now-playing "}" " ") | 141 | ,(concat "{" now-playing "}" " ") |
142 | emms-pause | 142 | emms-pause |
143 | ( :help ,(emms-mode-line-playlist-current)))))) | 143 | ( :help ,(emms-mode-line-playlist-current)))))) |
144 | 144 | ||
145 | (defun +tab-bar-bongo () | 145 | (defun +tab-bar-bongo () |
146 | "Display Bongo now playing information." | 146 | "Display Bongo now playing information." |
@@ -160,22 +160,22 @@ | |||
160 | "\\1: \\3" | 160 | "\\1: \\3" |
161 | (bongo-formatted-infoset)) | 161 | (bongo-formatted-infoset)) |
162 | ;; This isn't right | 162 | ;; This isn't right |
163 | (- (min 50 (/ (frame-width) 3 )) 2))) | 163 | (- (min 50 (/ (frame-width) 3 )) 2))) |
164 | "}") | 164 | "}") |
165 | (lambda () (interactive) | 165 | (lambda () (interactive) |
166 | (let ((bongo-playlist-buffer | 166 | (let ((bongo-playlist-buffer |
167 | ;; XXX: I'm sure this is terribly inefficient | 167 | ;; XXX: I'm sure this is terribly inefficient |
168 | (cl-some (lambda (b) | 168 | (cl-some (lambda (b) |
169 | (with-current-buffer b | 169 | (with-current-buffer b |
170 | (when-let* ((modep (derived-mode-p | 170 | (when-let* ((modep (derived-mode-p |
171 | 'bongo-playlist-mode)) | 171 | 'bongo-playlist-mode)) |
172 | (bongo-playlist-buffer b) | 172 | (bongo-playlist-buffer b) |
173 | (playingp (bongo-playing-p))) | 173 | (playingp (bongo-playing-p))) |
174 | b))) | 174 | b))) |
175 | (buffer-list)))) | 175 | (buffer-list)))) |
176 | (with-bongo-playlist-buffer | 176 | (with-bongo-playlist-buffer |
177 | (bongo-pause/resume)))) | 177 | (bongo-pause/resume)))) |
178 | :help ,(funcall bongo-header-line-function))))) | 178 | :help ,(funcall bongo-header-line-function))))) |
179 | 179 | ||
180 | (defvar +tab-bar-show-original nil | 180 | (defvar +tab-bar-show-original nil |
181 | "Original value of `tab-bar-show'.") | 181 | "Original value of `tab-bar-show'.") |
@@ -192,49 +192,49 @@ | |||
192 | 192 | ||
193 | ;;; FIXME this doesn't work... | 193 | ;;; FIXME this doesn't work... |
194 | ;; (defvar +tab-bar-tab-min-width 8 | 194 | ;; (defvar +tab-bar-tab-min-width 8 |
195 | ;; "Minimum width of a tab on the tab bar.") | 195 | ;; "Minimum width of a tab on the tab bar.") |
196 | 196 | ||
197 | ;; (defvar +tab-bar-tab-max-width 24 | 197 | ;; (defvar +tab-bar-tab-max-width 24 |
198 | ;; "Maximum width of a tab on the tab bar.") | 198 | ;; "Maximum width of a tab on the tab bar.") |
199 | 199 | ||
200 | ;; (defun +tab-bar-fluid-calculate-width () | 200 | ;; (defun +tab-bar-fluid-calculate-width () |
201 | ;; "Calculate the width of each tab in the tab-bar." | 201 | ;; "Calculate the width of each tab in the tab-bar." |
202 | ;; (let* ((tab-bar-list (cdr (tab-bar-make-keymap-1))) | 202 | ;; (let* ((tab-bar-list (cdr (tab-bar-make-keymap-1))) |
203 | ;; (tab-bar-avail-width (frame-width)) | 203 | ;; (tab-bar-avail-width (frame-width)) |
204 | ;; (tab-bar-tab-count (length (tab-bar-tabs))) | 204 | ;; (tab-bar-tab-count (length (tab-bar-tabs))) |
205 | ;; (tab-bar-close-button-char-width 1) | 205 | ;; (tab-bar-close-button-char-width 1) |
206 | ;; (tab-bar-add-tab-button-char-width 1) | 206 | ;; (tab-bar-add-tab-button-char-width 1) |
207 | ;; (tab-bar-total-width | 207 | ;; (tab-bar-total-width |
208 | ;; (length (mapconcat | 208 | ;; (length (mapconcat |
209 | ;; (lambda (el) | 209 | ;; (lambda (el) |
210 | ;; (when-let ((str (car-safe (cdr-safe (cdr-safe el))))) | 210 | ;; (when-let ((str (car-safe (cdr-safe (cdr-safe el))))) |
211 | ;; (substring-no-properties (eval str)))) | 211 | ;; (substring-no-properties (eval str)))) |
212 | ;; tab-bar-list))) | 212 | ;; tab-bar-list))) |
213 | ;; (tab-bar-total-tab-width | 213 | ;; (tab-bar-total-tab-width |
214 | ;; (+ (* tab-bar-tab-count tab-bar-close-button-char-width) | 214 | ;; (+ (* tab-bar-tab-count tab-bar-close-button-char-width) |
215 | ;; tab-bar-add-tab-button-char-width | 215 | ;; tab-bar-add-tab-button-char-width |
216 | ;; (length (mapconcat | 216 | ;; (length (mapconcat |
217 | ;; (lambda (el) | 217 | ;; (lambda (el) |
218 | ;; (substring-no-properties (alist-get 'name el))) | 218 | ;; (substring-no-properties (alist-get 'name el))) |
219 | ;; (tab-bar-tabs))))) | 219 | ;; (tab-bar-tabs))))) |
220 | ;; (tab-bar-total-nontab-width (- tab-bar-total-width | 220 | ;; (tab-bar-total-nontab-width (- tab-bar-total-width |
221 | ;; tab-bar-total-tab-width))) | 221 | ;; tab-bar-total-tab-width))) |
222 | ;; (min +tab-bar-tab-max-width | 222 | ;; (min +tab-bar-tab-max-width |
223 | ;; (max +tab-bar-tab-min-width | 223 | ;; (max +tab-bar-tab-min-width |
224 | ;; (/ (- tab-bar-avail-width | 224 | ;; (/ (- tab-bar-avail-width |
225 | ;; tab-bar-total-tab-width | 225 | ;; tab-bar-total-tab-width |
226 | ;; tab-bar-total-nontab-width) | 226 | ;; tab-bar-total-nontab-width) |
227 | ;; tab-bar-tab-count))))) | 227 | ;; tab-bar-tab-count))))) |
228 | 228 | ||
229 | ;; (defun +tab-bar-fluid-width () | 229 | ;; (defun +tab-bar-fluid-width () |
230 | ;; "Generate the tab name to fluidly fit in the given space." | 230 | ;; "Generate the tab name to fluidly fit in the given space." |
231 | ;; (let* ((tab-file-name (buffer-file-name (window-buffer | 231 | ;; (let* ((tab-file-name (buffer-file-name (window-buffer |
232 | ;; (minibuffer-selected-window))))) | 232 | ;; (minibuffer-selected-window))))) |
233 | ;; (format (format " %%s%%%ds" (+tab-bar-fluid-calculate-width)) | 233 | ;; (format (format " %%s%%%ds" (+tab-bar-fluid-calculate-width)) |
234 | ;; (if tab-file-name | 234 | ;; (if tab-file-name |
235 | ;; (file-name-nondirectory tab-file-name) | 235 | ;; (file-name-nondirectory tab-file-name) |
236 | ;; (+tab-bar-tab-name-truncated-left)) | 236 | ;; (+tab-bar-tab-name-truncated-left)) |
237 | ;; " "))) | 237 | ;; " "))) |
238 | 238 | ||
239 | (defun +tab-bar-tab-name-truncated-left () | 239 | (defun +tab-bar-tab-name-truncated-left () |
240 | "Generate the tab name from the buffer of the selected window. | 240 | "Generate the tab name from the buffer of the selected window. |
@@ -259,13 +259,13 @@ name to the left." | |||
259 | (defun +tab-bar-format-align-right () | 259 | (defun +tab-bar-format-align-right () |
260 | "Align the rest of tab bar items to the right, pixel-wise." | 260 | "Align the rest of tab bar items to the right, pixel-wise." |
261 | ;; XXX: ideally, wouldn't require `shr' here | 261 | ;; XXX: ideally, wouldn't require `shr' here |
262 | (require 'shr) ; `shr-string-pixel-width' | 262 | (require 'shr) ; `shr-string-pixel-width' |
263 | (let* ((rest (cdr (memq '+tab-bar-format-align-right tab-bar-format))) | 263 | (let* ((rest (cdr (memq '+tab-bar-format-align-right tab-bar-format))) |
264 | (rest (tab-bar-format-list rest)) | 264 | (rest (tab-bar-format-list rest)) |
265 | (rest (mapconcat (lambda (item) (nth 2 item)) rest "")) | 265 | (rest (mapconcat (lambda (item) (nth 2 item)) rest "")) |
266 | (hpos (shr-string-pixel-width rest)) | 266 | (hpos (shr-string-pixel-width rest)) |
267 | (str (propertize " " 'display `(space :align-to (- right (,hpos)))))) | 267 | (str (propertize " " 'display `(space :align-to (- right (,hpos)))))) |
268 | `((align-right menu-item ,str ignore)))) | 268 | `((align-right menu-item ,str ignore)))) |
269 | 269 | ||
270 | 270 | ||
271 | ;;; Menu bar | 271 | ;;; Menu bar |
@@ -309,18 +309,18 @@ Used by `tab-bar-format-menu-bar'." | |||
309 | `((current-tab | 309 | `((current-tab |
310 | menu-item | 310 | menu-item |
311 | ,(funcall tab-bar-tab-name-format-function tab i) | 311 | ,(funcall tab-bar-tab-name-format-function tab i) |
312 | ignore | 312 | ignore |
313 | :help "Current tab"))) | 313 | :help "Current tab"))) |
314 | (t | 314 | (t |
315 | `((,(intern (format "tab-%i" i)) | 315 | `((,(intern (format "tab-%i" i)) |
316 | menu-item | 316 | menu-item |
317 | ,(funcall tab-bar-tab-name-format-function tab i) | 317 | ,(funcall tab-bar-tab-name-format-function tab i) |
318 | ,(alist-get 'binding tab) | 318 | ,(alist-get 'binding tab) |
319 | :help "Click to visit tab")))) | 319 | :help "Click to visit tab")))) |
320 | (when (alist-get 'close-binding tab) | 320 | (when (alist-get 'close-binding tab) |
321 | `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i))) | 321 | `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i))) |
322 | menu-item "" | 322 | menu-item "" |
323 | ,(alist-get 'close-binding tab))))))) | 323 | ,(alist-get 'close-binding tab))))))) |
324 | 324 | ||
325 | 325 | ||
326 | ;; Emacs 27 | 326 | ;; Emacs 27 |
@@ -334,7 +334,7 @@ This is :filter-return advice for `tab-bar-make-keymap-1'." | |||
334 | ,reserve))))) | 334 | ,reserve))))) |
335 | (prog1 (append output | 335 | (prog1 (append output |
336 | `((align-right menu-item ,str nil)) | 336 | `((align-right menu-item ,str nil)) |
337 | (+tab-bar-misc-info))))) | 337 | (+tab-bar-misc-info))))) |
338 | 338 | ||
339 | 339 | ||
340 | ;; Emacs 28 | 340 | ;; Emacs 28 |
@@ -353,27 +353,27 @@ This is :filter-return advice for `tab-bar-make-keymap-1'." | |||
353 | (define-minor-mode +tab-bar-misc-info-mode | 353 | (define-minor-mode +tab-bar-misc-info-mode |
354 | "Show the `mode-line-misc-info' in the `tab-bar'." | 354 | "Show the `mode-line-misc-info' in the `tab-bar'." |
355 | :lighter "" | 355 | :lighter "" |
356 | :global t | 356 | :global t |
357 | (if +tab-bar-misc-info-mode | 357 | (if +tab-bar-misc-info-mode |
358 | (progn ; Enable | 358 | (progn ; Enable |
359 | (setq +tab-bar-show-original tab-bar-show) | 359 | (setq +tab-bar-show-original tab-bar-show) |
360 | (cond | 360 | (cond |
361 | ((boundp 'tab-bar-format) ; Emacs 28 | 361 | ((boundp 'tab-bar-format) ; Emacs 28 |
362 | (setq +tab-bar-format-original tab-bar-format) | 362 | (setq +tab-bar-format-original tab-bar-format) |
363 | (unless (memq '+tab-bar-misc-info tab-bar-format) | 363 | (unless (memq '+tab-bar-misc-info tab-bar-format) |
364 | (setq tab-bar-format | 364 | (setq tab-bar-format |
365 | (append tab-bar-format (+tab-bar-misc-info-28))))) | 365 | (append tab-bar-format (+tab-bar-misc-info-28))))) |
366 | ((fboundp 'tab-bar-make-keymap-1) ; Emacs 27 | 366 | ((fboundp 'tab-bar-make-keymap-1) ; Emacs 27 |
367 | (advice-add 'tab-bar-make-keymap-1 :filter-return | 367 | (advice-add 'tab-bar-make-keymap-1 :filter-return |
368 | '+tab-bar-misc-info-27))) | 368 | '+tab-bar-misc-info-27))) |
369 | (setq tab-bar-show t)) | 369 | (setq tab-bar-show t)) |
370 | (progn ; Disable | 370 | (progn ; Disable |
371 | (setq tab-bar-show +tab-bar-show-original) | 371 | (setq tab-bar-show +tab-bar-show-original) |
372 | (cond | 372 | (cond |
373 | ((boundp 'tab-bar-format) ; Emacs 28 | 373 | ((boundp 'tab-bar-format) ; Emacs 28 |
374 | (setq tab-bar-format +tab-bar-format-original)) | 374 | (setq tab-bar-format +tab-bar-format-original)) |
375 | ((fboundp 'tab-bar-make-keymap-1) ; Emacs 27 | 375 | ((fboundp 'tab-bar-make-keymap-1) ; Emacs 27 |
376 | (advice-remove 'tab-bar-make-keymap-1 '+tab-bar-misc-info-27)))))) | 376 | (advice-remove 'tab-bar-make-keymap-1 '+tab-bar-misc-info-27)))))) |
377 | 377 | ||
378 | 378 | ||
379 | 379 | ||