summaryrefslogtreecommitdiff
path: root/elpa/tabbar-ruler-20160802.307/tabbar-ruler.el
diff options
context:
space:
mode:
Diffstat (limited to 'elpa/tabbar-ruler-20160802.307/tabbar-ruler.el')
-rw-r--r--elpa/tabbar-ruler-20160802.307/tabbar-ruler.el2150
1 files changed, 2150 insertions, 0 deletions
diff --git a/elpa/tabbar-ruler-20160802.307/tabbar-ruler.el b/elpa/tabbar-ruler-20160802.307/tabbar-ruler.el
new file mode 100644
index 0000000..20323cf
--- /dev/null
+++ b/elpa/tabbar-ruler-20160802.307/tabbar-ruler.el
@@ -0,0 +1,2150 @@
+;;; tabbar-ruler.el --- Pretty tabbar, autohide, use both tabbar/ruler
+;;
+;; Filename: tabbar-ruler.el
+;; Description: Changes tabbar setup to be similar to Aquaemacs.
+;; Author: Matthew Fidler, Ta Quang Trung, Nathaniel Cunningham
+;; Maintainer: Matthew L. Fidler
+;; Created: Mon Oct 18 17:06:07 2010 (-0500)
+;; Version: 0.45
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800)
+;; By: Matthew L. Fidler
+;; Update #: 663
+;; URL: http://github.com/mlf176f2/tabbar-ruler.el
+;; Keywords: Tabbar, Ruler Mode, Menu, Tool Bar.
+;; Compatibility: Windows Emacs 23.x
+;; Package-Requires: ((tabbar "2.0.1") (powerline "2.3") (mode-icons "0.4.0") (cl-lib "0.5"))
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;; * Introduction
+;; Tabbar ruler is an Emacs package that allows both the tabbar and the
+;; ruler to be used together. In addition it allows auto-hiding of the
+;; menu-bar and tool-bar.
+;;
+;;
+;; Tabbar appearance based on reverse engineering Aquaemacs code and
+;; changing to my preferences, and Emacs Wiki.
+;;
+;; Tabbar/Ruler integration is new. Tabbar should be active on mouse
+;; move. Ruler should be active on self-insert commands.
+;;
+;; Also allows auto-hiding of toolbar and menu.
+;;
+;; To use this, put the library in your load path and use
+;;
+;;
+;; (setq tabbar-ruler-global-tabbar t) ; If you want tabbar
+;; (setq tabbar-ruler-global-ruler t) ; if you want a global ruler
+;; (setq tabbar-ruler-popup-menu t) ; If you want a popup menu.
+;; (setq tabbar-ruler-popup-toolbar t) ; If you want a popup toolbar
+;; (setq tabbar-ruler-popup-scrollbar t) ; If you want to only show the
+;; ; scroll bar when your mouse is moving.
+;; (require 'tabbar-ruler)
+;;
+;;
+;;
+;;
+;; * Changing how tabbar groups files/buffers
+;; The default behavior for tabbar-ruler is to group the tabs by frame.
+;; You can change this back to the old-behavior by:
+;;
+;; (tabbar-ruler-group-buffer-groups)
+;;
+;; or by issuing the following code:
+;;
+;;
+;; (setq tabbar-buffer-groups-function 'tabbar-buffer-groups)
+;;
+;;
+;; In addition, you can also group by projectile project easily by:
+;;
+;;
+;; (tabbar-ruler-group-by-projectile-project)
+;;
+;; * Adding key-bindings to tabbar-ruler
+;; You can add key-bindings to change the current tab. The easiest way
+;; to add the bindings is to add a key like:
+;;
+;;
+;; (global-set-key (kbd "C-c t") 'tabbar-ruler-move)
+;;
+;;
+;; After that, all you would need to press is Control+c t and then the
+;; arrow keys will allow you to change the buffer quite easily. To exit
+;; the buffer movement you can press enter or space.
+;;
+;; * Known issues
+;; the left arrow is text instead of an image.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Change Log:
+;; 13-Sep-2014 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Version bump
+;; 1-Jul-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Fix variable misspecification
+;; 28-Jun-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Fixed strange org-readme issue
+;; 28-Jun-2013 Matthew L. Fidler
+;; Last-Updated: Tue Oct 19 15:37:53 2010 (-0500) (us041375) #663 (Matthew L. Fidler)
+;; Added popup scrollbarbar
+;; 27-Jun-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Added autoload for tabbar-install-faces. That way ergoemacs and other
+;; packages can load the tabbar-ruler by just calling (tabbar-install-faces)
+;; 6-Jun-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Added left-char and right char to tabbar-ruler-move-keymap so that
+;; keybindings in emacs 24.3 work correctly.
+;; 6-Jun-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Changed movement commands. The movement commands are simpler (in my opinion)
+;; 4-Jun-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Change package description. Fixed the documentation to actually
+;; change to the old tabbar method of grouping buffers.
+;; 4-Jun-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Turn off ruler mode in the next buffer (if necessary)
+;; 4-Jun-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Add movement keys. Also add toggles for different groupings.
+;; 1-May-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Try to address issue #4
+;; 1-May-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Changed the modified font to italics. Made the modified symbol
+;; customizable, but off by default. Should address issue #5.
+;; 5-Apr-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Trying to update upstream sources.
+;; 5-Apr-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Fixed speed issues on windows. It wasn't a redraw that was causing
+;; the speed issues, it was the constant recreation of the right-click
+;; menus...
+;; 27-Mar-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Fixed typo to fix issue #2.
+;; 27-Mar-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Attempt to fix issue #2. Whenever the color is not a string, assume
+;; that it should be transparent. I'm unsure if the mac osx puts the
+;; translated color to a string. However, it seems that the undefined
+;; should be the same as transparent. Therefore, this fix *should* work...
+;; 20-Mar-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Add inverse video option for unselected tabbar. Made it the default.
+;; has better contrast between the selected and unselected tabs.
+;; 20-Mar-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Changed emacs 24.3 to support the times character. Also removed
+;; starred documentation strings.
+;; 20-Mar-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Emacs 24.3 had an error when using ucs-insert. Added fallbacks so
+;; that this works when ucs-insert does not work.
+;; 20-Feb-2013 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Changed so that the separators do not need to be fancy images. I
+;; found that when the separators were images, it slowed down emacs on
+;; windows. Therefore, the fancy images are disabled by default. This
+;; also includes the stylized close symbols.
+;; 19-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Added back popup-menu
+;; 19-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Upload to marmalade
+;; 19-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Changed slope. Made the background color the default background color
+;; if unspecified. Made tabbar-hex-color return "None" if not defined
+;; 15-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Made sure that the tabbr-ruler-separator-image is at least 17 pixels high
+;; 15-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Sat Dec 15 15:44:34 2012 (+0800) #663 (Matthew L. Fidler)
+;; Attempt to fix another bug on load
+;; 14-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Thu Mar 1 09:02:56 2012 (-0600) #659 (Matthew L. Fidler)
+;; Fixed tabbar ruler so that it loads cold.
+;; 14-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Thu Mar 1 09:02:56 2012 (-0600) #659 (Matthew L. Fidler)
+;; Memoized the tabbar images to speed things up
+;; 14-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Thu Mar 1 09:02:56 2012 (-0600) #659 (Mat`'thew L. Fidler)
+;; Upload to Marmalade
+;; 14-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Thu Mar 1 09:02:56 2012 (-0600) #659 (Matthew L. Fidler)
+;; Fancy tabs
+;; 13-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Thu Mar 1 09:02:56 2012 (-0600) #659 (Matthew L. Fidler)
+;; Added Bug fix for coloring. Made the selected tab match the default
+;; color in the buffer. Everything else is grayed out.
+;; 10-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Thu Mar 1 09:02:56 2012 (-0600) #659 (Matthew L. Fidler)
+;; Took out a statement that may fix the left-scrolling bug?
+;; 10-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Thu Mar 1 09:02:56 2012 (-0600) #659 (Matthew L. Fidler)
+;; Added package-menu-mode to the excluded tabbar-ruler fight modes.
+;; 07-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Thu Mar 1 09:02:56 2012 (-0600) #659 (Matthew L. Fidler)
+;; Will no longer take over editing of org source blocks or info blocks.
+;; 07-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Thu Mar 1 09:02:56 2012 (-0600) #659 (Matthew L. Fidler)
+;; Changed the order of checking so that helm will work when you move a mouse.
+;; 07-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Thu Mar 1 09:02:56 2012 (-0600) #659 (Matthew L. Fidler)
+;; Now works with Helm. Should fix issue #1
+;; 06-Dec-2012 Matthew L. Fidler
+;; Last-Updated: Thu Mar 1 09:02:56 2012 (-0600) #659 (Matthew L. Fidler)
+;; Now colors are based on loaded theme (from minibar). Also added
+;; bug-fix for setting tabbar colors every time a frame opens. Also
+;; added a bug fix for right-clicking a frame that is not associated with
+;; a buffer.
+;; 1-Mar-2012 Matthew L. Fidler
+;; Last-Updated: Thu Mar 1 08:38:09 2012 (-0600) #656 (Matthew L. Fidler)
+;; Will not change tool-bar-mode in Mac. It causes some funny
+;; things to happen.
+;; 9-Feb-2012 Matthew L. Fidler
+;; Last-Updated: Thu Feb 9 19:18:21 2012 (-0600) #651 (Matthew L. Fidler)
+;; Will not change the menu bar in a Mac. Its always there.
+;; 14-Jan-2012 Matthew L. Fidler
+;; Last-Updated: Sat Jan 14 21:58:51 2012 (-0600) #648 (Matthew L. Fidler)
+;; Added more commands that trigger the ruler.
+;; 14-Jan-2012 Matthew L. Fidler
+;; Last-Updated: Sat Jan 14 21:44:32 2012 (-0600) #641 (Matthew L. Fidler)
+;; Added more ruler commands. It works a bit better
+;; now. Additionally I have changed the ep- to tabbar-ruler-.
+;; 14-Jan-2012 Matthew L. Fidler
+;; Last-Updated: Tue Feb 8 15:01:27 2011 (-0600) #639 (Matthew L. Fidler)
+;; Changed EmacsPortable to tabbar-ruler
+;; 08-Feb-2011 Matthew L. Fidler
+;; Last-Updated: Tue Feb 8 14:59:57 2011 (-0600) #638 (Matthew L. Fidler)
+;; Added ELPA tags.
+;; 08-Feb-2011 Matthew L. Fidler
+;; Last-Updated: Tue Feb 8 12:47:09 2011 (-0600) #604 (Matthew L. Fidler)
+;; Removed xpm dependencies. Now no images are required, they are built by the library.
+;; 04-Dec-2010 Matthew L. Fidler
+;; Last-Updated: Sat Dec 4 16:27:07 2010 (-0600) #551 (Matthew L. Fidler)
+;; Added context menu.
+;; 01-Dec-2010 Matthew L. Fidler
+;; Last-Updated: Wed Dec 1 15:26:37 2010 (-0600) #341 (Matthew L. Fidler)
+;; Added scratch buffers to list.
+;; 04-Nov-2010
+;; Last-Updated: Thu Nov 4 09:39:14 2010 (-0500) (us041375)
+;; Made tabbar mode default.
+;; 02-Nov-2010 Matthew L. Fidler
+;; Last-Updated: Tue Nov 2 10:14:12 2010 (-0500) (Matthew L. Fidler)
+;; Make post-command-hook handle errors gracefully.
+;; 20-Oct-2010 Matthew L. Fidler
+;; Last-Updated: Tue Oct 19 15:37:53 2010 (-0500) (us041375)
+;;
+;; Changed behavior when outside the window to assume the last
+;; known mouse position. This fixes the two problems below.
+;;
+;; 20-Oct-2010 Matthew L. Fidler
+;; Last-Updated: Tue Oct 19 15:37:53 2010 (-0500) (us041375)
+;;
+;; As it turns out when the toolbar is hidden when the mouse is
+;; outside of the emacs window, it also hides when navigating the
+;; menu. Switching behavior back.
+;;
+;; 20-Oct-2010 Matthew L. Fidler
+;; Last-Updated: Tue Oct 19 15:37:53 2010 (-0500) (us041375)
+;; Made popup menu and toolbar be hidden when mouse is oustide of emacs window.
+;; 20-Oct-2010 Matthew L. Fidler
+;; Last-Updated: Tue Oct 19 15:37:53 2010 (-0500) (us041375)
+;; Changed to popup ruler-mode if tabbar and ruler are not displayed.
+;; 19-Oct-2010 Matthew L. Fidler
+;; Last-Updated: Tue Oct 19 15:37:53 2010 (-0500) (us041375)
+;; Changed tabbar, menu, toolbar and ruler variables to be buffer
+;; or frame local.
+;;
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; 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.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(add-to-list 'load-path (file-name-directory (or load-file-name (buffer-file-name))))
+
+(require 'cl-lib)
+(require 'tabbar)
+(require 'easymenu)
+(require 'powerline nil t)
+(require 'mode-icons nil t)
+
+(defgroup tabbar-ruler nil
+ "Pretty tabbar, autohide, use both tabbar/ruler."
+ :group 'tabbar)
+
+(defcustom tabbar-ruler-global-tabbar t
+ "Should tabbar-ruler have a global tabbar?"
+ :type 'boolean
+ :group 'tabbar-ruler)
+(defcustom tabbar-ruler-global-ruler nil
+ "Should tabbar-ruler have a global ruler?"
+ :type 'boolean
+ :group 'tabbar-ruler)
+(defcustom tabbar-ruler-popup-menu nil
+ "Should tabbar-ruler have a popup menu. As mouse moves toward top of window, the menu pops up."
+ :type 'boolean
+ :group 'tabbar-ruler)
+(defcustom tabbar-ruler-popup-toolbar nil
+ "Should tabbar-ruler have a popup toolbar. As mouse moves toward top of window, the toolbar pops up."
+ :type 'boolean
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-popup-scrollbar nil
+ "Should tabbas-ruler have popup scrollbar. As mouse moves, the scroll-bar pops up. Otherwise the sroll-bar is turned off."
+ :type 'boolean
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-popup-menu-min-y 5 ;
+ "Minimum number of pixels from the top before a menu/toolbar pops up."
+ :type 'integer
+ :group 'tabbar-ruler)
+(defcustom tabbar-ruler-popup-menu-min-y-leave 50
+ "Minimum number of pixels form the top before a menu/toolbar disappears."
+ :type 'integer
+ :group 'tabbar-ruler)
+(defcustom tabbar-ruler-do-not-switch-on-ruler-when-tabbar-is-on-y 75
+ "Minimum number of pixels to switch on ruler when tabbar is on."
+ :type 'integer
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-excluded-buffers '("*Messages*" "*Completions*" "*ESS*" "*Packages*" "*log-edit-files*" "*helm-mini*" "*helm-mode-describe-variable*")
+ "Excluded buffers in tabbar."
+ :type '(repeat (string :tag "Buffer Name"))
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-fight-igore-modes '(info-mode helm-mode package-menu-mode)
+ "Exclude these mode when changing between tabbar and ruler."
+ :type '(repeat (symbol :tag "Major Mode"))
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-use-mode-icons t
+ "Use mode icons for tabbar-ruler."
+ :type '(choice
+ (const :tag "No" nil)
+ (const :tag "If enabled" if-enabled)
+ (const :tag "Always" t))
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-recolor-inactive-icons t
+ "Recolor inactive icons for `mode-icons' icons."
+ :type '(choice
+ (const :tag "No" nil)
+ (const :tag "If enabled" if-enabled)
+ (const :tag "Always" t))
+ :group 'tabbar-ruler)
+
+(when tabbar-ruler-use-mode-icons
+ (require 'mode-icons nil t)
+ (if (fboundp #'mode-icons-mode)
+ (mode-icons-mode)
+ (warn "Cannot start mode-icons-mode, icons will be missing from tabs.")))
+
+(defcustom tabbar-ruler-mode-icon-for-unknown-modes nil
+ "Use mode icons for unknown modes."
+ :type 'boolean
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-fancy-tab-separator nil
+ "Separate each tab with a fancy generated image."
+ :type '(choice
+ (const :tag "Text" nil)
+ (const :tag "Alternate" alternate)
+ (const :tag "arrow" arrow)
+ (const :tag "arrow-fade" arrow-fade)
+ (const :tag "bar" bar)
+ (const :tag "box" box)
+ (const :tag "brace" brace)
+ (const :tag "butt" butt)
+ (const :tag "chamfer" chamfer)
+ (const :tag "contour" contour)
+ (const :tag "curve" curve)
+ (const :tag "rounded" rounded)
+ (const :tag "roundstub" roundstub)
+ (const :tag "slant" slant)
+ (const :tag "wave" wave)
+ (const :tag "zigzag" zigzag))
+ :group 'tabbar-ruler)
+
+
+(defcustom tabbar-ruler-fancy-current-tab-separator 'inherit
+ "The current tab can have a different separator."
+ :type '(choice
+ (const :tag "Inherit" inherit)
+ (const :tag "Text" nil)
+ (const :tag "Alternate" alternate)
+ (const :tag "arrow" arrow)
+ (const :tag "arrow-fade" arrow-fade)
+ (const :tag "bar" bar)
+ (const :tag "box" box)
+ (const :tag "brace" brace)
+ (const :tag "butt" butt)
+ (const :tag "chamfer" chamfer)
+ (const :tag "contour" contour)
+ (const :tag "curve" curve)
+ (const :tag "rounded" rounded)
+ (const :tag "roundstub" roundstub)
+ (const :tag "slant" slant)
+ (const :tag "wave" wave)
+ (const :tag "zigzag" zigzag))
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-tab-padding 2
+ "Separate each tab with this padding.
+This is only enabled whin `tabbar-ruler-fancy-tab-separator' is non-nil"
+ :type '(choice
+ (const :tag "No padding" nil)
+ (integer :tag "Padding in pixels"))
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-padding-face nil
+ "Color/Face of padding."
+ :type '(choice
+ (face :tag "Face")
+ (const :tag "Background color" nil)
+ (color :tag "Color"))
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-pad-selected t
+ "Pad selected tab."
+ :type 'boolean
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-tab-height 25
+ "Height for tabbar-ruler's separations."
+ :type '(choice
+ (const :tag "Height of Text" nil)
+ (integer :tag "Overriding Height"))
+ :group 'tabbar-ruler)
+
+
+(defcustom tabbar-ruler-fancy-close-image nil
+ "Use an image for the close."
+ :type 'boolean
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-movement-timer-delay 0.1
+ "Timer delay for `tabbar-ruler-movement-timer'."
+ :type 'number
+ :group 'tabbar-ruler)
+
+(defvar tabbar-close-tab-function nil
+ "Function to call to close a tabbar tab.
+
+Passed a single argument, the tab construct to be closed.")
+
+(defvar tabbar-new-tab-function nil
+ "Function to call to create a new buffer in tabbar-mode.
+
+Optional single argument is the MODE for the new buffer.")
+
+(defvar tabbar-last-tab nil)
+(defvar tabbar-ruler-keep-tabbar nil)
+
+
+(defvar mode-icon-unknown
+ "/* XPM */
+static char * c:\tmp\emacs_xpm[] = {
+\"16 16 103 2\",
+\" c None\",
+\". c #707070\",
+\"+ c #717171\",
+\"@ c #727272\",
+\"# c #6C6C6C\",
+\"$ c #696969\",
+\"% c #6E6E6E\",
+\"& c #7C7C7C\",
+\"* c #858585\",
+\"= c #969696\",
+\"- c #A3A3A3\",
+\"; c #A7A7A7\",
+\"> c #9A9A9A\",
+\", c #747474\",
+\"' c #838383\",
+\") c #A5A5A5\",
+\"! c #ACACAC\",
+\"~ c #A8A8A8\",
+\"{ c #A9A9A9\",
+\"] c #B0B0B0\",
+\"^ c #C5C5C5\",
+\"/ c #F5F5F5\",
+\"( c #D8D8D8\",
+\"_ c #777777\",
+\": c #C6C6C6\",
+\"< c #F7F7F7\",
+\"[ c #F1F1F1\",
+\"} c #F2F2F2\",
+\"| c #ECECEC\",
+\"1 c #E4E4E4\",
+\"2 c #DEDEDE\",
+\"3 c #F4F4F4\",
+\"4 c #FBFBFB\",
+\"5 c #8F8F8F\",
+\"6 c #6B6B6B\",
+\"7 c #AFAFAF\",
+\"8 c #F3F3F3\",
+\"9 c #E8E8E8\",
+\"0 c #C4C4C4\",
+\"a c #CCCCCC\",
+\"b c #D3D3D3\",
+\"c c #B7B7B7\",
+\"d c #737373\",
+\"e c #757575\",
+\"f c #828282\",
+\"g c #909090\",
+\"h c #C3C3C3\",
+\"i c #EEEEEE\",
+\"j c #BDBDBD\",
+\"k c #A1A1A1\",
+\"l c #979797\",
+\"m c #888888\",
+\"n c #8B8B8B\",
+\"o c #959595\",
+\"p c #BCBCBC\",
+\"q c #E6E6E6\",
+\"r c #C7C7C7\",
+\"s c #8A8A8A\",
+\"t c #818181\",
+\"u c #7A7A7A\",
+\"v c #BABABA\",
+\"w c #D1D1D1\",
+\"x c #DBDBDB\",
+\"y c #D7D7D7\",
+\"z c #DCDCDC\",
+\"A c #F0F0F0\",
+\"B c #7E7E7E\",
+\"C c #6F6F6F\",
+\"D c #A2A2A2\",
+\"E c #F6F6F6\",
+\"F c #EBEBEB\",
+\"G c #D0D0D0\",
+\"H c #BEBEBE\",
+\"I c #BFBFBF\",
+\"J c #A6A6A6\",
+\"K c #7D7D7D\",
+\"L c #787878\",
+\"M c #6D6D6D\",
+\"N c #D2D2D2\",
+\"O c #8C8C8C\",
+\"P c #868686\",
+\"Q c #878787\",
+\"R c #848484\",
+\"S c #C2C2C2\",
+\"T c #7F7F7F\",
+\"U c #949494\",
+\"V c #8D8D8D\",
+\"W c #C0C0C0\",
+\"X c #EDEDED\",
+\"Y c #E0E0E0\",
+\"Z c #9C9C9C\",
+\"` c #939393\",
+\" . c #8E8E8E\",
+\".. c #767676\",
+\"+. c #E9E9E9\",
+\"@. c #E5E5E5\",
+\"#. c #D6D6D6\",
+\"$. c #9D9D9D\",
+\"%. c #B8B8B8\",
+\"&. c #D5D5D5\",
+\"*. c #FFFFFF\",
+\"=. c #929292\",
+\"-. c #B1B1B1\",
+\" . + @ . # $ \",
+\" + % . & * = - ; > , \",
+\" + . ' ) ! ~ { ] ^ / ( _ \",
+\" @ @ @ : < [ } | 1 2 3 4 5 6 \",
+\" @ , & 7 8 9 0 0 : a b c _ . \",
+\"d d e f g h i j k k l m _ , @ + \",
+\"d , . _ n o p q r l s t u e d @ \",
+\", . 5 v w x y z A w g B u e , @ \",
+\"C D / E / F G h H I J K L e , d \",
+\"M I E 8 N O ' P Q * t & _ e e d \",
+\"@ R ( 3 S T P g U U V R u e e d \",
+\" + t W X Y j { Z ` .s f .., \",
+\" ..d + Z w +.X @.#.p $.T e , \",
+\" e u s D %.0 &.< *.F P @ \",
+\" _ ' =.k ! -.7 - ... \",
+\" @ + + + . C \"};
+")
+
+(defun tabbar-popup-menu ()
+ "Keymap for pop-up menu. Emacs only."
+ `(,(format "%s" (nth 0 tabbar-last-tab))
+ ["Buffer Indirect Clone" tabbar-popup-clone-indirect-buffer]
+ "--"
+ ["Close" tabbar-popup-close]
+ ["Close all buffers with same extension" tabbar-popup-close-ext]
+ ["Close all BUT this" tabbar-popup-close-but]
+ "--"
+ ["Save" tabbar-popup-save]
+ ["Save As" tabbar-popup-save-as]
+ "--"
+ ["Rename File" tabbar-popup-rename
+ :active (and (buffer-file-name (tabbar-tab-value tabbar-last-tab))
+ (file-exists-p (buffer-file-name (tabbar-tab-value tabbar-last-tab))))]
+ ["Delete File" tabbar-popup-delete
+ :active (and (buffer-file-name (tabbar-tab-value tabbar-last-tab))
+ (file-exists-p (buffer-file-name (tabbar-tab-value tabbar-last-tab))))]
+ "--"
+ ["Copy full path" tabbar-popup-copy-path
+ :active (and (buffer-file-name (tabbar-tab-value tabbar-last-tab))
+ (file-exists-p (buffer-file-name (tabbar-tab-value tabbar-last-tab))))
+ ]
+ ["Copy directory path" tabbar-popup-copy-dir
+ :active (and (buffer-file-name (tabbar-tab-value tabbar-last-tab))
+ (file-exists-p (buffer-file-name (tabbar-tab-value tabbar-last-tab))))
+ ]
+ ["Copy file-name" tabbar-popup-copy-file
+ :active (and (buffer-file-name (tabbar-tab-value tabbar-last-tab))
+ (file-exists-p (buffer-file-name (tabbar-tab-value tabbar-last-tab))))
+ ]
+ ["Copy buffer name" tabbar-popup-buffer-name]
+ "--"
+ ["Gzip File" tabbar-popup-gz
+ :active (and (executable-find "gzip")
+ (buffer-file-name (tabbar-tab-value tabbar-last-tab))
+ (file-exists-p (buffer-file-name (tabbar-tab-value tabbar-last-tab)))
+ (not (string-match "\\.gz\\(?:~\\|\\.~[0-9]+~\\)?\\'" (buffer-file-name (tabbar-tab-value tabbar-last-tab)))))]
+ ["Bzip File" tabbar-popup-bz2
+ :active (and (executable-find "bzip2")
+ (buffer-file-name (tabbar-tab-value tabbar-last-tab))
+ (file-exists-p (buffer-file-name (tabbar-tab-value tabbar-last-tab)))
+ (not (string-match "\\.bz2\\(?:~\\|\\.~[0-9]+~\\)?\\'" (buffer-file-name (tabbar-tab-value tabbar-last-tab)))))]
+ ["Xzip File" tabbar-popup-xz
+ :active (and (executable-find "xz")
+ (buffer-file-name (tabbar-tab-value tabbar-last-tab))
+ (file-exists-p (buffer-file-name (tabbar-tab-value tabbar-last-tab)))
+ (not (string-match "\\.xz\\(?:~\\|\\.~[0-9]+~\\)?\\'" (buffer-file-name (tabbar-tab-value tabbar-last-tab)))))]
+ ["Decompress File" tabbar-popup-decompress
+ :active (and
+ (buffer-file-name (tabbar-tab-value tabbar-last-tab))
+ (file-exists-p (buffer-file-name (tabbar-tab-value tabbar-last-tab)))
+ (string-match "\\(?:\\.\\(?:Z\\|gz\\|bz2\\|tbz2?\\|tgz\\|svgz\\|sifz\\|xz\\|dz\\)\\)\\(\\(?:~\\|\\.~[0-9]+~\\)?\\)\\'"
+ (buffer-file-name (tabbar-tab-value tabbar-last-tab))))
+ ]
+ ;; "--"
+ ;; ["Print" tabbar-popup-print]
+ ))
+
+(defun tabbar-popup-print ()
+ "Print buffer."
+ (interactive))
+
+(defun tabbar-popup-clone-indirect-buffer ()
+ "Tabbar pop up clone indirect-buffer."
+ (interactive)
+ (let ((buffer (tabbar-tab-value tabbar-last-tab)))
+ (with-current-buffer buffer
+ (call-interactively 'clone-indirect-buffer))))
+
+(defun tabbar-popup-close ()
+ "Tabbar pop up close."
+ (interactive)
+ (funcall tabbar-close-tab-function tabbar-last-tab))
+
+(defun tabbar-popup-close-but ()
+ "Tabbar close all BUT this buffer."
+ (interactive)
+ (let ((cur (symbol-value (funcall tabbar-current-tabset-function))))
+ (mapc (lambda(tab)
+ (unless (eq tab tabbar-last-tab)
+ (funcall tabbar-close-tab-function tab)))
+ cur)))
+
+(defun tabbar-popup-close-ext ()
+ "Tabbar close everything with the tabbaset same extension as the current."
+ (interactive)
+ (let ((cur (symbol-value (funcall tabbar-current-tabset-function)))
+ (ext (concat (regexp-quote (file-name-extension (buffer-name (car tabbar-last-tab)) t)) "$")))
+ (mapc (lambda(tab)
+ (when (string-match-p ext (buffer-name (car tab)))
+ (funcall tabbar-close-tab-function tab)))
+ cur)))
+
+(defun tabbar-popup-save-as ()
+ "Tabbar save as."
+ (interactive)
+ (let* ((buf (tabbar-tab-value tabbar-last-tab)))
+ (with-current-buffer buf
+ (call-interactively 'write-file))))
+
+(defun tabbar-popup-rename ()
+ "Tabbar rename."
+ (interactive)
+ (let* ((buf (tabbar-tab-value tabbar-last-tab))
+ (fn (buffer-file-name buf)))
+ (with-current-buffer buf
+ (when (call-interactively 'write-file)
+ (if (string= fn (buffer-file-name (current-buffer)))
+ (error "Buffer has same name. Just saved instead.")
+ (delete-file fn))))))
+
+(defun tabbar-popup-delete ()
+ "Tabbar delete file."
+ (interactive)
+ (let* ((buf (tabbar-tab-value tabbar-last-tab))
+ (fn (buffer-file-name buf)))
+ (when (yes-or-no-p (format "Are you sure you want to delete %s?" buf))
+ (with-current-buffer buf
+ (set-buffer-modified-p nil)
+ (kill-buffer (current-buffer))
+ (delete-file fn)))))
+
+
+(defun tabbar-popup-copy-path ()
+ "Tabbar copy path."
+ (interactive)
+ (let* ((buf (tabbar-tab-value tabbar-last-tab))
+ (fn (buffer-file-name buf)))
+ (kill-new fn)))
+
+
+(defun tabbar-popup-buffer-name ()
+ "Tab-bar copy buffer name"
+ (interactive)
+ (let* ((buf (tabbar-tab-value tabbar-last-tab))
+ (fn (buffer-name buf)))
+ (kill-new fn)))
+
+
+(defun tabbar-popup-copy-file ()
+ "Tabbar copy file name."
+ (interactive)
+ (let* ((buf (tabbar-tab-value tabbar-last-tab))
+ (fn (buffer-file-name buf)))
+ (kill-new (file-name-nondirectory fn))))
+
+
+(defun tabbar-popup-copy-dir ()
+ "Tabbar copy directory."
+ (interactive)
+ (let* ((buf (tabbar-tab-value tabbar-last-tab))
+ (fn (buffer-file-name buf)))
+ (kill-new (file-name-directory fn))))
+
+(defun tabbar-popup-remove-compression-ext (file-name &optional new-compression)
+ "Remove compression extension, and possibly add a new extension.
+
+FILE-NAME is the initial file-name.
+
+NEW-COMPRESSION is the new compression extension. If nil, the compression extesion is removed."
+ (let ((ret file-name))
+ (when (string-match "\\(\\(?:\\.\\(?:Z\\|gz\\|bz2\\|tbz2?\\|tgz\\|svgz\\|sifz\\|xz\\|dz\\)\\)?\\)\\(\\(?:~\\|\\.~[0-9]+~\\)?\\)\\'" ret)
+ (setq ret (replace-match (concat (or new-compression "") (match-string 2 ret)) t t ret)))
+ (symbol-value 'ret)))
+
+(defun tabbar-popup-gz (&optional ext err)
+ "Gzip the file.
+
+EXT is the extension to remove, which defaults to \".gz\".
+
+ERR is a custom error string. Otherwise, the error is assumed to
+be \"Could not gzip the file!\"."
+ (interactive)
+ (let* ((buf (tabbar-tab-value tabbar-last-tab))
+ (fn (buffer-file-name buf))
+ (nfn (tabbar-popup-remove-compression-ext fn (or ext ".gz"))))
+ (if (string= fn nfn)
+ (error "Already has that compression!")
+ (with-current-buffer buf
+ (write-file nfn)
+ (if (not (file-exists-p nfn))
+ (error "%s" (or err "Could not gzip file!"))
+ (when (file-exists-p fn)
+ (delete-file fn)))))))
+
+(defun tabbar-popup-bz2 ()
+ "Bzip file."
+ (interactive)
+ (tabbar-popup-gz ".bz2" "Could not bzip the file!"))
+
+(defun tabbar-popup-xz ()
+ "Xzip file."
+ (interactive)
+ (tabbar-popup-gz ".xz" "Could not xzip the file!"))
+
+(defun tabbar-popup-decompress ()
+ "Decompress file."
+ (interactive)
+ (tabbar-popup-gz "" "Could not decompress the file!"))
+
+(defun tabbar-context-menu ()
+ "Pop up a context menu."
+ (interactive)
+ (popup-menu (tabbar-popup-menu)))
+
+
+(defun tabbar-hex-color (color)
+ "Gets the hexadecimal value of a COLOR."
+ (let ((ret color))
+ (cond
+ ((not (eq (type-of color) 'string))
+ (setq ret "None"))
+ ((string= "#" (substring color 0 1))
+ (setq ret (upcase ret)))
+ ((color-defined-p color)
+ (setq ret (concat "#"
+ (mapconcat
+ (lambda(val)
+ (format "%02X" (* val 255)))
+ (color-name-to-rgb color) ""))))
+ (t (setq ret "None")))
+ (symbol-value 'ret)))
+
+(defcustom tabbar-ruler-swap-faces nil
+ "Swap the selected / unselected tab colors."
+ :type 'boolean
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-invert-deselected t
+ "Invert deselected tabs."
+ :type 'boolean
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-modified-symbol nil
+ "Add modified symbol in addition to changing the face."
+ :type 'boolean
+ :group 'tabbar-ruler)
+
+
+(defcustom tabbar-ruler-style nil
+ "Style of tabbar ruler."
+ :type '(choice
+ (const :tag "Let variables decide" nil)
+ (const :tag "Text-mode tabbar" 'text)
+ (const :tag "Firefox style" 'firefox)
+ (const :tag "Firefox with circle close" 'firefox-circle))
+ :group 'tabbar-ruler)
+
+(defcustom tabbar-ruler-use-variable-pitch t
+ "Use variable pich font.
+
+This copies the :family and :foundry from the `variable-pitch' face."
+ :type 'boolean
+ :group 'tabbar-ruler)
+
+(defun tabbar-diff-face-p (face)
+ "Is FACE customized?"
+ (and (facep face)
+ (or (and (custom-facep face)
+ (or (get face 'saved-value)
+ (get face 'saved-face)
+ (get face 'saved-face-comment)))
+ (ignore-errors (not (eq (default-value face) face))))))
+
+(defun tabbar-ruler-style-firefox (&optional frame)
+ "Setup firefox style for FRAME."
+ (setq tabbar-ruler-tab-padding 1
+ tabbar-ruler-pad-selected nil
+ tabbar-ruler-padding-face (tabbar-foreground 'tabbar-default)
+ tabbar-ruler-fancy-current-tab-separator 'wave
+ tabbar-ruler-fancy-tab-separator 'bar
+ tabbar-ruler-fancy-close-image nil)
+ (dolist (face '(tabbar-button
+ tabbar-separator
+ tabbar-unselected
+ tabbar-unselected-highlight
+ tabbar-unselected-modified))
+ (unless (tabbar-diff-face-p face)
+ (set-face-attribute face frame
+ :background (tabbar-background 'tabbar-default)
+ :foreground (tabbar-foreground 'tabbar-default))))
+ (dolist (face '(tabbar-button
+ tabbar-separator
+ tabbar-selected
+ tabbar-selected-highlight
+ tabbar-selected-modified
+ tabbar-unselected
+ tabbar-unselected-highlight
+ tabbar-unselected-modified))
+ (unless (tabbar-diff-face-p face)
+ (set-face-attribute face frame
+ :height 100))))
+
+(defun tabbar-ruler-style-firefox-circle (&optional frame)
+ "Setup firefox with closed image for FRAME."
+ (tabbar-ruler-style-firefox)
+ (setq tabbar-ruler-fancy-close-image t))
+
+(defun tabbar-ruler-style-text (&optional frame)
+ "Setup text style."
+ (setq tabbar-ruler-tab-padding nil
+ tabbar-ruler-pad-selected nil
+ tabbar-ruler-padding-face nil
+ tabbar-ruler-fancy-current-tab-separator 'inherit
+ tabbar-ruler-fancy-tab-separator nil
+ tabbar-ruler-fancy-close-image nil))
+
+;;;###autoload
+(defun tabbar-install-faces (&optional frame)
+ "Install faces for a FRAME."
+ (interactive)
+ (copy-face 'mode-line 'tabbar-default frame)
+ (if tabbar-ruler-swap-faces
+ (progn
+ (copy-face 'default 'tabbar-selected frame)
+ (copy-face 'shadow 'tabbar-unselected frame)
+ (if tabbar-ruler-invert-deselected
+ (unless (tabbar-diff-face-p 'tabbar-selected)
+ (copy-face 'tabbar-selected 'tabbar-unselected)
+ (set-face-attribute 'tabbar-selected frame)
+ (invert-face 'tabbar-selected))
+ (unless (tabbar-diff-face-p 'tabbar-selected)
+ (set-face-attribute 'tabbar-selected frame
+ :inherit 'mode-line-buffer-id
+ :background (face-attribute 'mode-line-inactive :background))))
+ (unless (tabbar-diff-face-p 'tabbar-unselected-highlight)
+ (copy-face 'mode-line-buffer-id 'tabbar-unselected-highlight frame))
+ (unless (tabbar-diff-face-p 'tabbar-selected-highlight)
+ (copy-face 'mode-line-inactive 'tabbar-selected-highlight frame)))
+ (unless (tabbar-diff-face-p 'tabbar-selected)
+ (copy-face 'default 'tabbar-selected frame))
+ (unless (tabbar-diff-face-p 'tabbar-unselected)
+ (copy-face 'shadow 'tabbar-unselected frame))
+
+ (if tabbar-ruler-invert-deselected
+ (unless (tabbar-diff-face-p 'tabbar-unselected)
+ (copy-face 'tabbar-selected 'tabbar-unselected)
+ (set-face-attribute 'tabbar-unselected frame)
+ (invert-face 'tabbar-unselected))
+ (unless (tabbar-diff-face-p 'tabbar-unselected)
+ (set-face-attribute 'tabbar-unselected frame
+ :inherit 'mode-line-buffer-id
+ :background (face-attribute 'mode-line-inactive :background))))
+
+
+ (unless (tabbar-diff-face-p 'tabbar-selected-highlight)
+ (copy-face 'mode-line-buffer-id 'tabbar-selected-highlight frame))
+ (unless (tabbar-diff-face-p 'tabbar-unselected-highlight)
+ (copy-face 'mode-line-inactive 'tabbar-unselected-highlight frame)))
+
+ (unless (tabbar-diff-face-p 'tabbar-separator)
+ (set-face-attribute 'tabbar-separator frame
+ :inherit 'tabbar-default))
+
+ (unless (tabbar-diff-face-p 'tabbar-button)
+ (set-face-attribute 'tabbar-button frame
+ :inherit 'tabbar-default))
+ (dolist (face '(tabbar-button
+ tabbar-separator
+ tabbar-selected
+ tabbar-selected-highlight
+ tabbar-selected-modified
+ tabbar-unselected
+ tabbar-unselected-highlight
+ tabbar-unselected-modified))
+ (unless (tabbar-diff-face-p face)
+ (set-face-attribute face frame
+ :box nil
+ :height (face-attribute 'default :height frame)
+ :width (face-attribute 'default :width frame)))
+ (when tabbar-ruler-use-variable-pitch
+ (unless (tabbar-diff-face-p face)
+ (set-face-attribute face frame
+ :family (face-attribute 'variable-pitch :family)
+ :foundry (face-attribute 'variable-pitch :foundry)))))
+ (tabbar-ruler-remove-caches)
+ (when tabbar-ruler-style
+ (let ((fun (intern (format "tabbar-ruler-style-%s" tabbar-ruler-style))))
+ (when (fboundp fun)
+ (funcall fun frame)))))
+
+(add-hook 'after-make-frame-functions 'tabbar-install-faces)
+(add-hook 'emacs-startup-hook 'tabbar-install-faces)
+
+;; Taken from powerline
+
+(defun tabbar-create-or-get-tabbar-cache ()
+ "Return a frame-local hash table that acts as a memoization
+cache for tabbar. Create one if the frame doesn't have one
+yet."
+ (or (frame-parameter nil 'tabbar-cache)
+ (let ((table (make-hash-table :test 'equal)))
+ ;; Store it as a frame-local variable
+ (modify-frame-parameters nil `((tabbar-cache . ,table)))
+ table)))
+
+;; from memoize.el @ http://nullprogram.com/blog/2010/07/26/
+(defun tabbar-memoize (func)
+ "Memoize FUNC.
+If argument is a symbol then install the tabbar-memoized function over
+the original function. Use frame-local memoization."
+ (cl-typecase func
+ (symbol (fset func (tabbar-memoize-wrap-frame-local (symbol-function func))) func)
+ (function (tabbar-memoize-wrap-frame-local func))))
+
+(defun tabbar-memoize-wrap-frame-local (func)
+ "Return the tabbar-memoized version of FUNC. The memoization cache is
+frame-local."
+ (let ((cache-sym (cl-gensym))
+ (val-sym (cl-gensym))
+ (args-sym (cl-gensym)))
+ `(lambda (&rest ,args-sym)
+ ,(concat (documentation func) "\n(tabbar-memoized function)")
+ (let* ((,cache-sym (tabbar-create-or-get-tabbar-cache))
+ (,val-sym (gethash ,args-sym ,cache-sym)))
+ (if ,val-sym
+ ,val-sym
+ (puthash ,args-sym (apply ,func ,args-sym) ,cache-sym))))))
+
+(cl-defun tabbar-ruler-image (&key type disabled color face)
+ "Returns the scroll-images"
+ (let ((clr2 (or (and face (facep face) (tabbar-background face))
+ (and disabled (tabbar-hex-color (face-attribute 'mode-line-inactive :background)))
+ (tabbar-hex-color (face-attribute 'mode-line :background))))
+ (clr (or color
+ (and face (facep face) (tabbar-foreground face))
+ (and disabled (tabbar-hex-color (face-attribute 'mode-line-inactive :foreground)))
+ (tabbar-hex-color (face-attribute 'mode-line :foreground)))))
+ (if (eq type 'close)
+ (format "/* XPM */
+ static char * close_tab_xpm[] = {
+ \"14 11 3 1\",
+ \" c None\",
+ \". c %s\",
+ \"+ c %s\",
+ \" ..... \",
+ \" ....... \",
+ \" ......... \",
+ \" ... ... ... \",
+ \" .... . .... \",
+ \" ..... ..... \",
+ \" .... . .... \",
+ \" ... ... ... \",
+ \" ......... \",
+ \" ....... \",
+ \" ..... \"};" clr clr2)
+
+ (format
+ "/* XPM */
+static char * scroll_%s_%s_xpm[] = {
+\"17 17 2 1\",
+\" c None\",
+\". c %s\",
+\" \",
+\" \",
+\" \",
+\" \",
+\" \",
+%s
+\" \",
+\" \",
+\" \",
+\" \",
+\" \",
+\" \"};
+" (symbol-name type)
+(if disabled "disabled" "enabled")
+clr
+(cond
+ ((eq 'right type)
+ "\" \",
+\" .. \",
+\" .... \",
+\" ...... \",
+\" ..... \",
+\" ... \",
+"
+ )
+ ((eq 'left type)
+ "\" \",
+\" .. \",
+\" .... \",
+\" ...... \",
+\" ..... \",
+\" ... \","
+ )
+ ((eq 'up type)
+ "\" . \",
+\" .. \",
+\" ... \",
+\" .... \",
+\" ..... \",
+\" ..... \",")
+ ((eq 'down type)
+ "\" ..... \",
+\" ..... \",
+\" .... \",
+\" ... \",
+\" .. \",
+\" . \","))))))
+
+
+(defconst tabbar-home-button-enabled-image
+ `((:type xpm :data ,(tabbar-ruler-image :type 'down)))
+ "Default image for the enabled home button.")
+
+(defconst tabbar-home-button-disabled-image
+ `((:type xpm :data ,(tabbar-ruler-image :type 'up)))
+ "Default image for the disabled home button")
+
+
+(defconst tabbar-home-button
+ (cons (cons "[o]" tabbar-home-button-enabled-image)
+ (cons "[x]" tabbar-home-button-disabled-image)))
+
+(defvar tabbar-buffer-home-button
+ (cons (cons "[+]" tabbar-home-button-enabled-image)
+ (cons "[-]" tabbar-home-button-disabled-image)))
+
+(defvar tabbar-scroll-left-button-enabled-image
+ `((:type xpm :data ,(tabbar-ruler-image :type 'left))))
+
+(defvar tabbar-scroll-left-button-disabled-image
+ `((:type xpm :data ,(tabbar-ruler-image :type 'left :disabled t))))
+
+(defvar tabbar-scroll-left-button
+ (cons (cons " <" tabbar-scroll-left-button-enabled-image)
+ (cons " =" tabbar-scroll-left-button-disabled-image)))
+
+(defvar tabbar-scroll-right-button-enabled-image
+ `((:type xpm :data ,(tabbar-ruler-image :type 'right))))
+
+(defvar tabbar-scroll-right-button-disabled-image
+ `((:type xpm :data ,(tabbar-ruler-image :type 'right :disabled t))))
+
+(defvar tabbar-scroll-right-button
+ (cons (cons " >" tabbar-scroll-right-button-enabled-image)
+ (cons " =" tabbar-scroll-right-button-disabled-image)))
+
+(defsubst tabbar-normalize-image (image &optional margin face mask)
+ "Make IMAGE centered and transparent.
+If optional MARGIN is non-nil, it must be a number of pixels to add as
+an extra margin around the image. If optional MASK is non-nil, mask
+property is included."
+ (when image
+ (let ((plist (cdr image))
+ (face (or face 'tabbar-default)))
+ (or (plist-get plist :ascent)
+ (setq plist (plist-put plist :ascent 'center)))
+ (or (plist-get plist :mask)
+ (when mask
+ (setq plist (plist-put plist :mask '(heuristic t)))))
+ (or (not (natnump margin))
+ ;; (plist-get plist :margin)
+ (plist-put plist :margin margin))
+ (and (facep face)
+ (plist-put plist :face face))
+ (setcdr image plist)))
+ image)
+
+;; for buffer tabs, use the usual command to close/kill a buffer
+(defun tabbar-buffer-close-tab (tab)
+ (let ((buffer (tabbar-tab-value tab)))
+ (with-current-buffer buffer
+ (kill-buffer buffer))))
+
+(setq tabbar-close-tab-function 'tabbar-buffer-close-tab)
+
+(defsubst tabbar-click-on-tab (tab &optional type action)
+ "Handle a mouse click event on tab TAB.
+Call `tabbar-select-tab-function' with the received, or simulated
+mouse click event, and TAB.
+Optional argument TYPE is a mouse click event type (see the function
+`tabbar-make-mouse-event' for details)."
+ (let* ((mouse-event (tabbar-make-mouse-event type))
+ (mouse-button (event-basic-type mouse-event))
+ tmp map)
+ (cond
+ ((eq mouse-button 'mouse-3)
+ (setq tabbar-last-tab tab)
+ (tabbar-context-menu))
+ ((eq action 'close-tab)
+ (when (and (eq mouse-button 'mouse-1) tabbar-close-tab-function)
+ (funcall tabbar-close-tab-function tab)))
+ ((and (eq action 'icon) (setq tmp (key-binding [menu-bar languages])))
+ (with-current-buffer (tabbar-tab-value tab)
+ (setq map (copy-keymap tmp)
+ tmp (mouse-menu-major-mode-map))
+ (define-key map [major-mode-sep-b] '(menu-item "---"))
+ (define-key map [major-mode] (cons (nth 1 tmp) tmp))
+ ;; (setq tmp (make-composed-map tmp (mouse-menu-major-mode-map)))
+ ;; (popup-menug tmp)
+ (popup-menu map))
+ (tabbar-ruler-modification-state-change)
+ (tabbar-display-update))
+ (t (when tabbar-select-tab-function
+ (funcall tabbar-select-tab-function
+ (tabbar-make-mouse-event type) tab)
+ (tabbar-display-update))))))
+
+(defun tabbar-reset ()
+ "Reset memoized functions."
+ (interactive)
+ (tabbar-memoize 'tabbar-make-tab-keymap)
+ (tabbar-memoize 'tabbar-ruler-image))
+(tabbar-reset)
+
+(defsubst tabbar-drag-p (event)
+ "Return non-nil if EVENT is a mouse drag event."
+ (memq 'drag (event-modifiers event)))
+
+(defun tabbar-select-tab-callback (event)
+ "Handle a mouse EVENT on a tab.
+Pass mouse click events on a tab to `tabbar-click-on-tab'."
+ (interactive "@e")
+ (cond
+ ((tabbar-click-p event)
+ (let ((target (posn-string (event-start event))))
+ (tabbar-click-on-tab
+ (get-text-property (cdr target) 'tabbar-tab (car target))
+ event
+ (get-text-property (cdr target) 'tabbar-action (car target)))))
+ ((tabbar-drag-p event)
+ (let ((start-target (posn-string (event-start event)))
+ (end-target (posn-string (event-end event))))
+ (tabbar-drag-tab
+ (get-text-property (cdr start-target) 'tabbar-tab (car start-target))
+ (get-text-property (cdr end-target) 'tabbar-tab (car end-target))
+ event)))
+ ))
+
+(defun tabbar-drag-tab (dragged-tab dropped-tab event)
+ "Handle DRAGGED-TAB dragged-and-dropped onto DROPPED-TAB.
+ Include full mouse EVENT from drag-and-drop action."
+ (let ((start-tabset (tabbar-tab-tabset dragged-tab)))
+ (when (and (eq start-tabset (tabbar-tab-tabset dropped-tab))
+ (not (eq dragged-tab dropped-tab)))
+ (let* ((tabs (tabbar-tabs start-tabset))
+ (drop-tail-length (length (memq dropped-tab tabs)))
+ (drag-tail-length (length (memq dragged-tab tabs)))
+ (dragdrop-pair (list dragged-tab dropped-tab))
+ new-tablist)
+ (when (> drag-tail-length drop-tail-length)
+ (setq dragdrop-pair (reverse dragdrop-pair)))
+ (dolist (thistab (reverse tabs))
+ ;; build list of tabs. When we hit dragged-tab, don't append it.
+ ;; When we hit dropped-tab, append dragdrop-pair
+ (cond
+ ((eq thistab dragged-tab))
+ ((eq thistab dropped-tab)
+ (setq new-tablist (append dragdrop-pair new-tablist)))
+ (t (add-to-list 'new-tablist thistab))
+ ))
+ (set start-tabset new-tablist)
+ ;; (setq tabbar-window-cache nil) ;; didn't help
+ (tabbar-set-template start-tabset nil)
+ ;; open the dragged tab
+ (funcall tabbar-select-tab-function
+ (tabbar-make-mouse-event event) dragged-tab)
+ (tabbar-display-update)
+ ))))
+
+(defun tabbar-ruler-pad-xpm (width color &optional height)
+ "Generate padding xpm of WIDTH and COLOR with optional HEIGHT."
+ (let* ((height (or height tabbar-ruler-tab-height (pl/separator-height)))
+ (data nil)
+ (i 0))
+ (while (< i height)
+ (setq data (cons
+ (append (make-list width 1))
+ data))
+ (setq i (+ i 1)))
+ (pl/make-xpm "sep" color color data)))
+
+(defun tabbar-background-- (int)
+ "Convert INT to 2 digit hex."
+ (substring (format "%02X" int) -2))
+
+(defun tabbar-background (face &optional foreground)
+ "Gets hex background of FACE.
+When FOREGROUND is non-nil, get the foreground instead."
+ (let ((color (or (and (facep face)
+ (or (and foreground (face-foreground face nil 'default))
+ (face-background face nil 'default)))
+ (and (stringp face) face))))
+ (when (member color (x-defined-colors))
+ (setq color (x-color-values color)
+ color (concat"#"
+ (tabbar-background--(nth 0 color))
+ (tabbar-background--(nth 1 color))
+ (tabbar-background--(nth 2 color)))))
+ color))
+
+(defun tabbar-foreground (face)
+ "Gets hex foreground of FACE."
+ (tabbar-background face t))
+
+
+(defun tabbar-line-right-separator (selected-p face background-face &optional dir
+ normalize-face)
+ "Right separator for tabbar.
+SELECTED-P tells if the item is seleceted."
+ (when tabbar-ruler-fancy-tab-separator
+ (let* ((dir (or dir "right"))
+ (fun
+ (if (and selected-p (not (eq tabbar-ruler-fancy-current-tab-separator 'inherit)))
+ (intern (format "powerline-%s-%s" tabbar-ruler-fancy-current-tab-separator dir))
+ (intern (format "powerline-%s-%s" tabbar-ruler-fancy-tab-separator dir))))
+ (normalize-face (or normalize-face face)))
+ (propertize "|"
+ 'display (tabbar-normalize-image (funcall fun background-face face tabbar-ruler-tab-height) 0 normalize-face)
+ 'face normalize-face))))
+
+(defun tabbar-line-left-separator (selected-p face background-face)
+ "Left separator for tabbar."
+ (or (tabbar-line-right-separator selected-p background-face face "left" face)
+ tabbar-separator-value))
+
+(defvar tabbar-line-mode-icon nil)
+
+(defun tabbar-line-fix-display (text face tab keymap)
+ "Fix display for TEXT given FACE, TAB and KEYMAP."
+ (let* ((compose-p (get-text-property 0 'composition text))
+ (display-p (get-text-property 0 'display text))
+ (image-p (and display-p (eq (car display-p) 'image)))
+ (plist (and image-p (cdr display-p))))
+ (cond
+ (image-p
+ (setq plist (plist-put plist :ascent 'center)
+ plist (plist-put plist :face face))
+ (propertize " "
+ 'display `(image ,@plist)
+ 'face face
+ 'tabbar-tab tab
+ 'local-map keymap
+ 'help-echo 'tabbar-help-on-tab
+ 'pointer 'hand
+ 'tabbar-action 'icon))
+ ((and display-p (stringp display-p)
+ (= 1 (length display-p)))
+ (propertize display-p
+ 'face face
+ 'tabbar-tab tab
+ 'local-map keymap
+ 'help-echo 'tabbar-help-on-tab
+ 'pointer 'hand
+ 'tabbar-action 'icon))
+ ((and compose-p (= 3 (length compose-p))
+ (setq compose-p (nth 2 compose-p))
+ (= 1 (length compose-p))
+ (setq compose-p (make-string 1 (aref compose-p 0))))
+ (propertize compose-p
+ 'face face
+ 'tabbar-tab tab
+ 'local-map keymap
+ 'help-echo 'tabbar-help-on-tab
+ 'pointer 'hand
+ 'tabbar-action 'icon))
+ (t ""))))
+
+(defun tabbar-line-mode-icon (tab face keymap)
+ "Create mode icon for TAB using FACE and KEYMAP"
+ (setq tabbar-line-mode-icon nil)
+ (when (and window-system
+ (or (and (eq t tabbar-ruler-use-mode-icons) (featurep 'mode-icons))
+ (and (eq 'if-enabled tabbar-ruler-use-mode-icons)
+ (boundp 'mode-icons-mode)
+ mode-icons-mode)))
+ (let ((mode-icon (and (fboundp #'mode-icons-get-icon-spec)
+ (with-current-buffer (tabbar-tab-value tab)
+ (mode-icons-get-icon-spec mode-name)))))
+ (setq tabbar-line-mode-icon (propertize " " 'face face
+ 'tabbar-tab tab
+ 'local-map keymap
+ 'help-echo 'tabbar-help-on-tab
+ 'face face
+ 'pointer 'hand
+ 'tabbar-action 'icon))
+ (if mode-icon
+ (tabbar-line-fix-display
+ (mode-icons--recolor-string (with-current-buffer (tabbar-tab-value tab) mode-name)
+ (or (not tabbar-ruler-recolor-inactive-icons)
+ (memq face '(tabbar-selected tabbar-selected-highlight tabbar-selected-modified)))
+ face)
+ face tab keymap)
+ (if tabbar-ruler-mode-icon-for-unknown-modes
+ (propertize " "
+ 'display (create-image mode-icon-unknown 'xpm t
+ :ascent 'center
+ :face face)
+ 'face face
+ 'tabbar-tab tab
+ 'local-map keymap
+ 'help-echo 'tabbar-help-on-tab
+ 'pointer 'hand
+ 'tabbar-action 'icon)
+ (setq tabbar-line-mode-icon nil))))))
+
+(defun tabbar-line-padding (selected-p next-selected-p background-face)
+ (when (and tabbar-ruler-fancy-tab-separator tabbar-ruler-tab-padding
+ (or (not selected-p) (and selected-p tabbar-ruler-pad-selected))
+ (or (not next-selected-p) (and next-selected-p tabbar-ruler-pad-selected)))
+ (propertize " " 'display (tabbar-normalize-image
+ (tabbar-ruler-pad-xpm
+ tabbar-ruler-tab-padding
+ (tabbar-background (or tabbar-ruler-padding-face background-face))) 0 background-face)
+ 'face background-face)))
+
+(defsubst tabbar-line-tab (tab &optional not-last sel)
+ "Return the display representation of tab TAB.
+That is, a propertized string used as an `header-line-format' template
+element.
+Call `tabbar-tab-label-function' to obtain a label for TAB."
+ (let* ((selected-p (tabbar-selected-p tab (tabbar-current-tabset)))
+ (next-selected-p (and not-last (tabbar-selected-p (car not-last) (tabbar-current-tabset))))
+ (modified-p (buffer-modified-p (tabbar-tab-value tab)))
+ (keymap (tabbar-make-tab-keymap tab))
+ (left-fun
+ (if (and selected-p (not (eq tabbar-ruler-fancy-current-tab-separator 'inherit)))
+ (intern (format "powerline-%s-left" tabbar-ruler-fancy-current-tab-separator))
+ (intern (format "powerline-%s-left" tabbar-ruler-fancy-tab-separator))))
+ (face (if selected-p
+ (if modified-p
+ 'tabbar-selected-modified
+ 'tabbar-selected)
+ (if modified-p
+ 'tabbar-unselected-modified
+ 'tabbar-unselected)))
+ (close-button-image (tabbar-find-image
+ `((:type xpm :data ,(tabbar-ruler-image :type 'close :disabled (not modified-p)
+ :face face)))))
+ (background-face 'tabbar-default)
+ (next-background-face 'tabbar-default)
+ (mode-icon (and (featurep 'mode-icons)
+ (with-current-buffer (tabbar-tab-value tab)
+ (assoc mode-name mode-icons))))
+ (pad-face (or tabbar-ruler-padding-face background-face)))
+ (setq close-button-image (tabbar-normalize-image close-button-image 0 face))
+ (concat
+ (tabbar-line-right-separator selected-p face background-face)
+ (propertize " " 'face face
+ 'tabbar-tab tab
+ 'local-map keymap
+ 'help-echo 'tabbar-help-on-tab
+ 'face face
+ 'pointer 'hand)
+
+ (tabbar-line-mode-icon tab face keymap)
+ tabbar-line-mode-icon
+ (propertize
+ (if tabbar-tab-label-function
+ (funcall tabbar-tab-label-function tab)
+ tab)
+ 'tabbar-tab tab
+ 'local-map keymap
+ 'help-echo 'tabbar-help-on-tab
+ 'mouse-face 'tabbar-highlight
+ 'face face
+ 'pointer 'hand)
+ (propertize (if (and modified-p tabbar-ruler-modified-symbol)
+ (with-temp-buffer
+ (insert (make-string 1 #x207A))
+ (insert " ")
+ (buffer-substring (point-min) (point-max))) " ")
+ 'face face
+ 'tabbar-tab tab
+ 'local-map keymap
+ 'help-echo 'tabbar-help-on-tab
+ 'face face
+ 'pointer 'hand)
+ (if tabbar-ruler-fancy-close-image
+ (propertize (with-temp-buffer
+ (insert (make-string 1 #x00D7))
+ (buffer-string))
+ 'display close-button-image
+ 'face face
+ 'pointer 'hand
+ 'tabbar-tab tab
+ 'local-map keymap
+ 'tabbar-action 'close-tab)
+ (propertize
+ (with-temp-buffer
+ (insert (make-string 1 #x00D7))
+ (insert " ")
+ (buffer-string))
+ 'face face
+ 'pointer 'hand
+ 'tabbar-tab tab
+ 'local-map keymap
+ 'tabbar-action 'close-tab))
+ (tabbar-line-left-separator selected-p face background-face)
+ (tabbar-line-padding selected-p next-selected-p 'tabbar-default)
+ )))
+
+(defsubst tabbar-line-format (tabset)
+ "Return the `header-line-format' value to display TABSET."
+ (let* ((sel (tabbar-selected-tab tabset))
+ (tabs (tabbar-view tabset))
+ (padcolor (tabbar-background-color))
+ atsel elts)
+ ;; Initialize buttons and separator values.
+ (or tabbar-separator-value
+ (tabbar-line-separator))
+ (or tabbar-home-button-value
+ (tabbar-line-button 'home))
+ (or tabbar-scroll-left-button-value
+ (tabbar-line-button 'scroll-left))
+ (or tabbar-scroll-right-button-value
+ (tabbar-line-button 'scroll-right))
+ ;; Track the selected tab to ensure it is always visible.
+ (when tabbar--track-selected
+ (while (not (memq sel tabs))
+ (tabbar-scroll tabset -1)
+ (setq tabs (tabbar-view tabset)))
+ (while (and tabs (not atsel))
+ (setq elts (cons (tabbar-line-tab (car tabs) (cdr tabs)) elts)
+ atsel (eq (car tabs) sel)
+ tabs (cdr tabs)))
+ (setq elts (nreverse elts))
+ ;; At this point the selected tab is the last elt in ELTS.
+ ;; Scroll TABSET and ELTS until the selected tab becomes
+ ;; visible.
+ (with-temp-buffer
+ (let ((truncate-partial-width-windows nil)
+ (inhibit-modification-hooks t)
+ deactivate-mark ;; Prevent deactivation of the mark!
+ start)
+ (setq truncate-lines nil
+ buffer-undo-list t)
+ (apply 'insert (tabbar-line-buttons tabset))
+ (setq start (point))
+ (while (and (cdr elts) ;; Always show the selected tab!
+ (progn
+ (delete-region start (point-max))
+ (goto-char (point-max))
+ (apply 'insert elts)
+ (goto-char (point-min))
+ (> (vertical-motion 1) 0)))
+ (tabbar-scroll tabset 1)
+ (setq elts (cdr elts)))))
+ (setq elts (nreverse elts))
+ (setq tabbar--track-selected nil))
+ ;; Format remaining tabs.
+ (while tabs
+ (setq elts (cons (tabbar-line-tab (car tabs) (cdr tabs)) elts)
+ tabs (cdr tabs)))
+ ;; Cache and return the new tab bar.
+ (setq elts (nreverse elts))
+ (tabbar-set-template
+ tabset
+ (list (tabbar-line-buttons tabset)
+ (cond
+ (tabbar-ruler-fancy-tab-separator
+ (propertize " " 'display (funcall (intern (format "powerline-%s-right" tabbar-ruler-fancy-tab-separator))
+ nil (get-text-property 0 'face (car elts)) tabbar-ruler-tab-height)))
+ (t ""))
+ elts
+ (propertize "%-"
+ 'face (list :background padcolor
+ :foreground padcolor)
+ 'pointer 'arrow)))))
+
+(defface tabbar-selected-modified
+ '((t
+ :inherit tabbar-selected
+ :foreground "DarkOrange3"
+ :weight bold))
+ "Face used for selected tabs."
+ :group 'tabbar)
+
+(defface tabbar-unselected-modified
+ '((t
+ :inherit tabbar-unselected
+ :foreground "DarkOrange3"
+ :weight bold))
+ "Face used for unselected tabs."
+ :group 'tabbar)
+
+(defface tabbar-key-binding '((t
+ :foreground "white"))
+ "Face for unselected, highlighted tabs."
+ :group 'tabbar)
+
+;; Hooks based on yswzing's hooks, but modified for this function state.
+;; called each time the modification state of the buffer changed
+(defun tabbar-ruler-modification-state-change ()
+ (tabbar-set-template tabbar-current-tabset nil)
+ (tabbar-display-update))
+
+;; first-change-hook is called BEFORE the change is made
+(defun tabbar-ruler-on-buffer-modification ()
+ (set-buffer-modified-p t)
+ (tabbar-ruler-modification-state-change))
+(add-hook 'after-save-hook 'tabbar-ruler-modification-state-change)
+
+(defvar tabbar-ruler-tabbar-off 't)
+(defvar tabbar-ruler-ruler-off 't)
+(set (make-variable-buffer-local 'tabbar-ruler-toolbar-off) nil)
+(set (make-variable-buffer-local 'tabbar-ruler-ruler-off) nil)
+
+(defvar tabbar-ruler-toolbar-off nil)
+(defvar tabbar-ruler-menu-off nil)
+(add-hook 'find-file-hook
+ (lambda()
+ (interactive)
+ (tabbar-ruler-tabbar-ruler-fight 't)))
+
+(defcustom tabbar-ruler-ruler-display-commands
+ '(ac-trigger-commands
+ esn-upcase-char-self-insert
+ esn-magic-$
+ right-char
+ left-char
+ previous-line
+ next-line
+ backward-paragraph
+ forward-paragraph
+ cua-scroll-down
+ cua-scroll-up
+ cua-paste
+ cua-paste-pop
+ scroll-up
+ scroll-down
+ autopair-newline
+ autopair-insert-opening
+ autopair-skip-close-maybe
+ autopair-backspace
+ backward-delete-char-untabify
+ delete-backward-char
+ self-insert-command)
+ "Ruler display commands."
+ :group 'tabbar-ruler
+ :type '(repeat symbol))
+
+(defun tabbar-ruler-tabbar-ruler-fight (&optional initialize)
+ "Defines the fighting behavior of the tabbar-ruler ruler and tabbar."
+ (condition-case error
+ (progn
+ (cond
+ ((minibufferp)
+ nil)
+ (tabbar-ruler-keep-tabbar
+ (setq tabbar-ruler-keep-tabbar nil)
+ nil)
+ ((and (save-match-data (string-match "^[*]Org Src " (buffer-name))))
+ nil)
+ ((member major-mode tabbar-ruler-fight-igore-modes)
+ nil)
+ ( (eq major-mode 'helm-mode)
+ nil)
+ ( (eq last-command 'mouse-drag-region)
+ (tabbar-ruler-mouse-movement))
+ ( (and tabbar-ruler-global-ruler tabbar-ruler-global-tabbar)
+ (cond
+ ( (memq last-command tabbar-ruler-ruler-display-commands)
+ (when tabbar-ruler-popup-scrollbar
+ (scroll-bar-mode -1))
+ (when tabbar-ruler-ruler-off
+ (ruler-mode 1)
+ (setq tabbar-ruler-ruler-off nil))
+ (unless tabbar-ruler-tabbar-off
+ (tabbar-mode -1)
+ (setq tabbar-ruler-tabbar-off 't))
+ (when tabbar-ruler-popup-menu
+ (unless tabbar-ruler-menu-off
+ (unless (eq system-type 'darwin)
+ (menu-bar-mode -1))
+ (setq tabbar-ruler-menu-off 't)))
+ (when tabbar-ruler-popup-toolbar
+ (unless (eq system-type 'darwin)
+ (unless tabbar-ruler-toolbar-off
+ (tool-bar-mode -1)
+ (setq tabbar-ruler-toolbar-off 't)))))
+ ( (save-match-data (string-match "\\(mouse\\|ignore\\|window\\|frame\\)" (format "%s" last-command)))
+ (when nil ;; Took this out; Afterward it works much better...
+ (unless tabbar-ruler-ruler-off
+ (ruler-mode -1)
+ (setq tabbar-ruler-ruler-off 't))
+ (when tabbar-ruler-tabbar-off
+ (tabbar-mode 1)
+ (setq tabbar-ruler-tabbar-off nil))))
+ ( 't
+ (when (or initialize (and tabbar-ruler-ruler-off tabbar-ruler-tabbar-off))
+ (when tabbar-ruler-popup-scrollbar
+ (scroll-bar-mode -1))
+ (when tabbar-ruler-ruler-off
+ (ruler-mode 1)
+ (setq tabbar-ruler-ruler-off nil))
+ (unless tabbar-ruler-tabbar-off
+ (tabbar-mode -1)
+ (setq tabbar-ruler-tabbar-off 't))))))
+ ( tabbar-ruler-global-ruler
+ (when tabbar-ruler-ruler-off
+ (ruler-mode 1)
+ (setq tabbar-ruler-ruler-off nil)))
+ ( tabbar-ruler-global-tabbar
+ (when tabbar-ruler-tabbar-off
+ (tabbar-mode 1)
+ (setq tabbar-ruler-tabbar-off nil)))))
+ (error
+ (message "Error in post-command-hook for Ruler/Tabbar: %s" (error-message-string error)))))
+
+(add-hook 'post-command-hook 'tabbar-ruler-tabbar-ruler-fight)
+(defvar tabbar-ruler-movement-timer nil)
+(defvar tabbar-ruler-movement-x nil)
+(defvar tabbar-ruler-movement-y nil)
+
+(defun tabbar-ruler-mouse-movement ()
+ "Mouse Movement function"
+ (interactive)
+ (when tabbar-ruler-movement-timer
+ (cancel-timer tabbar-ruler-movement-timer))
+ (let* ((y-pos (cddr (mouse-pixel-position)))
+ (x-pos (cadr (mouse-pixel-position))))
+ (unless y-pos
+ (setq y-pos tabbar-ruler-movement-y))
+ (unless x-pos
+ (setq x-pos tabbar-ruler-movement-x))
+ (when (or (not tabbar-ruler-movement-x) (not tabbar-ruler-movement-y)
+ (and tabbar-ruler-movement-x tabbar-ruler-movement-y
+ (not
+ (and
+ (= tabbar-ruler-movement-x x-pos)
+ (= tabbar-ruler-movement-y y-pos)))))
+ (when (and x-pos y-pos)
+ (when tabbar-ruler-popup-scrollbar
+ (scroll-bar-mode 1))
+ (setq tabbar-ruler-movement-x x-pos)
+ (setq tabbar-ruler-movement-y y-pos)
+ (unless tabbar-ruler-ruler-off
+ (ruler-mode -1)
+ (setq tabbar-ruler-ruler-off 't))
+ (when tabbar-ruler-tabbar-off
+ (tabbar-mode 1)
+ (setq tabbar-ruler-tabbar-off nil))
+ (if (>= (if (or tabbar-ruler-menu-off tabbar-ruler-toolbar-off)
+ tabbar-ruler-popup-menu-min-y
+ tabbar-ruler-popup-menu-min-y-leave) y-pos)
+ (progn
+ (when tabbar-ruler-popup-menu
+ (when tabbar-ruler-menu-off
+ (unless (eq system-type 'darwin)
+ (menu-bar-mode 1))
+ (setq tabbar-ruler-menu-off nil)))
+ (when tabbar-ruler-popup-toolbar
+ (unless (eq system-type 'darwin)
+ (when tabbar-ruler-toolbar-off
+ (tool-bar-mode 1)
+ (setq tabbar-ruler-toolbar-off nil)))))
+ (when tabbar-ruler-popup-menu
+ (unless tabbar-ruler-menu-off
+ (unless (eq system-type 'darwin)
+ (menu-bar-mode -1))
+ (setq tabbar-ruler-menu-off 't)))
+ (when tabbar-ruler-popup-toolbar
+ (unless (eq system-type 'darwin)
+ (unless tabbar-ruler-toolbar-off
+ (tool-bar-mode -1)
+ (setq tabbar-ruler-toolbar-off 't)))))))
+ (setq tabbar-ruler-movement-timer (run-with-idle-timer
+ (time-add
+ (if
+ (current-idle-time)
+ (current-idle-time)
+ (seconds-to-time 0))
+ (seconds-to-time
+ tabbar-ruler-movement-timer-delay))
+ nil
+ 'tabbar-ruler-mouse-movement))))
+(tabbar-ruler-mouse-movement)
+
+(defun tabbar-ruler-movement-timer-reset ()
+ "Mouse movement timer reset"
+ (interactive)
+ (when tabbar-ruler-movement-timer
+ (cancel-timer tabbar-ruler-movement-timer))
+ (setq tabbar-ruler-movement-timer (run-with-idle-timer
+ (seconds-to-time
+ tabbar-ruler-movement-timer-delay)
+ nil
+ 'tabbar-ruler-mouse-movement)))
+
+(add-hook 'post-command-hook 'tabbar-ruler-movement-timer-reset)
+
+(defvar tabbar-buffer-groups-function 'tabbar-buffer-groups)
+
+(defun last-tabbar-ruler-tabbar-buffer-groups nil)
+
+(defun tabbar-ruler-tabbar-buffer-groups ()
+ "Return the list of group names the current buffer belongs to.
+Return a list of one element based on major mode."
+ (setq last-tabbar-ruler-tabbar-buffer-groups
+ (list
+ (cond
+ ;; ((or (get-buffer-process (current-buffer))
+ ;; ;; Check if the major mode derives from `comint-mode' or
+ ;; ;; `compilation-mode'.
+ ;; (tabbar-buffer-mode-derived-p
+ ;; major-mode '(comint-mode compilation-mode)))
+ ;; "Process")
+ ;; ((string-match "^ *[*]" (buffer-name))
+ ;; "Common"
+ ;; )
+ ((eq major-mode 'dired-mode)
+ "Dired")
+ ((memq major-mode
+ '(help-mode apropos-mode Info-mode Man-mode))
+ "Help")
+ ((memq major-mode
+ '(rmail-mode
+ rmail-edit-mode vm-summary-mode vm-mode mail-mode
+ mh-letter-mode mh-show-mode mh-folder-mode
+ gnus-summary-mode message-mode gnus-group-mode
+ gnus-article-mode score-mode gnus-browse-killed-mode))
+ "Mail")
+ (t
+ "Files"
+ ))))
+ (symbol-value 'last-tabbar-ruler-tabbar-buffer-groups))
+
+
+(defun tabbar-ruler-tabbar-buffer-list ()
+ "Return the list of buffers to show in tabs.
+Exclude buffers whose name starts with a space or *, when they are not
+visiting a file. The current buffer is always included."
+ (delq nil
+ (mapcar #'(lambda (b)
+ (cond
+ ;; Always include the current buffer.
+ ((eq (current-buffer) b) b)
+ ((buffer-file-name b) b)
+ ((member (buffer-name b) tabbar-ruler-excluded-buffers) nil)
+ ;; ((string= "*Messages*" (format "%s" (buffer-name b))))
+ ((char-equal ?\ (aref (buffer-name b) 0)) nil)
+ ;;((char-equal ?* (aref (buffer-name b) 0)) nil)
+ ((buffer-live-p b) b)))
+ (buffer-list))))
+
+(setq tabbar-buffer-list-function #'tabbar-ruler-tabbar-buffer-list)
+
+(defvar tabbar-ruler-projectile-tabbar-buffer-group-calc nil
+ "Buffer group for projectile. Should be buffer local and speed up calculation of buffer groups.")
+(defun tabbar-ruler-projectile-tabbar-buffer-groups ()
+ "Return the list of group names BUFFER belongs to.
+ Return only one group for each buffer."
+
+ (if tabbar-ruler-projectile-tabbar-buffer-group-calc
+ (symbol-value 'tabbar-ruler-projectile-tabbar-buffer-group-calc)
+ (set (make-local-variable 'tabbar-ruler-projectile-tabbar-buffer-group-calc)
+
+ (cond
+ ((or (get-buffer-process (current-buffer)) (memq major-mode '(comint-mode compilation-mode))) '("Term"))
+ ((string-equal "*" (substring (buffer-name) 0 1)) '("Misc"))
+ ((condition-case err
+ (projectile-project-root)
+ (error nil)) (list (projectile-project-name)))
+ ((memq major-mode '(emacs-lisp-mode python-mode emacs-lisp-mode c-mode c++-mode makefile-mode lua-mode vala-mode)) '("Coding"))
+ ((memq major-mode '(javascript-mode js-mode nxhtml-mode html-mode css-mode)) '("HTML"))
+ ((memq major-mode '(org-mode calendar-mode diary-mode)) '("Org"))
+ ((memq major-mode '(dired-mode)) '("Dir"))
+ (t '("Main"))))
+ (symbol-value 'tabbar-ruler-projectile-tabbar-buffer-group-calc)))
+
+(defun tabbar-ruler-group-by-projectile-project()
+ "Group by projectile project."
+ (interactive)
+ (setq tabbar-buffer-groups-function 'tabbar-ruler-projectile-tabbar-buffer-groups))
+
+(defun tabbar-ruler-group-user-buffers-helper ()
+ ;; customize tabbar to have only 2 groups: emacs's and user's buffers
+ ;; all normal files will be shown in group user's buffers
+ (list (cond ((string-equal "*" (substring (buffer-name) 0 1)) "emacs's buffers")
+ ((eq major-mode 'dired-mode) "emacs's buffers")
+ (t "user's buffers"))))
+
+(defun tabbar-ruler-group-user-buffers ()
+ (interactive)
+ (setq tabbar-buffer-groups-function 'tabbar-ruler-group-user-buffers-helper))
+
+(defun tabbar-ruler-buffer-groups ()
+ "Return the list of group names the current buffer belongs to.
+Return a list of one element based on major mode."
+ (list
+ (cond
+ ((or (get-buffer-process (current-buffer))
+ ;; Check if the major mode derives from `comint-mode' or
+ ;; `compilation-mode'.
+ (tabbar-buffer-mode-derived-p
+ major-mode '(comint-mode compilation-mode)))
+ "Process")
+ ((member (buffer-name)
+ '("*scratch*" "*Messages*"))
+ "Common"
+ )
+ ((eq major-mode 'dired-mode)
+ "Dired"
+ )
+ ((memq major-mode
+ '(help-mode apropos-mode Info-mode Man-mode))
+ "Help")
+ ((memq major-mode
+ '(rmail-mode
+ rmail-edit-mode vm-summary-mode vm-mode mail-mode
+ mh-letter-mode mh-show-mode mh-folder-mode
+ gnus-summary-mode message-mode gnus-group-mode
+ gnus-article-mode score-mode gnus-browse-killed-mode))
+ "Mail")
+ (t
+ ;; Return `mode-name' if not blank, `major-mode' otherwise.
+ (if (and (stringp mode-name)
+ ;; Take care of preserving the match-data because this
+ ;; function is called when updating the header line.
+ (save-match-data (string-match "[^ ]" mode-name)))
+ (let ((txt (format "%s" mode-name)))
+ ;; Take out mode-icons and show text
+ (set-text-properties 0 (length txt) nil txt)
+ txt)
+ (symbol-name major-mode))))))
+
+(defun tabbar-ruler-group-buffer-groups ()
+ "Use tabbar's major-mode grouping of buffers."
+ (interactive)
+ (setq tabbar-buffer-groups-function 'tabbar-ruler-buffer-groups))
+
+;; default group mode
+(tabbar-ruler-group-user-buffers)
+
+;;; Adapted from auto-hide in EmacsWiki
+
+(defvar tabbar-display-functions
+ '(tabbar-press-home
+ tabbar-backward
+ tabbar-forward
+ tabbar-backward-tab
+ tabbar-forward-tab
+ tabbar-backward-group
+ tabbar-forward-group
+ tabbar-press-scroll-left
+ tabbar-press-scroll-right)
+ "Tabbar movement functions")
+
+(mapc
+ (lambda(x)
+ (eval `(defun ,(intern (concat "tabbar-ruler-" (symbol-name x))) (&optional arg)
+ ,(concat "Turn on tabbar before running `" (symbol-name x) "'")
+ (interactive "p")
+ (setq tabbar-ruler-keep-tabbar t)
+ (unless tabbar-ruler-ruler-off
+ (ruler-mode -1)
+ (setq tabbar-ruler-ruler-off 't))
+ (when tabbar-ruler-tabbar-off
+ (tabbar-mode 1)
+ (setq tabbar-ruler-tabbar-off nil))
+ (setq current-prefix-arg current-prefix-arg)
+ (call-interactively ',x)
+ (setq tabbar-ruler-keep-tabbar t)
+ (unless tabbar-ruler-ruler-off
+ (ruler-mode -1)
+ (setq tabbar-ruler-ruler-off 't))
+ (when tabbar-ruler-tabbar-off
+ (tabbar-mode 1)
+ (setq tabbar-ruler-tabbar-off nil)))))
+ tabbar-display-functions)
+
+;;;###autoload
+(defun tabbar-ruler-up (&optional arg)
+ "Tabbar press up key."
+ (interactive "p")
+ (setq current-prefix-arg current-prefix-arg)
+ (call-interactively 'tabbar-ruler-tabbar-press-home))
+
+;;;###autoload
+(defun tabbar-ruler-forward (&optional arg)
+ "Forward ruler. Takes into consideration if the home-key was pressed.
+This is based on the variable `tabbar--buffer-show-groups'"
+ (interactive "p")
+ (cond
+ (tabbar--buffer-show-groups
+ (setq current-prefix-arg current-prefix-arg)
+ (call-interactively 'tabbar-ruler-tabbar-forward-group)
+ (tabbar-ruler-tabbar-press-home))
+ (t
+ (setq current-prefix-arg current-prefix-arg)
+ (call-interactively 'tabbar-ruler-tabbar-forward-tab))))
+
+;;;###autoload
+(defun tabbar-ruler-backward (&optional arg)
+ "Backward ruler. Takes into consideration if the home-key was pressed."
+ (interactive "p")
+ (cond
+ (tabbar--buffer-show-groups
+ (setq current-prefix-arg current-prefix-arg)
+ (call-interactively 'tabbar-ruler-tabbar-backward-group)
+ (tabbar-ruler-tabbar-press-home))
+ (t
+ (setq current-prefix-arg current-prefix-arg)
+ (call-interactively 'tabbar-ruler-tabbar-backward-tab))))
+
+(when (not (fboundp 'set-temporary-overlay-map))
+ ;; Backport this function from newer emacs versions
+ (defun set-temporary-overlay-map (map &optional keep-pred)
+ "Set a new keymap that will only exist for a short period of time.
+The new keymap to use must be given in the MAP variable. When to
+remove the keymap depends on user input and KEEP-PRED:
+
+- if KEEP-PRED is nil (the default), the keymap disappears as
+ soon as any key is pressed, whether or not the key is in MAP;
+
+- if KEEP-PRED is t, the keymap disappears as soon as a key *not*
+ i in MAP is pressed;
+
+- otherwise, KEEP-PRED must be a 0-arguments predicate that will
+ decide if the keymap should be removed (if predicate returns
+ nil) or kept (otherwise). The predicate will be called after
+ each key sequence."
+
+ (let* ((clearfunsym (make-symbol "clear-temporary-overlay-map"))
+ (overlaysym (make-symbol "t"))
+ (alist (list (cons overlaysym map)))
+ (clearfun
+ `(lambda ()
+ (unless ,(cond ((null keep-pred) nil)
+ ((eq t keep-pred)
+ `(eq this-command
+ (lookup-key ',map
+ (this-command-keys-vector))))
+ (t `(funcall ',keep-pred)))
+ (remove-hook 'pre-command-hook ',clearfunsym)
+ (setq emulation-mode-map-alists
+ (delq ',alist emulation-mode-map-alists))))))
+ (set overlaysym overlaysym)
+ (fset clearfunsym clearfun)
+ (add-hook 'pre-command-hook clearfunsym)
+
+ (push alist emulation-mode-map-alists))))
+
+(defvar tabbar-ruler-move-keymap (make-sparse-keymap)
+ "Keymap for tabbar-ruler movement")
+
+(define-key tabbar-ruler-move-keymap [remap previous-line] 'tabbar-ruler-up)
+(define-key tabbar-ruler-move-keymap [remap next-line] 'tabbar-ruler-up)
+(define-key tabbar-ruler-move-keymap [remap backward-char] 'tabbar-ruler-backward)
+(define-key tabbar-ruler-move-keymap [remap forward-char] 'tabbar-ruler-forward)
+(define-key tabbar-ruler-move-keymap [remap left-char] 'tabbar-ruler-backward)
+(define-key tabbar-ruler-move-keymap [remap right-char] 'tabbar-ruler-forward)
+(define-key tabbar-ruler-move-keymap (kbd "SPC") (lambda() (interactive) (message "Exited tabbar-movement")))
+(define-key tabbar-ruler-move-keymap (kbd "<return>") (lambda() (interactive) (message "Exited tabbar-movement")))
+
+(defun tabbar-ruler-move-pred ()
+ "Determines if emacs should keep the temporary keymap
+ `tabbar-ruler-move-keymap' when running `tabbar-ruler-move'."
+ (memq this-command '(tabbar-ruler-up tabbar-ruler-backward tabbar-ruler-forward)))
+
+;;;###autoload
+(defun tabbar-ruler-move ()
+ "Start the movement for the tabbar"
+ (interactive)
+ (setq tabbar-ruler-keep-tabbar t)
+ (unless tabbar-ruler-ruler-off
+ (ruler-mode -1)
+ (setq tabbar-ruler-ruler-off 't))
+ (when tabbar-ruler-tabbar-off
+ (tabbar-mode 1)
+ (setq tabbar-ruler-tabbar-off nil))
+ (message "Use arrow keys to change buffers (or line movement commands). Exit with space/return or any other key.")
+ (set-temporary-overlay-map tabbar-ruler-move-keymap 'tabbar-ruler-move-pred))
+
+;; Hook save and change events to show modified buffers in tabbar
+(defun on-saving-buffer ()
+ (tabbar-set-template tabbar-current-tabset nil)
+ (tabbar-display-update))
+(defun on-modifying-buffer ()
+ (set-buffer-modified-p (buffer-modified-p))
+ (tabbar-set-template tabbar-current-tabset nil)
+ (tabbar-display-update))
+(defun after-modifying-buffer (begin end length)
+ (set-buffer-modified-p (buffer-modified-p))
+ (tabbar-set-template tabbar-current-tabset nil)
+ (tabbar-display-update))
+(add-hook 'after-save-hook 'on-saving-buffer)
+(add-hook 'first-change-hook 'on-modifying-buffer)
+(add-hook 'after-change-functions 'after-modifying-buffer)
+
+(defun tabbar-ruler-remove-caches ()
+ "Remove caches for tabbar-ruler."
+ ;; Courtesy of Ba Manzi
+ ;; https://bitbucket.org/bamanzi/dotemacs-elite/issue/24/tabbar-ruler-not-work-in-emacs-244-keep
+ (mapc #'(lambda (frame)
+ (modify-frame-parameters frame '((tabbar-cache . nil))))
+ (frame-list)))
+
+(add-hook 'desktop-after-read-hook 'tabbar-ruler-remove-caches)
+
+;; (defadvice enable-theme (after tabbar-ruler-enable-theme-after activate)
+;; "Fix the tabbar faces when you change themes."
+;; (tabbar-install-faces))
+
+;; (defadvice disable-theme (after tabbar-ruler-disable-theme-after activate)
+;; "Fix the tabbar faces when you change themes."
+;; (tabbar-install-faces))
+
+
+(defmacro tabbar-ruler-save-buffer-state (&rest body)
+ "Eval BODY,
+then restore the buffer state under the assumption that no significant
+modification has been made in BODY. A change is considered
+significant if it affects the buffer text in any way that isn't
+completely restored again. Changes in text properties like `face' or
+`syntax-table' are considered insignificant. This macro allows text
+properties to be changed, even in a read-only buffer.
+
+This macro should be placed around all calculations which set
+\"insignificant\" text properties in a buffer, even when the buffer is
+known to be writeable. That way, these text properties remain set
+even if the user undoes the command which set them.
+
+This macro should ALWAYS be placed around \"temporary\" internal buffer
+changes \(like adding a newline to calculate a text-property then
+deleting it again\), so that the user never sees them on his
+`buffer-undo-list'.
+
+However, any user-visible changes to the buffer \(like auto-newlines\)
+must not be within a `ergoemacs-save-buffer-state', since the user then
+wouldn't be able to undo them.
+
+The return value is the value of the last form in BODY.
+
+This was stole/modified from `c-save-buffer-state'"
+ `(let* ((modified (buffer-modified-p)) (buffer-undo-list t)
+ (inhibit-read-only t) (inhibit-point-motion-hooks t)
+ before-change-functions after-change-functions
+ deactivate-mark
+ buffer-file-name buffer-file-truename ; Prevent primitives checking
+ ; for file modification
+ )
+ (unwind-protect
+ (progn ,@body)
+ (and (not modified)
+ (buffer-modified-p)
+ (set-buffer-modified-p nil)))))
+
+(defadvice tabbar-display-update (around tabbar-ruler-fix-select-word activate)
+ "Fix the tabbar selection of a word with the mouse."
+ (tabbar-ruler-save-buffer-state
+ ad-do-it))
+
+
+(tabbar-install-faces)
+(provide 'tabbar-ruler)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; tabbar-ruler.el ends here
Copyright 2019--2024 Marius PETER