emacs/code/elpa/centaur-tabs-20230607.1501/centaur-tabs.el

219 lines
8.0 KiB
EmacsLisp

;;; centaur-tabs.el --- Aesthetic, modern looking customizable tabs plugin -*- lexical-binding: t; -*-
;; Copyright (C) 2019 Emmanuel Bustos
;; Filename: centaur-tabs.el
;; Description: Provide an out of box configuration to use highly customizable tabs.
;; URL: https://github.com/ema2159/centaur-tabs
;; Author: Emmanuel Bustos <ema2159@gmail.com>
;; Maintainer: Emmanuel Bustos <ema2159@gmail.com>
;; Created: 2019-21-19 22:14:34
;; Version: 5
;; Known Compatibility: GNU Emacs 26.2
;; Package-Requires: ((emacs "24.4") (powerline "2.4") (cl-lib "0.5"))
;;
;;
;;; This file is NOT part of GNU Emacs
;;; License
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
;; Floor, Boston, MA 02110-1301, USA.
;;; Commentary:
;;
;; Emacs plugin aiming to become an aesthetic, modern looking tabs plugin.
;;
;; This package offers tabs with a wide range of customization options, both
;; aesthetical and functional, implementing them trying to follow the Emacs
;; philosophy packing them with useful keybindings and a nice integration
;; with the Emacs environment, without sacrificing customizability.
;; Some of the features Centaur tabs offers are:
;; - Tab styles
;; - Tab icons
;; - Graying out icons
;; - Selected tab bar (over, under and left bar)
;; - Close button
;; - Modified marker
;; - Buffer grouping
;; - Projectile integration
;; - Ivy and Helm integration for group switching
;;
;;; Code:
;;; Requires
(require 'centaur-tabs-elements)
(require 'centaur-tabs-functions)
(require 'centaur-tabs-interactive)
;;;;;;;;;;;;;;;;;;;;;;; Centaur-Tabs source code ;;;;;;;;;;;;;;;;;;;;;;;
(defgroup centaur-tabs nil
"Display a tab bar in the header line."
:group 'convenience)
(defvar centaur-tabs--buffer-show-groups nil)
;;; Minor modes
;;
(defsubst centaur-tabs-mode-on-p ()
"Return non-nil if Centaur-Tabs mode is on."
(eq (default-value centaur-tabs-display-line-format)
centaur-tabs-header-line-format))
;;; Centaur-Tabs-Local mode
;;
(defvar centaur-tabs--local-hlf nil)
;;;###autoload
(define-minor-mode centaur-tabs-local-mode
"Toggle local display of the tab bar.
With prefix argument ARG, turn on if positive, otherwise off.
Returns non-nil if the new state is enabled.
When turned on, if a local header line is shown, it is hidden to show
the tab bar. The tab bar is locally hidden otherwise. When turned
off, if a local header line is hidden or the tab bar is locally
hidden, it is shown again. Signal an error if Centaur-Tabs mode is off."
:group 'centaur-tabs
:global nil
(unless (centaur-tabs-mode-on-p)
(error "Centaur-Tabs mode must be enabled"))
;;; ON
(if centaur-tabs-local-mode
(if (and (local-variable-p centaur-tabs-display-line-format)
(eval centaur-tabs-display-line-format))
;; A local header line exists, hide it to show the tab bar.
(progn
;; Fail in case of an inconsistency because another local
;; header line is already hidden.
(when (local-variable-p 'centaur-tabs--local-hlf)
(error "Another local header line is already hidden"))
(set (make-local-variable 'centaur-tabs--local-hlf)
(eval centaur-tabs-display-line-format))
(kill-local-variable centaur-tabs-display-line-format))
;; Otherwise hide the tab bar in this buffer.
(set centaur-tabs-display-line-format nil))
;;; OFF
(if (local-variable-p 'centaur-tabs--local-hlf)
;; A local header line is hidden, show it again.
(progn
(set centaur-tabs-display-line-format centaur-tabs--local-hlf)
(kill-local-variable 'centaur-tabs--local-hlf))
;; The tab bar is locally hidden, show it again.
(kill-local-variable centaur-tabs-display-line-format))))
;;; Centaur-Tabs mode
;;
(defvar centaur-tabs--global-hlf nil)
;;;###autoload
(define-minor-mode centaur-tabs-mode
"Toggle display of a tab bar in the header line.
With prefix argument ARG, turn on if positive, otherwise off.
Returns non-nil if the new state is enabled.
\\{centaur-tabs-mode-map}"
:group 'centaur-tabs
:require 'centaur-tabs
:global t
:keymap centaur-tabs-mode-map
(if centaur-tabs-mode
;;; ON
(unless (centaur-tabs-mode-on-p)
;; Save current default value of `centaur-tabs-display-line-format'.
(setq centaur-tabs--global-hlf (default-value centaur-tabs-display-line-format))
(centaur-tabs-init-tabsets-store)
(set-default centaur-tabs-display-line-format centaur-tabs-header-line-format))
;;; OFF
(when (centaur-tabs-mode-on-p)
;; Turn off Centaur-Tabs-Local mode globally.
(mapc #'(lambda (b)
(condition-case nil
(with-current-buffer b
(and centaur-tabs-local-mode
(centaur-tabs-local-mode -1)))
(error nil)))
(buffer-list))
;; Restore previous `centaur-tabs-display-line-format'.
(set-default centaur-tabs-display-line-format centaur-tabs--global-hlf)
(centaur-tabs-free-tabsets-store))
))
;;; Tab bar buffer setup
;;
(defun centaur-tabs-buffer-init ()
"Initialize tab bar buffer data.
Run as `centaur-tabs-init-hook'."
(setq centaur-tabs--buffers nil
centaur-tabs-current-tabset-function 'centaur-tabs-buffer-tabs
centaur-tabs-tab-label-function 'centaur-tabs-buffer-tab-label
centaur-tabs-select-tab-function 'centaur-tabs-buffer-select-tab
)
;; If set, initialize selected overline
(when (eq centaur-tabs-set-bar 'under)
(set-face-attribute 'centaur-tabs-selected nil
:underline (face-background 'centaur-tabs-active-bar-face nil 'default)
:overline nil)
(set-face-attribute 'centaur-tabs-selected-modified nil
:underline (face-background 'centaur-tabs-active-bar-face nil 'default)
:overline nil)
(set-face-attribute 'centaur-tabs-unselected nil
:underline nil
:overline nil)
(set-face-attribute 'centaur-tabs-unselected-modified nil
:underline nil
:overline nil))
(when (eq centaur-tabs-set-bar 'over)
(set-face-attribute 'centaur-tabs-selected nil
:overline (face-background 'centaur-tabs-active-bar-face nil 'default)
:underline nil)
(set-face-attribute 'centaur-tabs-selected-modified nil
:overline (face-background 'centaur-tabs-active-bar-face nil 'default)
:underline nil)
(set-face-attribute 'centaur-tabs-unselected nil
:overline nil
:underline nil)
(set-face-attribute 'centaur-tabs-unselected-modified nil
:overline nil
:underline nil))
(add-hook 'after-save-hook #'centaur-tabs-on-saving-buffer)
(add-hook 'first-change-hook #'centaur-tabs-on-modifying-buffer)
(add-hook 'kill-buffer-hook #'centaur-tabs-buffer-track-killed)
(advice-add #'undo :after #'centaur-tabs-after-modifying-buffer)
(advice-add #'undo-tree-undo-1 :after #'centaur-tabs-after-modifying-buffer)
(advice-add #'undo-tree-redo-1 :after #'centaur-tabs-after-modifying-buffer))
(defun centaur-tabs-buffer-quit ()
"Quit tab bar buffer.
Run as `centaur-tabs-quit-hook'."
(setq centaur-tabs--buffers nil
centaur-tabs-current-tabset-function nil
centaur-tabs-tab-label-function nil
centaur-tabs-select-tab-function nil
)
(remove-hook 'after-save-hook 'centaur-tabs-after-modifying-buffer)
(remove-hook 'first-change-hook 'centaur-tabs-on-modifying-buffer)
(remove-hook 'kill-buffer-hook 'centaur-tabs-buffer-track-killed)
(advice-remove #'undo #'centaur-tabs-after-modifying-buffer)
(advice-remove #'undo-tree-undo-1 #'centaur-tabs-after-modifying-buffer)
(advice-remove #'undo-tree-redo-1 #'centaur-tabs-after-modifying-buffer))
(add-hook 'centaur-tabs-init-hook #'centaur-tabs-buffer-init)
(add-hook 'centaur-tabs-quit-hook #'centaur-tabs-buffer-quit)
(provide 'centaur-tabs)
;;; centaur-tabs.el ends here