;;; 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 ;; Maintainer: Emmanuel Bustos ;; 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