diff options
Diffstat (limited to 'elpa/mode-icons-20190627.2121/mode-icons.el')
-rw-r--r-- | elpa/mode-icons-20190627.2121/mode-icons.el | 1883 |
1 files changed, 0 insertions, 1883 deletions
diff --git a/elpa/mode-icons-20190627.2121/mode-icons.el b/elpa/mode-icons-20190627.2121/mode-icons.el deleted file mode 100644 index cfa68ec..0000000 --- a/elpa/mode-icons-20190627.2121/mode-icons.el +++ /dev/null @@ -1,1883 +0,0 @@ -;;; mode-icons.el --- Show icons for modes -*- lexical-binding: t; -*- - -;; Copyright (C) 2013, 2016 Tom Willemse -;; 2016 Matthew L. Fidler - -;; Author: Tom Willemse <tom@ryuslash.org> -;; Keywords: multimedia -;; Version: 0.4.0 -;; URL: http://ryuslash.org/projects/mode-icons.html -;; Package-Requires: ((emacs "24") (cl-lib "0.5")) - -;; 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 of the License, 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. If not, see <http://www.gnu.org/licenses/>. - -;;; Commentary: - -;; This package provides a globalized minor mode that replaces the -;; major mode name in your mode-line and places like Ibuffer with an -;; icon. Currently the following programming modes are supported, -;; among others: -;; -;; - C -;; - C++ -;; - C# -;; - CSS -;; - Coffee -;; - Dart -;; - Emacs-Lisp -;; - HTML -;; - Haml -;; - JavaScript -;; - Lisp -;; - Lua -;; - nXML -;; - PHP -;; - Python -;; - React -;; - Ruby -;; - Rust -;; - Sass/Scss -;; - Scheme -;; - Shell-script -;; - Slim -;; - Snippet -;; - Web -;; - Yaml -;; -;; To enable this minor mode add the following line to your init file: -;; -;; (mode-icons-mode) -;; -;; As of version 0.3.0 this project includes some icons which can use icon -;; fonts instead of images. These fonts are: -;; -;; - Font Awesome, found at URL `http://fontawesome.io/'. -;; - GitHub Octicons, found at URL `https://octicons.github.com/'. -;; - Font Mfizz, found at URL `http://fizzed.com/oss/font-mfizz'. -;; - IcoMoon, found at URL `https://icomoon.io/#icons-icomoon'. -;; - -;;; Code: - -(declare-function comint-send-string "comint") -(declare-function emojify-set-emoji-data "emojify") -(declare-function ht-get "ht") -(declare-function powerline-minor-modes "powerline") -(declare-function powerline-raw "powerline-raw") -(declare-function pl/add-text-property "powerline") -(declare-function mode-icons--real-powerline-raw "powerline") -(declare-function mode-icons--powerline-raw "mode-icons") -(declare-function mode-icons--real-powerline-major-mode "powerline") -(declare-function mode-icons--powerline-major-mode "mode-icons") - -(require 'cl-lib) -(require 'color) -(require 'emojify nil t) - -(defgroup mode-icons nil - "Provide icons for major modes." - :group 'editing-basics - :group 'convenience) - -(defconst mode-icons--directory - (if load-file-name - (file-name-directory load-file-name) - default-directory) - "Where mode-icons was loaded from.") - -(defun mode-icons-get-icon-file (icon) - "Get the location of ICON. - -ICON should be a file name with extension. The result is the -absolute path to ICON." - (expand-file-name icon (expand-file-name "icons" mode-icons--directory))) - -(defmacro mode-icons-save-buffer-state (&rest body) - "Eval BODY saving buffer state. -This macro restores 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))))) - -(defcustom mode-icons - `(("\\`CSS\\'" "css" xpm) - ("\\`Coffee\\'" "coffee" xpm-bw) - ("\\`Compilation\\'" "compile" xpm) - ("\\`Dart\\'" "dart" xpm) - ("\\`Flutter\\'" "flutter" xpm) - ("\\`Elixir\\'" "elixir" xpm) - ("\\`Erlang\\'" "erlang" xpm) - ("\\`Emacs-Lisp\\'" "emacs" xpm) - ("\\`Lisp Interaction\\'" "emacs" xpm) - ("\\`HTML\\'" "html" xpm) - ("\\`Haml\\'" "haml" xpm) - ("\\`Image\\[imagemagick\\]\\'" "svg" xpm) - ("\\`Inf-Ruby\\'" "infruby" xpm) - ("\\`Java[Ss]cript\\'" "js" xpm) - ("\\`Lisp\\'" "cl" xpm) - ("\\`Lua\\'" "Lua-Logo_16x16" png) - ("\\`nXML\\'" "xml" xpm) - ("\\`Org\\'" "org" xpm) - ("\\`PHP\\(\\|/.*\\)\\'" "php" xpm) - ("\\`Projectile Rails Server\\'" "rails" xpm) - ("\\`Python\\'" "python" xpm) - ("\\` Emmet\\'" "emmet" xpm) - ("\\`RJSX\\'" "react" xpm) - ("\\`Ruby\\'" "ruby" xpm) - ("\\`Rust\\'" "rust" xpm) - ("\\`EnhRuby\\'" "ruby" xpm) - ("\\`ESS\\[S\\]\\'" "R" xpm) - ("\\`ESS\\[SAS\\]\\'" "sas" xpm) - ("\\`ESS\\[BUGS\\]\\'" #xf188 FontAwesome) - ("\\`iESS\\'" "R" xpm) - ("\\`SCSS\\'" "sass" xpm) - ("\\`Sass\\'" "sass" xpm) - ("\\`Scheme" "scheme" xpm-bw) - ("\\`Shell-script" "bash" xpm-bw) - ("\\`Slim" "slim" xpm-bw) - ("\\`Snippet" "yas" xpm) - ("\\`Term\\'" "term" xpm) - ("\\`Web\\'" "html" xpm) - ("\\`XML\\'" "xml" xpm) - ("\\`YAML\\'" "yaml" xpm) - ("\\` ?YASnippet\\'" "yas" xpm) - ("\\` ?yas\\'" "yas" xpm) - ("\\` ?hs\\'" "hs" xpm) - ("\\`Markdown\\'" #xf0c9 github-octicons) - ("\\`GFM\\'" #xf0c9 github-octicons) - ("\\`Scala\\'" #xf15b font-mfizz) - ("\\`Magit\\'" #xf1d2 FontAwesome) - ("\\` Pulls\\'" #xf092 FontAwesome) - ("\\`Zip-Archive\\'" #xf1c6 FontAwesome) - ("\\` ARev\\'" #xf021 FontAwesome) - ("\\`Calc\\(ulator\\)?\\'" #xf1ec FontAwesome) - ("\\`Debug.*\\'" #xf188 FontAwesome) - ("\\`Debug.*\\'" #xf188 FontAwesome) - ("\\`Calendar\\'" #xf073 FontAwesome) - ("\\`Help\\'" #xf059 FontAwesome) - ("\\`WoMan\\'" #xf05a FontAwesome) - ("\\`C\\(/.*\\|\\)\\'" "c" xpm) - ("\\`Custom\\'" #xf013 FontAwesome) - ("\\`Go\\'" "go" xpm) - ("\\` ?Rbow\\'" "rainbow" xpm) - ("\\` ?ivy\\'" "ivy" xpm) ;; Icon created by Philipp Lehmann from the Noun Project https://thenounproject.com/search/?q=ivy&i=329756 - ("\\` ?ICY\\'" "icy" xpm) ;; http://www.clipartpal.com/clipart_pd/weather/ice_10206.html - ("\\` ?Golden\\'" "golden" xpm-bw) ;; Icon created by Arthur Shlain from Noun Project - ("\\`BibTeX\\'\\'" "bibtex" xpm-bw) - ("\\`C[+][+]\\(/.*\\|\\)\\'" "cpp" xpm) - ("\\`C[#]\\(/.*\\|\\)\\'" "csharp" xpm) - ("\\`Haskell\\'" #xf126 font-mfizz) - ("\\`Clojure\\'" #xf10b font-mfizz) - ("\\`Java\\(/.*\\|\\)\\'" #xf12b font-mfizz) - ("\\`C?Perl\\'" #xf148 font-mfizz) - ("\\`Octave\\'" "octave" xpm) - ("\\`AHK\\'" "autohotkey" xpm) - ("\\`Info\\'" #xf05a FontAwesome) - ("\\` ?Narrow\\'" #xf066 FontAwesome) - ("\\`Dockerfile\\'" "docker" xpm) - ("\\`Spacemacs buffer\\'" "spacemacs" png) - ("\\` ?emoji\\'" "emoji" png) - ("\\`Org-Agenda" #xf046 FontAwesome) - ("\\`PS\\'" "powershell" xpm) - (mode-icons-powershell-p "powershell" xpm) - (mode-icons-cmd-p "cmd" xpm-bw) - (mode-icons-msys-p "msys" xpm) - (mode-icons-cygwin-p "cygwin" xpm) - (read-only #xf023 FontAwesome) - (writable #xf09c FontAwesome) - (save #xf0c7 FontAwesome) - (saved "" nil) - (modified-outside #xf071 FontAwesome) - (steal #xf21b FontAwesome) - ;; Prefer finder icon since it looks like the old mac icon - (apple #xeabf IcoMoon-Free) - (apple #xf179 FontAwesome) - (win #xf17a FontAwesome) - ;; FIXME: use lsb_release to determine Linux variant and choose appropriate icon - (unix #xeabd IcoMoon-Free) ;; Clear Tux (Unlike FontAwesome) - - ;; This icon is clearer than FontAwesome's Linux Penguin - (unix #xf166 font-mfizz) ;; Use ubuntu, since I think it is the most common. - (unix #xf17c FontAwesome) ;; Fall Back to FontAwesome - (undecided #xf128 FontAwesome) - ("Text\\'" #xf0f6 FontAwesome) - ("\\` ?company\\'" #xf1ad FontAwesome) - ("\\` ?AC\\'" #xf18e FontAwesome) - ("\\` ?Fly\\'" #xea12 IcoMoon-Free) - ;; ("\\` ?FlyC.*\\'" "flycheck" xpm) - ("\\` ?SP\\(/s\\)?\\'" "smartparens" xpm) - ("\\` ?Ergo" #xf11c FontAwesome) - ("\\` ?drag\\'" #xf047 FontAwesome) - ("\\` ?Helm\\'" "helm" xpm-bw) ;; By Noe Araujo, MX, https://thenounproject.com/term/helm/233101/ - ("\\`Messages\\'" #xf27b FontAwesome) - ("\\`Conf" #xf1de FontAwesome) - ("\\`Fundamental\\'" #xf016 FontAwesome) - ("\\`Javascript-IDE\\'" "js" xpm) - ("\\` Undo-Tree\\'" ":palm_tree:" emoji) - ("\\`LaTeX\\'" "tex" ext) - ("\\`Image\\[xpm\\]\\'" "xpm" ext) - ("\\`Image\\[png\\]\\'" "png" ext) - ("\\` ?AI\\'" #xf03c FontAwesome) - ("\\` ?Isearch\\'" #xf002) - (default #xf059 FontAwesome) - ;; Diminished modes - ("\\` ?\\(?:ElDoc\\|Anzu\\|SP\\|Guide\\|PgLn\\|Undo-Tree\\|Ergo.*\\|,\\|Isearch\\|Ind\\)\\'" nil nil)) - "Icons for major and minor modes. - -Each specificatioun is a list with the first element being the -name of the major mode. The second the name of the icon file, -without the extension. And the third being the type of icon." - :type '(repeat - (list (choice - (string :tag "Regular Expression") - (const :tag "Read Only Indicator" read-only) - (const :tag "Writable Indicator" writable) - (const :tag "Saved" saved) - (const :tag "Save" save) - (const :tag "Modified Outside Emacs" modified-outside) - (const :tag "Locked By Someone Else" steal) - (const :tag "Apple" apple) - (const :tag "Windows" win) - (const :tag "Unix" unix) - (const :tag "Default Icon" default) - (function :tag "Enriched minor mode")) - (choice - (string :tag "Icon Name") - (integer :tag "Font Glyph Code") - (const :tag "ess" nil)) - (choice - (const :tag "text" nil) - (const :tag "png" png) - (const :tag "gif" gif) - (const :tag "jpeg" jpeg) - (const :tag "jpg" jpg) - (const :tag "xbm" xbm) - (const :tag "xpm" xpm) - (const :tag "Black and White xpm that changes color to match the mode-line face" xpm-bw) - (const :tag "Emoji" emoji) - (const :tag "Mode Icons Generated file-type" ext) - (symbol :tag "Font")))) - :group 'mode-icons) - -(defun mode-icons-powershell-p (&optional match) - "Is the current mode a powershell process?" - (let ((proc (get-buffer-process (current-buffer)))) - (and proc (string-match-p (or match "powershell") (car (process-command proc)))))) - -(defun mode-icons-cmd-p () - "Is the current mode a CMD shell?" - (mode-icons-powershell-p "cmdproxy")) - -(defun mode-icons-cygwin-p () - "Is the current mode a CMD shell?" - (mode-icons-powershell-p "cygwin")) - -(defun mode-icons-msys-p () - "Is the current mode a CMD shell?" - (mode-icons-powershell-p "msys")) - -(defvar mode-icons-get-xpm-string (make-hash-table :test 'equal)) -(defun mode-icons-get-xpm-string (icon-path) - "Get XPM file contents for ICON-PATH. -If ICON-PATH is a string, return that." - (or (and (file-exists-p icon-path) - (or (gethash icon-path mode-icons-get-xpm-string) - (puthash icon-path (mode-icons-save-buffer-state (with-temp-buffer (insert-file-contents icon-path) (buffer-string))) - mode-icons-get-xpm-string))) - (and (stringp icon-path) icon-path))) - -(defun mode-icons-get-icon-display-xpm-replace (icon-path rep-alist &optional name) - "Get xpm image from ICON-PATH and replace REP-ALIST in file. -When NAME is non-nil, also replace the internal xpm image name." - (let ((case-fold-search t) - (img (mode-icons-get-xpm-string icon-path)) - (i 0)) - (dolist (c rep-alist) - (setq img (replace-regexp-in-string (regexp-quote (car c)) (format "COLOR<%d>" i) img t t) - i (1+ i))) - (let ((i 0)) - (dolist (c rep-alist) - (setq img (replace-regexp-in-string (format "COLOR<%d>" i) (cdr c) img t t) - i (1+ i)))) - (when name - (setq img (replace-regexp-in-string "^[ ]*static[ ]+char[ ]+[*][ ]+.*?\\[" (concat "static char * " name "[") img t t))) - img)) - -(defun mode-icons-interpolate (c1 c2 &optional factor) - "Interpolate between C1 and C2 by FACTOR. -If FACTOR is unspecified, use 0.5" - (let* ((factor (or factor 0.5)) - (red (+ (* (nth 0 c1) factor) (* (nth 0 c2) (- 1.0 factor)))) - (green (+ (* (nth 1 c1) factor) (* (nth 1 c2) (- 1.0 factor)))) - (blue (+ (* (nth 2 c1) factor) (* (nth 2 c2) (- 1.0 factor))))) - (setq red (/ (round (* 256.0 red)) 256.0) - green (/ (round (* 256.0 green)) 256.0) - blue (/ (round (* 256.0 blue)) 256.0)) - (color-rgb-to-hex red green blue))) - -(defun mode-icons-interpolate-from-scale (foreground background) - "Interpolate black to FOREGROUND and white to BACKGROUND. -Grayscales are in between. -Assumes that FOREGROUND and BACKGROUND are (r g b) lists." - (let ((black '(0.0 0.0 0.0)) - (white '(1.0 1.0 1.0)) - lst tmp - (i 0)) - (while (< i 256) - (setq tmp (/ i 255.0)) - (push (cons (upcase (mode-icons-interpolate black white tmp)) - (upcase (mode-icons-interpolate foreground background tmp))) lst) - (setq i (1+ i))) - lst)) - -(defvar mode-icons-get-icon-display-xpm-bw-face (make-hash-table) - "Hash table of dynamic images.") - -(defun mode-icons-background-color (&optional face) - "Get the background color of FACE. -In order, will try to get the background color from: -- FACE -- `mode-line' face -- `default' face -- Assume white." - (color-name-to-rgb (or (face-background (or face 'mode-line)) - (face-background 'mode-line) - (face-background 'default) - "white"))) - -(defun mode-icons-foreground-color (&optional face) - "Get the foreground color of FACE. -In order, will try to get the foreground color from: -- FACE -- `mode-line' face -- `default' face -- Assume black." - (color-name-to-rgb (or (face-foreground (or face 'mode-line)) - (face-foreground 'mode-line) - (face-foreground 'default) - "black"))) - -(defun mode-icons-get-icon-display-xpm-bw-face (icon-path &optional face) - "Change xpm at ICON-PATH to match FACE. -The white is changed to the background color. -The black is changed to the foreground color. -Grayscale colors are also changed by `mode-icons-interpolate-from-scale'." - (let* ((background (mode-icons-background-color face)) - (foreground (mode-icons-foreground-color face)) - (lst (mode-icons-interpolate-from-scale foreground background)) - (name (concat "mode_icons_bw_" (substring (mode-icons-interpolate background foreground 0.0) 1) "_" - (substring (mode-icons-interpolate background foreground 1.0) 1) "_" - (file-name-sans-extension (file-name-nondirectory icon-path)))) - (sym (intern name))) - (or (gethash sym mode-icons-get-icon-display-xpm-bw-face) - (puthash sym (mode-icons-get-icon-display-xpm-replace icon-path lst name) mode-icons-get-icon-display-xpm-bw-face)))) - -(defun mode-icons-get-xpm-icon-colors (icon-path) - "Get a list of rgb colors based on ICON-PATH xpm icon. -ICON-PATH can be a XPM string or a XPM file." - (let (colors) - (mode-icons-save-buffer-state - (with-temp-buffer - (insert (mode-icons-get-xpm-string icon-path)) - (goto-char (point-min)) - (while (re-search-forward "#[0-9A-Fa-f]\\{6\\}" nil t) - (push (color-name-to-rgb (match-string 0)) colors)))) - colors)) - -(defun mode-icons-desaturate-colors (colors &optional foreground background) - "Desaturate COLORS. - -If COLORS is an icon-path of an xpm file, use the colors from -that file. - -When FOREGROUND and BACKGROUND are both non-nil, use -`mode-icons-interpolate-from-scale' to change the grayscale to -match the foreground (black) and background (white) colors. - -Assume that COLORS is a list of (r g b) values. - -Returns a replacement list for `mode-icons-get-icon-display-xpm-replace'" - (if (and colors (stringp colors)) - (mode-icons-desaturate-colors (mode-icons-get-xpm-icon-colors colors) foreground background) - (let (color-list - val tmp - (trans-alist (and foreground background (mode-icons-interpolate-from-scale foreground background)))) - (dolist (color colors) - (setq val (+ (* 0.3 (nth 0 color)) (* 0.59 (nth 1 color)) (* 0.11 (nth 2 color))) - val (upcase (color-rgb-to-hex val val val))) - (when (and trans-alist (setq tmp (assoc val trans-alist))) - (setq val (cdr tmp))) - (push (cons (upcase (color-rgb-to-hex (nth 0 color) (nth 1 color) (nth 2 color))) val) color-list)) - color-list))) - -(defun mode-icons-desaturate-xpm (icon-path &optional face) - "Desaturate the xpm at ICON-PATH. -When FACE is non-nil, match the foreground and background colors -in FACE instead of making the image black and white." - (let* ((background (mode-icons-background-color face)) - (foreground (mode-icons-foreground-color face)) - (lst (mode-icons-desaturate-colors icon-path foreground background)) - (name (concat "mode_icons_desaturate_" - (or (and background foreground - (substring (mode-icons-interpolate background foreground 0.0) 1)) - "black") "_" - (or (and background foreground - (substring (mode-icons-interpolate background foreground 1.0) 1)) - "white") "_" - (file-name-sans-extension (file-name-nondirectory icon-path)))) - (sym (intern name))) - (or (gethash sym mode-icons-get-icon-display-xpm-bw-face) - (puthash sym (mode-icons-get-icon-display-xpm-replace icon-path lst name) mode-icons-get-icon-display-xpm-bw-face)))) - - -(defcustom mode-icons-desaturate-inactive t - "Should the inactive mode-line be desaturated. -And changed to match the icon colors? -This only works with xpm files." - :type 'boolean - :group 'mode-icons) - -(defcustom mode-icons-desaturate-active nil - "Should the active mode-line be desaturated. -And changed to match the icon colors? -This only works with xpm files." - :type 'boolean - :group 'mode-icons) - -(defcustom mode-icons-grayscale-transform t - "Should grayscale 'xpm-bw images match mode-line colors?" - :type 'boolean - :group 'mode-icons) - -(defvar mode-icons-get-icon-display (make-hash-table :test 'equal) - "Hash table of `mode-icons-get-icon-display'.") - -(defun mode-icons--get-face (&optional face active) - "If FACE is unspecified, use ACTIVE to determine the face. -ACTIVE tells if current window is active." - (or face (and active 'mode-line) 'mode-line-inactive)) - -(defcustom mode-icons-line-height-adjust 0 - "The manual adjustment of the mode-line height for images." - :type 'integer - :group 'mode-icons) - -(defun mode-icons-line-height (&optional window) - "Gets the height in pixels of WINDOW's mode-line, if accessible. -This uses `window-mode-line-height' on emacs 24.4+. Otherwise it assumes 16. - -This function also adjusts the line height by `mode-icons-line-height-adjust'." - (+ mode-icons-line-height-adjust - (or (and (fboundp 'window-mode-line-height) (window-mode-line-height window)) 16))) - -(defun mode-icons-get-icon-display (icon type &optional face active) - "Get the value for the display property of ICON having TYPE. - -ICON should be a string naming the file of the icon, without its -extension. Type should be a symbol designating the file type for -the icon. - -FACE should be the face for rendering black and white xpm icons -specified by type 'xpm-bw. - -ACTIVE is an indicator that the current window is active." - (let* ((face (mode-icons--get-face face active)) - (key (list icon type face active - mode-icons-desaturate-inactive mode-icons-desaturate-active - mode-icons-grayscale-transform custom-enabled-themes)) - tmp) - (or (gethash key mode-icons-get-icon-display) - (puthash key - (cond - ((memq type '(png xpm xpm-bw gif jpeg jpg xbm xpm)) - (let ((icon-path (mode-icons-get-icon-file - (concat icon "." (or (and (eq type 'xpm-bw) "xpm") - (symbol-name type)))))) - (cond - ((and mode-icons-grayscale-transform (eq type 'xpm-bw)) - (create-image (mode-icons-get-icon-display-xpm-bw-face icon-path face) - ;; Use imagemagick for rescaling... - (or (and (fboundp 'imagemagick-types) - (memq 'png (imagemagick-types)) 'imagemagick) - 'xpm) - t :ascent 'center - :face face - :xpm-bw t - :height (mode-icons-line-height) - :icon icon)) - ((eq type 'xpm-bw) - (create-image icon-path - (or (and (fboundp 'imagemagick-types) - (memq 'png (imagemagick-types)) 'imagemagick) - 'xpm) - :height (mode-icons-line-height) - :ascent 'center - :face face - :icon icon)) - ((and (eq type 'xpm) - (or (and active mode-icons-desaturate-active) - (and (not active) mode-icons-desaturate-inactive))) - (create-image (mode-icons-desaturate-xpm icon-path face) - (or (and (fboundp 'imagemagick-types) - (memq 'png (imagemagick-types)) 'imagemagick) - 'xpm) t - :ascent 'center - :height (mode-icons-line-height) - :face face :icon icon)) - (t - (create-image icon-path - (or (and (fboundp 'imagemagick-types) - (memq (or (and (eq type 'jpg) 'jpeg) type) (imagemagick-types)) - 'imagemagick) - (or (and (eq type 'jpg) 'jpeg) type)) - nil - :height (mode-icons-line-height) - :ascent 'center :face face :icon icon))))) - ((and (eq type 'emoji) (setq tmp (mode-icons--get-emoji " " (list "" icon type) face))) - (get-text-property 0 'display tmp)) - ;; Shouldn't get here... - ((and (eq type 'ext) (setq tmp (mode-icons--ext-available-p (list "" icon type)))) - (mode-icons-get-icon-display (concat "ext-" (downcase icon)) 'xpm-bw face active)) - ((and (image-type-available-p 'xpm) - (setq tmp (mode-icons--get-font-xpm-file (list "" icon type))) - (file-exists-p tmp)) - (setq tmp nil) - (mode-icons-get-icon-display (mode-icons--get-font-xpm-file (list "" icon type) t) 'xpm-bw face active)) - (t nil)) - mode-icons-get-icon-display)))) - -(defcustom mode-icons-minor-mode-base-text-properties - '('help-echo nil - 'mouse-face 'mode-line-highlight - 'local-map mode-line-minor-mode-keymap) - "List of text propeties to apply to every minor mode." - :type '(repeat sexp) - :group 'mode-icons) - -(defcustom mode-icons-major-mode-base-text-properties - '('help-echo "Major mode\nmouse-1: Display major mode menu\nmouse-2: Show help for major mode\nmouse-3: Toggle minor modes" - 'mouse-face 'mode-line-highlight - 'local-map mode-line-major-mode-keymap) - "List of text propeties to apply to every major mode." - :type '(repeat sexp) - :group 'mode-icons) - -(defcustom mode-icons-narrow-text-properties - '('local-map - '(keymap - (mode-line keymap - (mouse-2 . mode-line-widen))) - 'mouse-face 'mode-line-highlight 'help-echo "mouse-2: Remove narrowing from buffer") - "List of text propeties to apply to narrowing buffer indicator." - :type '(repeat sexp) - :group 'mode-icons) - -(defcustom mode-icons-read-only-text-properties - '('mouse-face 'mode-line-highlight 'local-map - '(keymap - (mode-line keymap - (mouse-1 . mode-line-toggle-read-only))) - 'help-echo 'mode-line-read-only-help-echo) - "List of text propeties to apply to read-only buffer indicator." - :type '(repeat sexp) - :group 'mode-icons) - -(defcustom mode-icons-modified-text-properties - '('mouse-face 'mode-line-highlight - 'local-map - '(keymap - (mode-line keymap - (mouse-1 . mode-icons-save-steal-or-revert-buffer) - (mouse-3 . mode-line-toggle-modified))) - 'help-echo 'mode-icons-modified-help-echo) - "List of text propeties to apply to read-only buffer indicator." - :type '(repeat sexp) - :group 'mode-icons) - -(defun mode-icons-save-steal-or-revert-buffer (event) - "Save buffer OR revert file from mode line. -Use EVENT to determine location." - (interactive "e") - (with-selected-window (posn-window (event-start event)) - (let* ((bfn (buffer-file-name)) - (revert-p (not (or (and bfn (file-remote-p buffer-file-name)) - (verify-visited-file-modtime (current-buffer))))) - (steal-p (and (not (or (and bfn (file-remote-p buffer-file-name)) - (member (file-locked-p bfn) '(nil t))))))) - (cond - (revert-p (revert-buffer t t)) - (steal-p - (message "To steal or ignore lock, start editing the file.")) - (t (call-interactively (key-binding (where-is-internal 'save-buffer global-map t)))))) - (force-mode-line-update))) - -(defun mode-icons-modified-help-echo (window _object _point) - "Return help text specifying WINDOW's buffer modification status." - (let* ((bfn (buffer-file-name)) - (revert-p (not (or (and bfn (file-remote-p buffer-file-name)) - (verify-visited-file-modtime (current-buffer))))) - (steal-p (and (not (or (and bfn (file-remote-p buffer-file-name)) - (member (file-locked-p bfn) '(nil t)))))) - (mod-p (buffer-modified-p (window-buffer window)))) - (format "Buffer is %s\nmouse-1: %s Buffer\nmouse-3: Toggle modification state" - (cond - (steal-p - "locked for editing by another user.") - (revert-p - "modified outside of emacs!") - ((buffer-modified-p (window-buffer window)) - "modified") - (t "unmodified")) - (cond - (steal-p - "Echo about lock status of") - (revert-p - "Revert") - (mod-p - "Save") - (t ""))))) - -(defcustom mode-icons-read-only-text-properties - '('mouse-face 'mode-line-highlight 'local-map - '(keymap - (mode-line keymap - (mouse-1 . mode-line-toggle-read-only))) - 'help-echo 'mode-line-read-only-help-echo) - "List of text propeties to apply to read-only buffer indicator." - :type '(repeat sexp) - :group 'mode-icons) - -(defvar mode-icons-powerline-p nil) -(defun mode-icons-need-update-p () - "Determine if the mode-icons need an update." - (not (or (and (boundp 'rich-minority-mode) rich-minority-mode) - (member 'sml/pos-id-separator mode-line-format) - (string-match-p "powerline" (prin1-to-string mode-line-format))))) - -(defvar mode-icons-font-register-alist nil - "Alist of characters supported.") - -(defun mode-icons-supported-font-p (char font) - "Determine if the CHAR is supported in FONT. -When DONT-REGISTER is non-nil, don't register the font. -Otherwise, register the font for use in the mode-line and -everywhere else." - (if (memq font '(ext emoji xpm xbm jpg jpeg gif png nil)) nil - (unless (boundp (intern (format "mode-icons-font-spec-%s" font))) - (set (intern (format "mode-icons-font-spec-%s" font)) - (and (member (format "%s" font) (font-family-list)) - (font-spec :name (format "%s" font))))) - (when (and (or (integerp char) - (and (stringp char) (= 1 (length char)))) - (boundp (intern (format "mode-icons-font-spec-%s" font))) - (symbol-value (intern (format "mode-icons-font-spec-%s" font)))) - (let* ((char (or (and (integerp char) char) - (and (stringp char) (= 1 (length char)) - (aref (vconcat char) 0)))) - (found-char-p (assoc char mode-icons-font-register-alist)) - (char-font-p (and found-char-p (eq (cdr found-char-p) font)))) - (cond - (char-font-p t) - (found-char-p t) - (t ;; not yet registered. - (set-fontset-font t (cons char char) (symbol-value (intern (format "mode-icons-font-spec-%s" font)))) - (push (cons char font) mode-icons-font-register-alist) - t)))))) - -(defun mode-icons-supported-p (icon-spec) - "Determine if ICON-SPEC is suppored on your system." - (or - (and (or (eq (nth 2 icon-spec) nil) (eq (nth 1 icon-spec) nil)) t) - (and (eq (nth 2 icon-spec) 'emoji) - (or (and (image-type-available-p 'png) (featurep 'emojify)) - (and (image-type-available-p 'xpm) - (file-exists-p (mode-icons--get-emoji-xpm-file icon-spec))))) - (and (eq (nth 2 icon-spec) 'jpg) (image-type-available-p 'jpeg)) - (and (eq (nth 2 icon-spec) 'xpm-bw) (image-type-available-p 'xpm)) - (and (eq (nth 2 icon-spec) 'ext) (image-type-available-p 'xpm) - (mode-icons--ext-available-p icon-spec)) - (or (mode-icons-supported-font-p (nth 1 icon-spec) (nth 2 icon-spec)) - (and (image-type-available-p 'xpm) - (mode-icons--get-font-xpm-file icon-spec) - (file-exists-p (mode-icons--get-font-xpm-file icon-spec)))) - (or (image-type-available-p (nth 2 icon-spec)) - (and (eq (nth 2 icon-spec) 'png) - (and (image-type-available-p 'xpm) - (file-exists-p (mode-icons--get-png-xpm-file icon-spec))))) )) - -(defvar emojify-emojis) - -(defvar mode-icons--gimp (executable-find "gimp") - "Gimp to convert png to xpm.") - -(defvar mode-icons--gimp-inferior-args "-i -d -b -") - -(defvar mode-icons--stop-gimp-after nil - "Seconds of idle time before mode-icons gimp is stopped. -When nil, don't stop the gimp inferior mode.") - -(defvar mode-icons--stop-gimp-timer nil) - -(defun mode-icons--start-gimp-inferior () - "GIMP inferior process." - (interactive) - (when (file-exists-p mode-icons--gimp) - (unless (get-buffer "*mode-icons-gimp*") - (cl-letf (((symbol-function 'pop-to-buffer-same-window) (lambda(&rest _ignore)))) - (save-excursion - (run-scheme (format "\"%s\" %s" mode-icons--gimp mode-icons--gimp-inferior-args)))) - (with-current-buffer (get-buffer "*scheme*") - (rename-buffer "*mode-icons-gimp*") - (set-process-query-on-exit-flag (get-buffer-process (get-buffer "*mode-icons-gimp*")) nil))))) - -(defvar mode-icons--gimp-ready-p nil) - -(defun mode-icons--gimp-ready-p () - "Determine if GIMP inferior process is ready." - (if (file-exists-p mode-icons--gimp) - (or mode-icons--gimp-ready-p - (let (buf) - (mode-icons--start-gimp-inferior) - (and (setq buf (get-buffer "*mode-icons-gimp*")) - (with-current-buffer buf - (goto-char (point-min)) - (when (re-search-forward "ts>" nil t) - (setq mode-icons--gimp-ready-p t)))))))) - -(defvar mode-icons--stop-gimp-inferior nil) -(defun mode-icons--stop-gimp-inferior () - "Stop the inferior gimp process." - (interactive) - (when (file-exists-p mode-icons--gimp) - (let ((buf (get-buffer "*mode-icons-gimp*"))) - (cond - ((and (mode-icons--gimp-ready-p) buf - (get-buffer-process buf)) - (mode-icons--process-gimp "(gimp-quit 0)") - (setq mode-icons--gimp-ready-p nil - mode-icons--stop-gimp-inferior t) - (run-with-idle-timer 1 nil #'mode-icons--stop-gimp-inferior)) - ((and buf (not (get-buffer-process buf))) - (kill-buffer (get-buffer "*mode-icons-gimp*"))) - (t (run-with-idle-timer 1 nil #'mode-icons--stop-gimp-inferior)))))) - -(defun mode-icons--process-gimp (scm) - "Process gimp SCM (scheme)." - (when mode-icons--stop-gimp-timer - (cancel-timer mode-icons--stop-gimp-timer)) - (when (file-exists-p mode-icons--gimp) - (if (mode-icons--gimp-ready-p) - (progn - (comint-send-string - (with-current-buffer (get-buffer "*mode-icons-gimp*")) - (concat scm "\n")) - (when mode-icons--stop-gimp-after - (setq mode-icons--stop-gimp-timer (run-with-timer mode-icons--stop-gimp-after nil #'mode-icons--stop-gimp-inferior)))) - (run-with-idle-timer 1 nil #'mode-icons--process-gimp scm)))) - -(defvar mode-icons--generic-type-to-xpm-gimp-script - (replace-regexp-in-string - "[ \n\t]+" " " - "(let* ((image-width 1024) - (image-height 20) - (buffer-image 1) - (text \"%s\") - (font-size 20) - (font-name \"FontAwesome\") - (xpm-image \"%s\") - (font-size-2 10) - (text-2 \"%s\") - (font-name-2 \"Haettenschweiler\") - (bg-color '(255 255 255)) - (fg-color '(0 0 0)) - (image (car (gimp-image-new 1024 16 0))) - (layer (car (gimp-layer-new image image-width image-height RGB-IMAGE \"layer 1\" 100 NORMAL))) - (layer2 (car (gimp-layer-new image image-width image-height RGB-IMAGE \"layer 2\" 100 NORMAL))) - (out-text) - (out-width) - (out-height) - (out-buffer) - (drawable)) - (gimp-image-add-layer image layer 0) - (gimp-context-set-background bg-color) - (gimp-context-set-foreground fg-color) - (gimp-layer-add-alpha layer) - (gimp-drawable-fill layer TRANSPARENT-FILL) - (gimp-image-add-layer image layer2 0) - (gimp-layer-add-alpha layer2) - (gimp-drawable-fill layer2 TRANSPARENT-FILL) - (gimp-text-fontname image layer2 3 7 text-2 0 TRUE font-size-2 PIXELS font-name-2) - (set! out-text (car (gimp-text-fontname image layer 0 0 text 0 TRUE font-size PIXELS font-name))) - (set! out-width (car (gimp-drawable-width out-text))) - (set! out-height (car (gimp-drawable-height out-text))) - (set! out-buffer (* out-height (/ buffer-image 100))) - (set! out-height (+ out-height out-buffer out-buffer)) - (set! out-width (+ out-width out-buffer out-buffer)) - (gimp-image-resize image out-width out-height 0 0) - (gimp-layer-resize layer out-width out-height 0 0) - (gimp-layer-set-offsets out-text out-buffer out-buffer) - (gimp-image-flatten image) - (set! drawable (car (gimp-image-get-active-layer image))) - (file-xpm-save RUN-NONINTERACTIVE image drawable xpm-image xpm-image 127) - (gimp-image-delete image))") - "Generic Type script.") - -(defvar mode-icons--font-to-xpm-gimp-script - (replace-regexp-in-string - "[ \n\t]+" " " - "(let* ((image-width 1024) - (image-height 20) - (buffer-image 1) - (text \"%s\") - (font-size 20) - (font-name \"%s\") - (xpm-image \"%s\") - (bg-color '(255 255 255)) - (fg-color '(0 0 0)) - (image (car (gimp-image-new 1024 16 0))) - (layer (car (gimp-layer-new image image-width image-height RGB-IMAGE \"layer 1\" 100 NORMAL))) - (out-text) - (out-width) - (out-height) - (out-buffer) - (drawable)) - (gimp-image-add-layer image layer 0) - (gimp-context-set-background bg-color) - (gimp-context-set-foreground fg-color) - (gimp-layer-add-alpha layer) - (gimp-drawable-fill layer TRANSPARENT-FILL) - (set! out-text (car (gimp-text-fontname image layer 0 0 text 0 TRUE font-size PIXELS font-name))) - - (set! out-width (car (gimp-drawable-width out-text))) - (set! out-height (car (gimp-drawable-height out-text))) - (set! out-buffer (* out-height (/ buffer-image 100))) - (set! out-height (+ out-height out-buffer out-buffer)) - (set! out-width (+ out-width out-buffer out-buffer)) - (gimp-image-resize image out-width out-height 0 0) - (gimp-layer-resize layer out-width out-height 0 0) - (gimp-layer-set-offsets out-text out-buffer out-buffer) - (gimp-image-flatten image) - (set! drawable (car (gimp-image-get-active-layer image))) - (file-xpm-save RUN-NONINTERACTIVE image drawable xpm-image xpm-image 127) - (gimp-image-delete image))") - "Gimp scheme script to convert a font character to xpm file.") - -(defvar mode-icons--convert-ext-to-xpm (make-hash-table :test 'equal)) -(defun mode-icons--convert-ext-to-xpm (ext) - "Convert EXT to a xpm file." - (let ((xpm (mode-icons-get-icon-file (concat "ext-" (downcase ext) ".xpm")))) - (when (and mode-icons--gimp (file-exists-p mode-icons--gimp) - xpm (not (gethash xpm mode-icons--convert-ext-to-xpm)) - (not (file-exists-p xpm))) - (puthash xpm t mode-icons--convert-ext-to-xpm) - (mode-icons--process-gimp - (format mode-icons--generic-type-to-xpm-gimp-script (make-string 1 #xf016) xpm - (downcase ext)))))) - -(defun mode-icons--ext-available-p (icon-spec) - "Determine if ICON-SPEC's ext is availble for display. -If not, try `mode-icons--convert-ext-to-xpm'." - (when (eq (nth 2 icon-spec) 'ext) - (let ((xpm (mode-icons-get-icon-file (concat "ext-" (downcase (nth 1 icon-spec)) ".xpm")))) - (if (file-readable-p xpm) - xpm - (mode-icons--convert-ext-to-xpm (nth 1 icon-spec)) - nil)))) - -(defcustom mode-icons-generate-font-grayscale nil - "Generate grayscale images for font icons. -This is used instead of transparancy to capure the font's -anti-aliasing. `mode-icons' will transform the colors to match -the background instead." - :type 'boolean - :group 'mode-icons) - -(defvar mode-icons--convert-text-to-xpm (make-hash-table :test 'equal)) -(defun mode-icons--convert-text-to-xpm (text font xpm &optional face height) - "Convert TEXT in FONT to XPM file using gimp. - -When FACE is non-nil, use the face background and foreground -properties to render the font (its no longer transparent). - -When HEIGHT is non-nil, use the font HEIGHT (in pixels) instead -of 20px." - (when (and mode-icons--gimp (file-exists-p mode-icons--gimp) - xpm (not (gethash xpm mode-icons--convert-text-to-xpm)) - (not (file-exists-p xpm))) - (puthash xpm t mode-icons--convert-text-to-xpm) - (let ((script (format mode-icons--font-to-xpm-gimp-script text font xpm)) - (background (mode-icons-background-color face)) - (foreground (mode-icons-foreground-color face))) - (when face - (setq background (mapcar (lambda(x) - (round (* 255 x))) background) - foreground (mapcar (lambda(x) - (round (* 255 x))) foreground)) - (setq script (replace-regexp-in-string - (regexp-quote "(bg-color '(255 255 255))") - (format "(bg-color '%s)" background) - script) - script (replace-regexp-in-string - (regexp-quote "(fg-color '(0 0 0))") - (format "(fg-color '%s)" foreground) - script) - script (replace-regexp-in-string - "TRANSPARENT-FILL" "BACKGROUND-FILL" script) - script (replace-regexp-in-string - (regexp-quote "(gimp-layer-add-alpha layer)") "" script))) - (when height - (setq script (replace-regexp-in-string - (regexp-quote "(image-height 20)") - (format "(image-height %s)" background) - script) - script (replace-regexp-in-string - (regexp-quote "(font-size 20)") - (format "(font-size %s)" background) - script) - script (replace-regexp-in-string - "TRANSPARENT-FILL" "BACKGROUND-FILL" script) - script (replace-regexp-in-string - (regexp-quote "(gimp-layer-add-alpha layer)") "" script))) - (when mode-icons-generate-font-grayscale - (setq script (replace-regexp-in-string - "TRANSPARENT-FILL" "BACKGROUND-FILL" script) - script (replace-regexp-in-string - (regexp-quote "(gimp-layer-add-alpha layer)") "" script))) - (mode-icons--process-gimp script)))) - -(defun mode-icons--get-font-xpm-file (icon-spec &optional icon-name) - "Get the font icon equivalent xpm file name from ICON-SPEC. -When ICON-NAME is non-nil, return the small icon name without the -extension or directory." - (let* ((xpm-int (or (and (stringp (nth 1 icon-spec)) - (= 1 (length (nth 1 icon-spec))) - (aref (nth 1 icon-spec) 0)) - (and (integerp (nth 1 icon-spec)) - (nth 1 icon-spec)))) - (xpm-base (and (integerp xpm-int) - (format "%s-%x" (nth 2 icon-spec) - xpm-int)))) - (and xpm-base - (if icon-name - xpm-base - (mode-icons-get-icon-file (concat xpm-base ".xpm")))))) - -(defun mode-icons--create-font-xpm-file (icon-spec) - "Create a font-based xpm file based on ICON-SPEC." - (mode-icons--convert-text-to-xpm - (or (and (stringp (nth 1 icon-spec)) - (nth 1 icon-spec)) - (and (integerp (nth 1 icon-spec)) - (make-string 1 (nth 1 icon-spec)))) - (symbol-name (nth 2 icon-spec)) - (mode-icons--get-font-xpm-file icon-spec))) - -(defun mode-icons--convert-all-font-icons-to-xpm () - "Convert all font icons to xpm files." - (interactive) - (setq mode-icons--convert-text-to-xpm (make-hash-table :test 'equal)) - (dolist (icon-spec mode-icons) - (when (mode-icons-supported-font-p (nth 1 icon-spec) (nth 2 icon-spec)) - (mode-icons--create-font-xpm-file icon-spec)))) - -(defvar mode-icons--png-to-xpm-gimp-script - (replace-regexp-in-string - "[ \n\t]+" " " - "(let* ((png-image \"%s\") - (xpm-image \"%s\") - (image (car (file-png-load RUN-NONINTERACTIVE png-image png-image))) - (drawable (car (gimp-image-get-active-layer image))) - (width (car (gimp-image-width image))) - (height (car (gimp-image-height image))) - (new-height 16.0) - (new-width (inexact->exact (round (* width (/ new-height height)))))) - (gimp-image-resize image 16 new-width 0 0) - (set! drawable (car (gimp-image-get-active-layer image))) - (file-xpm-save RUN-NONINTERACTIVE image drawable xpm-image xpm-image 127) - (gimp-image-delete image))") - "Gimp scheme script to convert png to xpm.") - -(defvar mode-icons--convert-png-to-xpm (make-hash-table :test 'equal) - "Hash table to make sure you only convert once.") - -(defun mode-icons--convert-png-to-xpm (png xpm) - "Covert PNG to a ?x16 XPM using `mode-icons--gimp'." - (when (and mode-icons--gimp (file-exists-p mode-icons--gimp) - xpm (not (gethash (list png xpm) mode-icons--convert-png-to-xpm)) - (not (file-exists-p xpm))) - (puthash (list png xpm) t mode-icons--convert-png-to-xpm) - (mode-icons--process-gimp (format mode-icons--png-to-xpm-gimp-script png xpm)))) - -(defun mode-icons--get-png-xpm-file (icon-spec &optional icon-name) - "Get the png->xpm file name from ICON-SPEC. - -When ICON-NAME is non-nil, return the mode-icons icon name." - (if icon-name - (nth 1 icon-spec) - (mode-icons-get-icon-file (concat (nth 1 icon-spec) ".xpm")))) - -(defun mode-icons--convert-all-png-icons-to-xpm () - "Convert all png icons to xpm files." - (interactive) - (setq mode-icons--convert-png-to-xpm (make-hash-table :test 'equal)) - (dolist (icon-spec mode-icons) - (when (eq 'png (nth 2 icon-spec)) - (mode-icons--convert-png-to-xpm - (mode-icons-get-icon-file (concat (nth 1 icon-spec) ".png")) - (mode-icons-get-icon-file (concat (nth 1 icon-spec) ".xpm")))))) - -(defun mode-icons--get-emoji-xpm-file (icon-spec &optional icon-name) - "Get the emoji xpm file name from ICON-SPEC. -This only supports emoji enclosed in a \":\" like :herb:. - -When ICON-NAME is non-nil, return the mode-icons icon name. -For :herb: it would be e-herb." - (let* ((xpm-base (nth 1 icon-spec)) - file) - (when (char-equal (aref xpm-base 0) ?:) - (setq file (substring xpm-base 1)) - (when (char-equal (aref (substring xpm-base -1) 0) ?:) - (setq file (substring file 0 -1)) - (if icon-name - (concat "e-" file) - (mode-icons-get-icon-file (concat "e-" file ".xpm"))))))) - -(defun mode-icons--get-png (mode icon-spec &optional face active) - "Get MODE for png ICON-SPEC using FACE. -If possible, convert the png file to an xpm file. -ACTIVE is a flag telling if the current window is active." - (let* ((xpm (mode-icons--get-png-xpm-file icon-spec)) - (xpm-name (mode-icons--get-png-xpm-file icon-spec t)) - (xpm-p (file-readable-p xpm)) - (png (mode-icons-get-icon-file (concat (nth 1 icon-spec) ".png"))) - (png-p (file-readable-p png)) - (face (mode-icons--get-face face active))) - (if xpm-p - (propertize (format "%s" mode) 'display - (mode-icons-get-icon-display - xpm-name 'xpm - face active) - 'face face - 'mode-icons-p (list (nth 0 icon-spec) xpm-name 'xpm)) - (if (not png-p) - (propertize (format "%s" mode) - 'face face - 'mode-icons-p icon-spec) - (mode-icons--convert-png-to-xpm png xpm) - (propertize (format "%s" mode) - 'display - (create-image png - ;; use imagemagick if available and supports PNG images - ;; (allows resizing images) - (or (and (and (fboundp 'imagemagick-types) - (memq 'png (imagemagick-types))) - 'imagemagick) 'png) - nil - :height (mode-icons-line-height) - :ascent 'center - :heuristic-mask t - :face face) - 'face face - 'mode-icons-p icon-spec))))) - -(defcustom mode-icons-prefer-xpm-over-emoji nil - "Prefer generated xpms over fonts. -If mode-icons has a generated font character, prefer that over -the actual font." - :type 'boolean - :group 'mode-icons) - -(defcustom mode-icons-generate-emoji-xpms nil - "Generate font compatibility xpms for fonts." - :type 'boolean - :group 'mode-icons) - -(defun mode-icons--get-emoji (mode icon-spec &optional face active) - "Get MODE emoji for ICON-SPEC using FACE. -ACTIVE is a flag for if the current window is active." - (let* ((xpm (mode-icons--get-emoji-xpm-file icon-spec)) - (xpm-name (mode-icons--get-emoji-xpm-file icon-spec t)) - (xpm-p (file-readable-p xpm)) - (face (mode-icons--get-face face active))) - (if (or (and mode-icons-prefer-xpm-over-emoji xpm-p) - (and xpm-p (not (featurep 'emojify))) - (and xpm-p (not (image-type-available-p 'png)))) - (propertize (format "%s" mode) 'display - (mode-icons-get-icon-display - xpm-name 'xpm face active) - 'mode-icons-p (list (nth 0 icon-spec) xpm-name 'xpm)) - (unless emojify-emojis - (emojify-set-emoji-data)) - (let* ((emoji (ht-get emojify-emojis (nth 1 icon-spec))) - (image-file (expand-file-name (ht-get emoji "image") (if (fboundp 'emojify-image-dir) - (emojify-image-dir) - emojify-image-dir))) - (image-type (intern (upcase (file-name-extension image-file))))) - (if (not (file-exists-p image-file)) - (propertize (format "%s" mode) - 'face face - 'mode-icons-p icon-spec) - (when mode-icons-generate-emoji-xpms - (mode-icons--convert-png-to-xpm image-file xpm)) - (propertize (format "%s" mode) - 'display - (create-image image-file - ;; use imagemagick if available and supports PNG images - ;; (allows resizing images) - (or (and (and (fboundp 'imagemagick-types) - (memq image-type (imagemagick-types))) - 'imagemagick) 'png) - nil - :ascent 'center - :heuristic-mask t - :face face - ;; :background (emojify--get-image-background beg end) - ;; no-op if imagemagick is not available - :height (mode-icons-line-height)) - 'face face - 'mode-icons-p icon-spec)))))) - -(defcustom mode-icons-prefer-xpm-over-font nil - "Prefer generated xpms over fonts. -If mode-icons has a generated font character, prefer that over -the actual font." - :type 'boolean - :group 'mode-icons) - -(defcustom mode-icons-generate-font-xpms nil - "Generate font compatibility xpms for fonts." - :type 'boolean - :group 'mode-icons) - -(defun mode-icons--get-font (mode icon-spec &optional face active) - "Get font for MODE based on ICON-SPEC, and FACE. -ACTIVE if a flag for if the current window is active." - ;; Use `compose-region' because it allows clickable text. - (let* ((xpm (mode-icons--get-font-xpm-file icon-spec)) - (xpm-name (mode-icons--get-font-xpm-file icon-spec t)) - (xpm-p (file-readable-p xpm)) - (face (mode-icons--get-face face active))) - (when (and (not xpm-p) mode-icons-generate-font-xpms) - (mode-icons--create-font-xpm-file icon-spec)) - (if (and xpm-p (or mode-icons-prefer-xpm-over-font - (not (mode-icons-supported-font-p (nth 1 icon-spec) (nth 2 icon-spec))))) - (propertize (format "%s" mode) 'display - (mode-icons-get-icon-display - xpm-name 'xpm face active) - 'mode-icons-p (list (nth 0 icon-spec) xpm-name 'xpm-bw) - 'face face) - (mode-icons-save-buffer-state - (with-temp-buffer - (if (stringp mode) - (insert mode) - (insert (or (and (integerp (nth 1 icon-spec)) - (make-string 1 (nth 1 icon-spec))) - (nth 1 icon-spec)))) - (compose-region (point-min) (point-max) (or (and (integerp (nth 1 icon-spec)) - (make-string 1 (nth 1 icon-spec))) - (nth 1 icon-spec))) - (put-text-property (point-min) (point-max) - 'face face) - (if (mode-icons-supported-font-p (nth 1 icon-spec) (nth 2 icon-spec)) - (put-text-property (point-min) (point-max) - 'mode-icons-p icon-spec) - (put-text-property (point-min) (point-max) - 'mode-icons-p (list (nth 0 icon-spec) xpm-name 'xpm-bw))) - (buffer-string)))))) - -(defun mode-icons-propertize-mode (mode icon-spec &optional face active) - "Propertize MODE with ICON-SPEC. - -MODE should be a string, the name of the mode to propertize. -ICON-SPEC should be a specification from `mode-icons'. -FACE is the face to match when a xpm-bw image is used. -ACTIVE is a flag to tell if the current window is active." - (let (tmp new-icon-spec) - (mode-icons-save-buffer-state ;; Otherwise may cause issues with trasient mark mode - (cond - ((and (stringp mode) (get-text-property 0 'mode-icons-p mode)) - mode) - ((not (nth 1 icon-spec)) - "") - ((and (stringp (nth 1 icon-spec)) (not (nth 2 icon-spec))) - (propertize (nth 1 icon-spec) 'display (nth 1 icon-spec) - 'mode-icons-p icon-spec)) - ((mode-icons-supported-font-p (nth 1 icon-spec) (nth 2 icon-spec)) - ;; (propertize mode 'display (nth 1 icon-spec) 'mode-icons-p t) - ;;(mode-icons--get-font " AI" '("\\` ?AI\\'" 61500 FontAwesome) face active) - (mode-icons--get-font mode icon-spec face active)) - ((and (stringp (nth 1 icon-spec)) (eq (nth 2 icon-spec) 'emoji)) - (mode-icons--get-emoji mode icon-spec face active)) - ((and (stringp (nth 1 icon-spec)) (eq (nth 2 icon-spec) 'png)) - (mode-icons--get-png mode icon-spec face active)) - ((and (stringp (nth 1 icon-spec)) (eq (nth 2 icon-spec) 'ext)) - (propertize (format "%s" mode) 'display - (mode-icons-get-icon-display - (concat "ext-" (nth 1 icon-spec)) 'xpm-bw face active) - 'mode-icons-p (list (nth 0 icon-spec) - (concat "ext-" (nth 1 icon-spec)) - 'xpm-bw))) - (t (setq tmp (mode-icons-get-icon-display (nth 1 icon-spec) (nth 2 icon-spec) face active)) - ;; (when (string= (nth 0 icon-spec) "\\` ?AI\\'") - ;; (message "plist: %s" tmp)) - (cond - ((and (plist-get (cdr tmp) :xpm-bw) (plist-get (cdr tmp) :icon)) - (setq new-icon-spec (list (nth 0 icon-spec) (plist-get (cdr tmp) :icon) 'xpm-bw))) - ((and (eq (plist-get (cdr tmp) :type) 'xpm) (plist-get (cdr tmp) :icon)) - (setq new-icon-spec (list (nth 0 icon-spec) (plist-get (cdr tmp) :icon) 'xpm))) - (t (setq new-icon-spec icon-spec))) - (propertize (format "%s" mode) 'display tmp - 'mode-icons-p new-icon-spec)))))) - -(defvar mode-icons-get-icon-spec (make-hash-table :test 'equal) - "Hash table of icon-specifications.") -(defun mode-icons-get-icon-spec (mode &optional is-major-mode-p) - "Get icon spec for MODE based on regular expression." - (or (gethash mode mode-icons-get-icon-spec) - (let* (case-fold-search - (ignore-cache nil) - (icon-spec (catch 'found-mode - (dolist (item mode-icons) - (when (and (mode-icons-supported-p item) - (or - (and - (stringp (car item)) - (stringp mode) - (string-match-p (car item) mode)) - (and - (symbolp (car item)) - (symbolp mode) - (eq mode (car item))) - (and - is-major-mode-p - (symbolp (car item)) - (functionp (car item)) - (and (ignore-errors (funcall (car item))) - (setq ignore-cache t))))) - (throw 'found-mode item))) - nil))) - (when (and icon-spec (eq (nth 2 icon-spec) 'emoji) - (file-exists-p (mode-icons--get-emoji-xpm-file icon-spec))) - (setq icon-spec (list (nth 0 icon-spec) (mode-icons--get-emoji-xpm-file icon-spec t) 'xpm))) - (unless ignore-cache - (puthash mode icon-spec mode-icons-get-icon-spec)) - icon-spec))) - -(defcustom mode-icons-show-mode-name nil - "Show Icon and `mode-name'." - :type 'boolean - :group 'mode-icons) - -(defcustom mode-icons-change-mode-name t - "Change the `mode-name' variable. - -This allows functions like `ibuffer' or `helm-mode' to show the -icon as well." - :type 'boolean - :group 'mode-icons) - -(defcustom mode-icons-use-default-icon nil - "Use the 'default icon when icon-name cannot be found." - :type 'boolean - :group 'mode-icons) - -(defun mode-icons-get-mode-icon (mode &optional face active) - "Get the icon for MODE, if there is one. -FACE represents the face used when the icon is a xpm-bw image. -ACTIVE represents if the window is active." - (let* ((mode-name (format-mode-line mode)) - (icon-spec (mode-icons-get-icon-spec mode-name t)) - (face (mode-icons--get-face face active)) - ret) - (when (and (not icon-spec) mode-icons-use-default-icon) - (setq icon-spec (mode-icons-get-icon-spec 'default))) - (if icon-spec - (setq ret - (if mode-icons-show-mode-name - (concat (mode-icons-propertize-mode mode-name icon-spec face active) " " mode-name) - (mode-icons-propertize-mode mode-name icon-spec face active))) - (setq ret mode-name)) - ;; Don't hide major mode names... - (when (string= ret "") - (setq ret mode-name)) - ret)) - -(defvar mode-icons-cached-mode-name nil - "Cached mode name to restore when disabling mode-icons.") - -(defvar mode-icons--mode-name nil - "Mode name displayed by mode-icons.") - -(defun mode-icons-set-mode-icon (mode) - "Set the icon for MODE." - (unless mode-icons-cached-mode-name - (set (make-local-variable 'mode-icons-cached-mode-name) - mode-name) - (set (make-local-variable 'mode-icons--mode-name) - (mode-icons-get-mode-icon mode nil t)) - (when mode-icons-change-mode-name - (setq mode-name mode-icons--mode-name)))) - -(defun mode-icons-major-mode-icons-undo () - "Undo the `mode-name' icons." - (dolist (b (buffer-list)) - (with-current-buffer b - (when mode-icons-cached-mode-name - (setq mode-name mode-icons-cached-mode-name - mode-icons-cached-mode-name nil))))) - -(defun mode-icons-major-mode-icons () - "Apply mode name icons on all buffers." - (dolist (b (buffer-list)) - (with-current-buffer b - (mode-icons-set-current-mode-icon)))) - -(defun mode-icons-set-current-mode-icon () - "Set the icon for the current major mode." - (mode-icons-set-mode-icon mode-name)) - -(defvar mode-icons-set-minor-mode-icon-alist nil) - -(defun mode-icons-set-minor-mode-icon-undo (&optional dont-update) - "Undo minor modes. -When DONT-UPDATE is non-nil, don't call `force-mode-line-update'." - (let (minor) - (dolist (mode mode-icons-set-minor-mode-icon-alist) - (setq minor (assq (car mode) minor-mode-alist)) - (when minor - (setcdr minor (cdr mode))))) - (setq mode-icons-set-minor-mode-icon-alist nil) - (unless dont-update - (force-mode-line-update))) - -(defcustom mode-icons-separate-images-with-spaces t - "Separate minor-mode icons with spaces." - :type 'boolean - :group 'mode-icons) - -(defun mode-icons-set-minor-mode-icon (&optional dont-update) - "Set the icon for the minor modes. -When DONT-UPDATE is non-nil, don't call `force-mode-line-update'" - (let (icon-spec mode-name minor cur-mode) - (dolist (mode minor-mode-alist) - (setq cur-mode - (or (assq (car mode) mode-icons-set-minor-mode-icon-alist) - mode)) - (setq mode-name (format-mode-line cur-mode) - icon-spec (mode-icons-get-icon-spec mode-name)) - (when icon-spec - (setq minor (assq (car cur-mode) minor-mode-alist)) - (when minor - (or (assq (car cur-mode) mode-icons-set-minor-mode-icon-alist) - (push (copy-sequence minor) mode-icons-set-minor-mode-icon-alist)) - (setq mode-name (replace-regexp-in-string "^ " "" mode-name) - mode-name (mode-icons-propertize-mode mode-name icon-spec)) - (if (string= "" mode-name) - (setcdr minor (list "")) - (setcdr minor (list (concat (or (and mode-icons-separate-images-with-spaces " ") "") - mode-name)))))))) - (unless dont-update - (force-mode-line-update))) - -(defun mode-icons--generate-major-mode-item (&optional face) - "Give rich strings needed for `major-mode' viewing. -FACE is the face that the major mode item should be rendered in." - (let* ((active (mode-icons--selected-window-active)) - (face (mode-icons--get-face face active))) - (eval `(propertize ,(mode-icons--recolor-string (or mode-icons--mode-name mode-name) active face) - 'face ',face - ,@mode-icons-major-mode-base-text-properties)))) - -;;; selected take from powerline -(defvar mode-icons--selected-window (frame-selected-window) - "Selected window.") - -(defun mode-icons--set-selected-window () - "Set the variable `mode-icons--selected-window' appropriately." - (when (not (minibuffer-window-active-p (frame-selected-window))) - (setq mode-icons--selected-window (frame-selected-window)))) - -(defun mode-icons--unset-selected-window () - "Unsets the variable `mode-icons--selected-window' and update the modeline." - (setq mode-icons--selected-window nil) - (force-mode-line-update)) - -(add-hook 'window-configuration-change-hook 'mode-icons--set-selected-window) - -;; focus-in-hook was introduced in emacs v24.4. -;; Gets evaluated in the last frame's environment. -;; (add-hook 'focus-in-hook 'mode-icons--set-selected-window) - -;; focus-out-hook was introduced in emacs v24.4. -;; (add-hook 'focus-out-hook 'mode-icons--unset-selected-window) - -;; Executes after the window manager requests that the user's events -;; be directed to a different frame. -(defadvice handle-switch-frame - (after mode-icons--set-selected-window-after-switch-frame activate) - "Make `mode-icons' aware of selected window." - (mode-icons--set-selected-window)) - -(defadvice select-window (after mode-icons--select-window activate) - "Make `mode-icons' aware of selected window." - (mode-icons--set-selected-window)) - -(defun mode-icons--selected-window-active () - "Return whether the current window is active." - (eq mode-icons--selected-window (selected-window))) - -(defun mode-icons--property-substrings (str prop) - "Return a list of substrings of STR when PROP change." - ;; Taken from powerline by Donald Ephraim Curtis, Jason Milkins and - ;; Nicolas Rougier - (let ((beg 0) (end 0) - (len (length str)) - (out)) - (while (< end (length str)) - (setq end (or (next-single-property-change beg prop str) len)) - (setq out (append out (list (substring str beg (setq beg end)))))) - out)) - -(defun mode-icons--recolor-string (string &optional active face) - "Recolor `mode-icons' in STRING. -ACTIVE tells if the current window is active. -FACE is the face to recolor the icon to." - (let* ((face (mode-icons--get-face face active)) - icon-spec) - (mapconcat - (lambda(str) - (cond - ((get-text-property 0 'display str) - (mode-icons--recolor-minor-mode-image str active face)) - ((and (setq icon-spec (get-text-property 0 'mode-icons-p str)) - (mode-icons-supported-font-p (nth 1 icon-spec) (nth 2 icon-spec))) - (mode-icons--get-font str icon-spec face active)) - (t - str))) - (mode-icons--property-substrings string 'mode-icons-p) - ""))) - -(defun mode-icons--recolor-minor-mode-image (mode active &optional face) - "Recolor MODE image based on if the window is ACTIVE. -Use FACE when specified." - (let ((icon-spec (get-text-property 0 'mode-icons-p mode)) - (face (mode-icons--get-face face active))) - (cond - ((and icon-spec (memq (nth 2 icon-spec) '(xpm xpm-bw))) - (propertize mode 'display (mode-icons-get-icon-display - (nth 1 icon-spec) (nth 2 icon-spec) face active) - 'face face - 'mode-icons-p icon-spec)) - ((and icon-spec (memq (nth 2 icon-spec) '(emoji)) - (file-exists-p (mode-icons--get-emoji-xpm-file icon-spec))) - (propertize mode 'display (mode-icons-get-icon-display - (mode-icons--get-emoji-xpm-file icon-spec t) - 'xpm face active) 'face face - 'mode-icons-p icon-spec)) - (t (propertize mode 'face face))))) - -(defun mode-icons--generate-minor-mode-list (&optional face) - "Extracts all rich strings necessary for the minor mode list. -When FACE is non-nil, use FACE to render the `minor-mode-alist'." - (let* ((active (mode-icons--selected-window-active)) - (face (mode-icons--get-face face active))) - (delete " " (delete "" (mapcar (lambda(mode) - (concat " " (eval `(propertize ,(mode-icons--recolor-minor-mode-image mode active face) - ,@mode-icons-minor-mode-base-text-properties)))) - (split-string (format-mode-line minor-mode-alist))))))) - -(defun mode-icons--generate-narrow (&optional face) - "Extracts all rich strings necessary for narrow indicator. -When FACE is non-nil, use FACE to render the narrow indicator." - (let* ((active (mode-icons--selected-window-active)) - (face (mode-icons--get-face active face)) - icon-spec) - (delete " " (delete "" (mapcar (lambda(mode) - (concat " " (eval `(propertize - ,(if (setq icon-spec (mode-icons-get-icon-spec (concat " " mode))) - (mode-icons--recolor-minor-mode-image - (mode-icons-propertize-mode (concat " " mode) icon-spec face active) - active face) - mode) - ,@mode-icons-narrow-text-properties)))) - (split-string (format-mode-line "%n"))))))) - - -(defcustom mode-icons-read-only-space t - "Add Space after read-only icon." - :type 'boolean - :group 'mode-icons) - -(defun mode-icons--read-only-status (&optional face) - "Get Read Only Status icon. -FACE is the face to render the icon in." - (let ((active (mode-icons--selected-window-active))) - (eval `(propertize - ,(let ((ro (format-mode-line "%1*")) - icon-spec) - (setq ro (or (cond - ((string= "%" ro) - (if (setq icon-spec (mode-icons-get-icon-spec 'read-only)) - (mode-icons-propertize-mode 'read-only icon-spec face active) - ro)) - (t - (if (setq icon-spec (mode-icons-get-icon-spec 'writable)) - (mode-icons-propertize-mode 'writable icon-spec face active) - ro))) - "") - ro (mode-icons--recolor-minor-mode-image ro active face)) - (when (and mode-icons-read-only-space - (not (string= ro ""))) - (setq ro (concat ro " "))) - ro) - ,@mode-icons-read-only-text-properties)))) - -(defcustom mode-icons-modified-status-space t - "Add Space to modified status." - :type 'boolean - :group 'mode-icons) - -(defun mode-icons--modified-status (&optional face) - "Get modified status icon. -FACE is the face to render the icon in." - (let ((active (mode-icons--selected-window-active))) - (eval `(propertize - ,(or (ignore-errors - (let* ((bfn (buffer-file-name)) - (nice-file-p (and (file-remote-p bfn))) - (mod (or (and (not (or nice-file-p (verify-visited-file-modtime (current-buffer)))) - "!") - (and (not (or nice-file-p (member (file-locked-p bfn) '(nil t)))) - "s") - (format-mode-line "%1+"))) - icon-spec) - (setq mod (or (cond - ((not (stringp mod)) "") - ((char-equal ?s (aref mod 0)) - (if (setq icon-spec (mode-icons-get-icon-spec 'steal)) - (mode-icons-propertize-mode 'steal icon-spec face active) - mod)) - ((char-equal ?! (aref mod 0)) - (if (setq icon-spec (mode-icons-get-icon-spec 'modified-outside)) - (mode-icons-propertize-mode 'modified-outside icon-spec face active) - mod)) - ((char-equal ?* (aref mod 0)) - (if (setq icon-spec (mode-icons-get-icon-spec 'save)) - (mode-icons-propertize-mode 'save icon-spec face active) - mod)) - (t - (if (setq icon-spec (mode-icons-get-icon-spec 'saved)) - (mode-icons-propertize-mode 'saved icon-spec face active) - mod))) - "")) - (setq mod (mode-icons--recolor-minor-mode-image mod active face)) - (when (and mode-icons-modified-status-space - (stringp mod) - (not (string= mod ""))) - (setq mod (concat mod " "))) - mod)) "") - ,@mode-icons-modified-text-properties)))) - -;; Based on rich-minority by Artur Malabarba -(defvar mode-icons--backup-construct nil) -(defvar mode-icons--mode-line-construct - '(:eval (mode-icons--generate-minor-mode-list)) - "Construct used to replace `minor-mode-alist'.") - -(defvar mode-icons--major-backup-construct nil) -(defvar mode-icons--major-construct - '(:eval (mode-icons--generate-major-mode-item)) - "Construct used to replace `mode-name'.") - -(defvar mode-icons--narrow-backup-construct nil) -(defvar mode-icons--narrow-construct - '(:eval (mode-icons--generate-narrow)) - "Construct used to replace %n in `mode-line-modes'.") - - -(defvar mode-icons--read-only-backup-construct nil) -(defvar mode-icons--read-only-construct - '(:eval (mode-icons--read-only-status)) - "Construct used to replace %1* in `mode-line-modified'.") - - -(defvar mode-icons--modified-backup-construct nil) -(defvar mode-icons--modified-construct - '(:eval (mode-icons--modified-status)) - "Construct used to replace %1+ in `mode-line-modified'.") - -(defvar mode-icons--backup-eol-construct nil) -(defvar mode-icons--eol-construct - '(:eval (mode-icons--mode-line-eol-desc)) - "End of Line Construct.") - -(defcustom mode-icons-eol-space t - "Add a space to the end of line specification." - :type 'boolean - :group 'mode-icons) - -(defcustom mode-icons-eol-text nil - "Describe end of line type. -\(Unix) -> LF -\(DOS) -> CRLF -\(Mac) -> CR" - :type 'boolean - :group 'mode-icons) - -(defun mode-icons--mode-line-eol-desc (&optional string face) - "Modify `mode-line-eol-desc' to have icons. - -STRING is the string to modify, or if absent, the value from -`mode-line-eol-desc'. - -FACE is the face that will be used to render the segment." - (let* ((str (or string (mode-line-eol-desc))) - (props (text-properties-at 0 str)) - (lt2 "") - (active (mode-icons--selected-window-active)) - icon-spec) - (setq str (or (cond - ((string= "(Unix)" str) - (setq lt2 " LF") - (if (setq icon-spec (mode-icons-get-icon-spec 'unix)) - (mode-icons-propertize-mode 'unix icon-spec face active) - str)) - ((or (string= str "(DOS)") - (string= str "\\")) - (setq lt2 " CRLF") - (if (setq icon-spec (mode-icons-get-icon-spec 'win)) - (mode-icons-propertize-mode 'win icon-spec face active) - str)) - ((string= str "(Mac)") - (setq lt2 " CR") - (if (setq icon-spec (mode-icons-get-icon-spec 'apple)) - (mode-icons-propertize-mode 'apple icon-spec face active) - str)) - ((string= str ":") - (setq lt2 " Undecided") - (if (setq icon-spec (mode-icons-get-icon-spec 'undecided)) - (mode-icons-propertize-mode 'undecided icon-spec face active) - str)) - (t str)) - "")) - (setq str (mode-icons--recolor-minor-mode-image str active face)) - (when mode-icons-eol-text - (setq str (concat str lt2))) - (when (and mode-icons-eol-space - (not (string= "" str))) - (setq str (concat str " "))) - (add-text-properties 0 (length str) props str) - str)) - - -(defun mode-icons-fix (&optional enable) - "Fix mode-icons. -When ENABLE is non-nil, enable the changes to the mode line." - (if enable - (let ((place (or (member 'minor-mode-alist mode-line-modes) - (cl-member-if - (lambda (x) (and (listp x) - (equal (car x) :propertize) - (equal (cadr x) '("" minor-mode-alist)))) - mode-line-modes))) - (place-major (cl-member-if - (lambda(x) - (and (listp x) - (equal (car x) :propertize) - (equal (cadr x) '("" mode-name)))) - mode-line-modes)) - (place-narrow (cl-member-if - (lambda(x) - (and (stringp x) (string= "%n" x))) - mode-line-modes)) - (place-ro (cl-member-if - (lambda(x) - (and (stringp x) (string-match-p "%[0-9]*[*]" x))) - mode-line-modified)) - (place-mod (cl-member-if - (lambda(x) - (and (stringp x) (string-match-p "%[0-9]*[+]" x))) - mode-line-modified)) - (place-eol (cl-member-if - (lambda(x) - (and (listp x) - (equal (car x) :eval) - (eq (cl-caadr x) 'mode-line-eol-desc))) - mode-line-mule-info))) - (when place - (setq mode-icons--backup-construct (car place)) - (setcar place mode-icons--mode-line-construct)) - (when place-major - (setq mode-icons--major-backup-construct (car place-major)) - (setcar place-major mode-icons--major-construct)) - (when place-narrow - (setq mode-icons--narrow-backup-construct (car place-narrow)) - (setcar place-narrow mode-icons--narrow-construct)) - (when place-ro - (setq mode-icons--read-only-backup-construct (car place-ro)) - (setcar place-ro mode-icons--read-only-construct)) - (when place-mod - (setq mode-icons--modified-backup-construct (car place-mod)) - (setcar place-mod mode-icons--modified-construct)) - (when place-eol - (setq mode-icons--backup-eol-construct (car place-eol)) - (setcar place-eol mode-icons--eol-construct))) - (let ((place (member mode-icons--mode-line-construct mode-line-modes)) - (place-major (member mode-icons--major-construct mode-line-modes)) - (place-narrow (member mode-icons--narrow-construct mode-line-modes)) - (place-ro (member mode-icons--read-only-construct mode-line-modified)) - (place-mod (member mode-icons--modified-construct mode-line-modified)) - (place-eol (member mode-icons--eol-construct mode-line-mule-info))) - (when place - (setcar place mode-icons--backup-construct)) - (when place-major - (setcar place-major mode-icons--major-backup-construct)) - (when place-narrow - (setcar place-narrow mode-icons--narrow-backup-construct)) - (when place-ro - (setcar place-ro mode-icons--read-only-backup-construct)) - (when place-mod - (setcar place-mod mode-icons--modified-backup-construct)) - (when place-eol - (setcar place-eol mode-icons--backup-eol-construct))))) - -;;;###autoload -(define-minor-mode mode-icons-mode - "Replace the name of the current major mode with an icon." - :global t - (if mode-icons-mode - (progn - (add-hook 'after-change-major-mode-hook #'mode-icons-reset) - (mode-icons-fix t) - (mode-icons-set-minor-mode-icon) - (mode-icons-major-mode-icons)) - (remove-hook 'after-change-major-mode-hook #'mode-icons-reset) - (mode-icons-set-minor-mode-icon-undo) - (mode-icons-major-mode-icons-undo) - (mode-icons-fix))) - -(defun mode-icons-reset-hash () - "Reset `mode-icons-get-icon-spec' and `mode-icons-get-icon-display'." - (interactive) - (setq mode-icons-get-icon-spec (make-hash-table :test 'equal) - mode-icons-get-icon-display (make-hash-table :test 'equal))) - -(defun mode-icons-reset () - "Reset mode-icons icons." - (interactive) - (when (and mode-icons-mode (not (minibufferp))) - ;; Reset the major mode now. - (mode-icons-set-current-mode-icon) - ;; Reset the minor mode later, in case the mode turns on some - ;; minor-modes. - (run-with-idle-timer - 0.1 nil `(lambda() - ;; Reset the minor mode icons - (when (buffer-live-p ,(current-buffer)) - (with-current-buffer ,(current-buffer) - (mode-icons-set-minor-mode-icon))))))) - -(add-hook 'emacs-startup-hook #'mode-icons-reset) - -(defadvice isearch-mode (after mode-icons--reset-isearch-icon activate) - "Make `mode-icons' aware of icon." - (mode-icons-set-minor-mode-icon)) - -(eval-after-load 'powerline - '(progn - (declare-function mode-icons--real-powerline-minor-modes "powerline") - (fset 'mode-icons--real-powerline-minor-modes #'powerline-minor-modes) - (defun mode-icons--powerline-minor-modes (&optional face pad) - "Powerline minor modes is replaced by this function. -FACE is the face to use. -PAD is the padding around the minor modes. - -The original is called if `mode-icons-mode' is disabled. It is -saved in `mode-icons--real-powerline-minor-modes'." - (if mode-icons-mode - (mode-icons--generate-minor-mode-list face) - (mode-icons--real-powerline-minor-modes face pad))) - (fset 'mode-icons--real-powerline-major-mode #'powerline-minor-modes) - (defun mode-icons--powerline-major-mode (&optional face pad) - "Powerline major modes is replaced by this function. -FACE is the face to use. -PAD is the padding around the minor modes. - -The original is called if `mode-icons-mode' is disabled. It is -saved in `mode-icons--real-powerline-major-mode'." - (if mode-icons-mode - (powerline-raw (format-mode-line (mode-icons--generate-major-mode-item face) face) face pad) - (mode-icons--real-powerline-major-mode face pad))) - (fset 'powerline-major-mode #'mode-icons--powerline-major-mode) - (fset 'mode-icons--real-powerline-raw #'powerline-raw) - (defun mode-icons--powerline-raw (str &optional face pad) - "Render STR as mode-line data using FACE and optionally PAD import on left (l) or right (r). -This uses `mode-icons--recolor-string' when `mode-icons-mode' is enabled." - (if mode-icons-mode - (when str - (let* ((rendered-str (format-mode-line str)) - (padded-str (concat - (when (and (> (length rendered-str) 0) (eq pad 'l)) " ") - (if (listp str) rendered-str str) - (when (and (> (length rendered-str) 0) (eq pad 'r)) " ")))) - (if face - (mode-icons--recolor-string (pl/add-text-property padded-str 'face face) - (mode-icons--selected-window-active) face) - padded-str))) - (mode-icons--real-powerline-raw str face pad))) - (fset 'powerline-raw #'mode-icons--powerline-raw))) - - -(eval-after-load 'emojify - '(progn - (mode-icons-reset-hash))) - -(provide 'mode-icons) -;;; mode-icons.el ends here -;; Local Variables: -;; indent-tabs-mode: nil -;; End: |