diff options
| author | Juri Linkov | 2019-11-12 23:31:12 +0200 |
|---|---|---|
| committer | Juri Linkov | 2019-11-12 23:31:12 +0200 |
| commit | 0a492e4dfa188f32fd04cdf95c9fa6324facae08 (patch) | |
| tree | a7e82c6205741478b7cee208830651cc70da502a | |
| parent | d0351f4d2010e3e8f3ada04b045dede10f110d7f (diff) | |
| download | emacs-0a492e4dfa188f32fd04cdf95c9fa6324facae08.tar.gz emacs-0a492e4dfa188f32fd04cdf95c9fa6324facae08.zip | |
* lisp/tab-line.el (tab-line-tabs-buffer-list-function): New variable.
(tab-line-tabs-buffer-list): New function.
(tab-line-tabs-mode-buffers, tab-line-tabs-buffer-groups):
Call tab-line-tabs-mode-buffers.
(tab-line-tabs-buffer-groups): Add 'close' function that uses
kill-buffer instead of bury-buffer that makes no sense here.
(tab-line-format): Don't show the close button when a tab
has no 'close' function or buffer.
(tab-line-switch-to-prev-tab, tab-line-switch-to-next-tab):
Support tabs with 'buffer' properties.
(tab-line-close-tab): Call 'close' function when defined.
| -rw-r--r-- | lisp/tab-line.el | 89 |
1 files changed, 62 insertions, 27 deletions
diff --git a/lisp/tab-line.el b/lisp/tab-line.el index bf090374fad..6f5b40657a9 100644 --- a/lisp/tab-line.el +++ b/lisp/tab-line.el | |||
| @@ -281,13 +281,22 @@ with the same major mode as the current buffer." | |||
| 281 | :group 'tab-line | 281 | :group 'tab-line |
| 282 | :version "27.1") | 282 | :version "27.1") |
| 283 | 283 | ||
| 284 | (defvar tab-line-tabs-buffer-list-function #'tab-line-tabs-buffer-list | ||
| 285 | "Function to return a global list of buffers. | ||
| 286 | Used only for `tab-line-tabs-mode-buffers' and `tab-line-tabs-buffer-groups'.") | ||
| 287 | |||
| 288 | (defun tab-line-tabs-buffer-list () | ||
| 289 | (seq-filter (lambda (b) (and (buffer-live-p b) | ||
| 290 | (/= (aref (buffer-name b) 0) ?\s))) | ||
| 291 | (buffer-list))) | ||
| 292 | |||
| 284 | (defun tab-line-tabs-mode-buffers () | 293 | (defun tab-line-tabs-mode-buffers () |
| 285 | "Return a list of buffers with the same major mode with current buffer." | 294 | "Return a list of buffers with the same major mode with current buffer." |
| 286 | (let ((mode major-mode)) | 295 | (let ((mode major-mode)) |
| 287 | (seq-sort-by #'buffer-name #'string< | 296 | (seq-sort-by #'buffer-name #'string< |
| 288 | (seq-filter (lambda (b) (with-current-buffer b | 297 | (seq-filter (lambda (b) (with-current-buffer b |
| 289 | (derived-mode-p mode))) | 298 | (derived-mode-p mode))) |
| 290 | (buffer-list))))) | 299 | (funcall tab-line-tabs-buffer-list-function))))) |
| 291 | 300 | ||
| 292 | (defvar tab-line-tabs-buffer-group-function nil | 301 | (defvar tab-line-tabs-buffer-group-function nil |
| 293 | "Function to put a buffer to the group. | 302 | "Function to put a buffer to the group. |
| @@ -308,18 +317,17 @@ If the major mode's name string matches REGEXP, use GROUPNAME instead.") | |||
| 308 | (defun tab-line-tabs-buffer-group-name (&optional buffer) | 317 | (defun tab-line-tabs-buffer-group-name (&optional buffer) |
| 309 | (if (functionp tab-line-tabs-buffer-group-function) | 318 | (if (functionp tab-line-tabs-buffer-group-function) |
| 310 | (funcall tab-line-tabs-buffer-group-function buffer) | 319 | (funcall tab-line-tabs-buffer-group-function buffer) |
| 311 | (unless (= (elt (buffer-name buffer) 0) ?\s) | 320 | (let ((mode (if buffer (with-current-buffer buffer |
| 312 | (let ((mode (if buffer (with-current-buffer buffer | 321 | (format-mode-line mode-name)) |
| 313 | (format-mode-line mode-name)) | 322 | (format-mode-line mode-name)))) |
| 314 | (format-mode-line mode-name)))) | 323 | (or (cdr (seq-find (lambda (group) |
| 315 | (or (cdr (seq-find (lambda (group) | 324 | (string-match-p (car group) mode)) |
| 316 | (string-match-p (car group) mode)) | 325 | tab-line-tabs-buffer-groups)) |
| 317 | tab-line-tabs-buffer-groups)) | 326 | mode)))) |
| 318 | mode))))) | ||
| 319 | 327 | ||
| 320 | (defun tab-line-tabs-buffer-groups () | 328 | (defun tab-line-tabs-buffer-groups () |
| 321 | (if (window-parameter nil 'tab-line-groups) | 329 | (if (window-parameter nil 'tab-line-groups) |
| 322 | (let* ((buffers (buffer-list)) | 330 | (let* ((buffers (funcall tab-line-tabs-buffer-list-function)) |
| 323 | (groups | 331 | (groups |
| 324 | (seq-sort tab-line-tabs-buffer-groups-sort-function | 332 | (seq-sort tab-line-tabs-buffer-groups-sort-function |
| 325 | (delq nil (mapcar #'car (seq-group-by | 333 | (delq nil (mapcar #'car (seq-group-by |
| @@ -341,8 +349,8 @@ If the major mode's name string matches REGEXP, use GROUPNAME instead.") | |||
| 341 | tabs) | 349 | tabs) |
| 342 | 350 | ||
| 343 | (let* ((window-parameter (window-parameter nil 'tab-line-group)) | 351 | (let* ((window-parameter (window-parameter nil 'tab-line-group)) |
| 344 | (group-name (tab-line-tabs-buffer-group-name)) | 352 | (group-name (tab-line-tabs-buffer-group-name (current-buffer))) |
| 345 | (group (prog1 (or window-parameter group-name) | 353 | (group (prog1 (or window-parameter group-name "All") |
| 346 | (when (equal window-parameter group-name) | 354 | (when (equal window-parameter group-name) |
| 347 | (set-window-parameter nil 'tab-line-group nil)))) | 355 | (set-window-parameter nil 'tab-line-group nil)))) |
| 348 | (group-tab `(tab | 356 | (group-tab `(tab |
| @@ -358,8 +366,8 @@ If the major mode's name string matches REGEXP, use GROUPNAME instead.") | |||
| 358 | (equal (tab-line-tabs-buffer-group-name b) | 366 | (equal (tab-line-tabs-buffer-group-name b) |
| 359 | group)) | 367 | group)) |
| 360 | (seq-uniq (append (list (current-buffer)) | 368 | (seq-uniq (append (list (current-buffer)) |
| 361 | (reverse (mapcar #'car (window-prev-buffers))) | 369 | (mapcar #'car (window-prev-buffers)) |
| 362 | (buffer-list))))) | 370 | (funcall tab-line-tabs-buffer-list-function))))) |
| 363 | (sorted-buffers (if (functionp tab-line-tabs-buffer-group-sort-function) | 371 | (sorted-buffers (if (functionp tab-line-tabs-buffer-group-sort-function) |
| 364 | (seq-sort tab-line-tabs-buffer-group-sort-function | 372 | (seq-sort tab-line-tabs-buffer-group-sort-function |
| 365 | buffers) | 373 | buffers) |
| @@ -368,7 +376,11 @@ If the major mode's name string matches REGEXP, use GROUPNAME instead.") | |||
| 368 | `(tab | 376 | `(tab |
| 369 | (name . ,(funcall tab-line-tab-name-function buffer)) | 377 | (name . ,(funcall tab-line-tab-name-function buffer)) |
| 370 | (selected . ,(eq buffer (current-buffer))) | 378 | (selected . ,(eq buffer (current-buffer))) |
| 371 | (buffer . ,buffer))) | 379 | (buffer . ,buffer) |
| 380 | (close . ,(lambda (&optional b) | ||
| 381 | ;; kill-buffer because bury-buffer | ||
| 382 | ;; won't remove the buffer from tab-line | ||
| 383 | (kill-buffer (or b buffer)))))) | ||
| 372 | sorted-buffers))) | 384 | sorted-buffers))) |
| 373 | (cons group-tab tabs)))) | 385 | (cons group-tab tabs)))) |
| 374 | 386 | ||
| @@ -427,7 +439,8 @@ variable `tab-line-tabs-function'." | |||
| 427 | separator | 439 | separator |
| 428 | (apply 'propertize | 440 | (apply 'propertize |
| 429 | (concat (propertize name 'keymap tab-line-tab-map) | 441 | (concat (propertize name 'keymap tab-line-tab-map) |
| 430 | (or (and tab-line-close-button-show | 442 | (or (and (or buffer-p (assq 'buffer tab) (assq 'close tab)) |
| 443 | tab-line-close-button-show | ||
| 431 | (not (eq tab-line-close-button-show | 444 | (not (eq tab-line-close-button-show |
| 432 | (if selected-p 'non-selected 'selected))) | 445 | (if selected-p 'non-selected 'selected))) |
| 433 | tab-line-close-button) "")) | 446 | tab-line-close-button) "")) |
| @@ -506,8 +519,9 @@ using the `previous-buffer' command." | |||
| 506 | (tab-line-select-tab-buffer buffer (posn-window posnp)) | 519 | (tab-line-select-tab-buffer buffer (posn-window posnp)) |
| 507 | (let ((select (cdr (assq 'select tab)))) | 520 | (let ((select (cdr (assq 'select tab)))) |
| 508 | (when (functionp select) | 521 | (when (functionp select) |
| 509 | (funcall select) | 522 | (with-selected-window (posn-window posnp) |
| 510 | (force-mode-line-update)))))) | 523 | (funcall select) |
| 524 | (force-mode-line-update))))))) | ||
| 511 | 525 | ||
| 512 | (defun tab-line-select-tab-buffer (buffer &optional window) | 526 | (defun tab-line-select-tab-buffer (buffer &optional window) |
| 513 | (let* ((window-buffer (window-buffer window)) | 527 | (let* ((window-buffer (window-buffer window)) |
| @@ -539,9 +553,17 @@ Its effect is the same as using the `previous-buffer' command | |||
| 539 | (if (eq tab-line-tabs-function #'tab-line-tabs-window-buffers) | 553 | (if (eq tab-line-tabs-function #'tab-line-tabs-window-buffers) |
| 540 | (switch-to-prev-buffer window) | 554 | (switch-to-prev-buffer window) |
| 541 | (with-selected-window (or window (selected-window)) | 555 | (with-selected-window (or window (selected-window)) |
| 542 | (let ((buffer (cadr (memq (current-buffer) | 556 | (let* ((tabs (funcall tab-line-tabs-function)) |
| 543 | (reverse (funcall tab-line-tabs-function)))))) | 557 | (tab (nth (1- (seq-position |
| 544 | (when buffer (switch-to-buffer buffer))))))) | 558 | tabs (current-buffer) |
| 559 | (lambda (tab buffer) | ||
| 560 | (if (bufferp tab) | ||
| 561 | (eq buffer tab) | ||
| 562 | (eq buffer (cdr (assq 'buffer tab))))))) | ||
| 563 | tabs)) | ||
| 564 | (buffer (if (bufferp tab) tab (cdr (assq 'buffer tab))))) | ||
| 565 | (when (bufferp buffer) | ||
| 566 | (switch-to-buffer buffer))))))) | ||
| 545 | 567 | ||
| 546 | (defun tab-line-switch-to-next-tab (&optional mouse-event) | 568 | (defun tab-line-switch-to-next-tab (&optional mouse-event) |
| 547 | "Switch to the next tab. | 569 | "Switch to the next tab. |
| @@ -552,16 +574,26 @@ Its effect is the same as using the `next-buffer' command | |||
| 552 | (if (eq tab-line-tabs-function #'tab-line-tabs-window-buffers) | 574 | (if (eq tab-line-tabs-function #'tab-line-tabs-window-buffers) |
| 553 | (switch-to-next-buffer window) | 575 | (switch-to-next-buffer window) |
| 554 | (with-selected-window (or window (selected-window)) | 576 | (with-selected-window (or window (selected-window)) |
| 555 | (let ((buffer (cadr (memq (current-buffer) | 577 | (let* ((tabs (funcall tab-line-tabs-function)) |
| 556 | (funcall tab-line-tabs-function))))) | 578 | (tab (nth (1+ (seq-position |
| 557 | (when buffer (switch-to-buffer buffer))))))) | 579 | tabs (current-buffer) |
| 580 | (lambda (tab buffer) | ||
| 581 | (if (bufferp tab) | ||
| 582 | (eq buffer tab) | ||
| 583 | (eq buffer (cdr (assq 'buffer tab))))))) | ||
| 584 | tabs)) | ||
| 585 | (buffer (if (bufferp tab) tab (cdr (assq 'buffer tab))))) | ||
| 586 | (when (bufferp buffer) | ||
| 587 | (switch-to-buffer buffer))))))) | ||
| 558 | 588 | ||
| 559 | 589 | ||
| 560 | (defcustom tab-line-close-tab-action 'bury-buffer | 590 | (defcustom tab-line-close-tab-action 'bury-buffer |
| 561 | "Defines what to do on closing the tab. | 591 | "Defines what to do on closing the tab. |
| 562 | If `bury-buffer', put the tab's buffer at the end of the list of all | 592 | If `bury-buffer', put the tab's buffer at the end of the list of all |
| 563 | buffers that effectively hides the buffer's tab from the tab line. | 593 | buffers that effectively hides the buffer's tab from the tab line. |
| 564 | If `kill-buffer', kills the tab's buffer." | 594 | If `kill-buffer', kills the tab's buffer. |
| 595 | This option is useful when `tab-line-tabs-function' has the value | ||
| 596 | `tab-line-tabs-window-buffers'." | ||
| 565 | :type '(choice (const :tag "Bury buffer" bury-buffer) | 597 | :type '(choice (const :tag "Bury buffer" bury-buffer) |
| 566 | (const :tag "Kill buffer" kill-buffer)) | 598 | (const :tag "Kill buffer" kill-buffer)) |
| 567 | :group 'tab-line | 599 | :group 'tab-line |
| @@ -575,10 +607,13 @@ from the tab line." | |||
| 575 | (interactive (list last-nonmenu-event)) | 607 | (interactive (list last-nonmenu-event)) |
| 576 | (let* ((posnp (and (listp mouse-event) (event-start mouse-event))) | 608 | (let* ((posnp (and (listp mouse-event) (event-start mouse-event))) |
| 577 | (window (and posnp (posn-window posnp))) | 609 | (window (and posnp (posn-window posnp))) |
| 578 | (buffer (or (get-pos-property 1 'tab (car (posn-string posnp))) | 610 | (tab (get-pos-property 1 'tab (car (posn-string posnp)))) |
| 579 | (current-buffer)))) | 611 | (buffer (if (bufferp tab) tab (cdr (assq 'buffer tab)))) |
| 612 | (close-action (unless (bufferp tab) (cdr (assq 'close tab))))) | ||
| 580 | (with-selected-window (or window (selected-window)) | 613 | (with-selected-window (or window (selected-window)) |
| 581 | (cond | 614 | (cond |
| 615 | ((functionp close-action) | ||
| 616 | (funcall close-action)) | ||
| 582 | ((eq tab-line-close-tab-action 'kill-buffer) | 617 | ((eq tab-line-close-tab-action 'kill-buffer) |
| 583 | (kill-buffer buffer)) | 618 | (kill-buffer buffer)) |
| 584 | ((eq tab-line-close-tab-action 'bury-buffer) | 619 | ((eq tab-line-close-tab-action 'bury-buffer) |