fix icons path invalid issue
[major-mode-icons.git] / major-mode-icons.el
blobce80de5cfd0d18d75f92ae6749a10c244c94a80f
1 ;;; major-mode-icons.el --- display icon for major-mode on mode-line.
3 ;;; Commentary:
5 ;; Authors: stardiviner <numbchild@gmail.com>
6 ;; Package-Requires: ((emacs "25.1") (cl-lib "0.5"))
7 ;; Version: 0.1
8 ;; Keywords: frames multimedia
9 ;; homepage: http://github.com/stardiviner/major-mode-icons
11 ;; You should have received a copy of the GNU General Public License
12 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
15 ;;; Code:
16 ;;; ----------------------------------------------------------------------------
18 (require 'cl-lib)
19 (require 'cl-extra)
20 (require 'map) ; `map-keys'
22 (defgroup major-mode-icons nil
23 "Show icon for current buffer's major-mode."
24 :group 'mode-line)
26 (defconst major-mode-icons--icons-default-path
27 (concat
28 (file-name-directory (or load-file-name
29 (buffer-file-name)))
30 "icons/")
31 "Default icons path of major-mode-icons.")
33 (defcustom major-mode-icons--icons-path major-mode-icons--icons-default-path
34 "Path to icons."
35 :group 'major-mode-icons
36 :type 'string)
38 (defcustom major-mode-icons--mode-name-font "Segoe Print"
39 "The font family used for major mode name."
40 :group 'major-mode-icons)
43 ;;; separate settings for only active mode-line.
45 (defvar major-mode-icons--mode-line-selected-window nil)
47 (defun major-mode-icons--mode-line-record-selected-window ()
48 "Record the current selected window."
49 (setq major-mode-icons--mode-line-selected-window (selected-window)))
51 (defun major-mode-icons--mode-line-update-all ()
52 "Force update mode-line."
53 (force-mode-line-update t))
55 (add-hook 'post-command-hook 'major-mode-icons--mode-line-record-selected-window)
57 (add-hook 'buffer-list-update-hook 'major-mode-icons--mode-line-update-all)
59 (defun major-mode-icons--active ()
60 "Detect whether current window is the selected window."
61 (eq major-mode-icons--mode-line-selected-window (selected-window)))
64 ;; major mode with icon
65 (defvar major-mode-icons--major-mode-list
66 '(((emacs-lisp-mode
67 inferior-emacs-lisp-mode
68 ielm-mode) . ("Elisp" "Emacs"))
69 ((lisp-mode
70 inferior-lisp-mode
71 slime-repl-mode sly-mrepl-mode) . ("Lisp" "Common-Lisp"))
72 ((scheme-mode) . ("Scheme" "Scheme"))
73 ((clojure-mode
74 cider-repl-mode) . ("Clojure" "Clojure"))
75 ((clojurescript-mode) . ("ClojureScript" "ClojureScript"))
76 ((python-mode) . ("Python" "Python"))
77 ((enh-ruby-mode ruby-mode) . ("Ruby" "Ruby"))
78 ((inf-ruby-mode) . ("Inf-Ruby" "inf-ruby"))
79 ((c-mode) . ("C" "C"))
80 ((c++-mode) . ("C++" "C++"))
81 ((csharp-mode) . ("C#" "C#"))
82 ((go-mode) . ("Go" "Go"))
83 ((swift-mode) . ("Swift" "Swift"))
84 ((rust-mode) . ("Rust" "Rust"))
85 ((java-mode) . ("Java" "Java"))
86 ((php-mode) . ("PHP" "PHP"))
87 ((web-mode html-mode) . ("HTML" "HTML"))
88 ((css-mode) . ("CSS" "CSS"))
89 ((javascript-mode
90 js-mode js2-mode js3-mode inferior-js-mode) . ("JavaScript" "JavaScript"))
91 ((coffee-mode) . ("CoffeeScript" "CoffeeScript"))
92 ((org-mode) . ("Org" "Org-mode"))
93 ((tex-mode latex-mode TeX-mode LaTeX-mode) . ("TeX/LaTeX" "TeX"))
94 ((bibtex-mode) . ("BibTeX" "BibTeX"))
95 ((markdown-mode) . ("Markdown" "Markdown"))
96 ((yaml-mode) . ("YAML" "YAML"))
97 ((rst-mode) . ("reStructuredText" "reStructuredText"))
98 ((eshell-mode) . ("Shell" "Command-Line"))
99 ((sh-mode shell-mode) . ("Shell Script" "Shell"))
100 ((term-mode) . ("Terminal" "term"))
101 ((powershell-mode) . ("PowerShell" "powershell"))
102 ((ess-mode R-mode) . ("R" "R"))
103 ((julia-mode ess-julia-mode) . ("Julia" "Julia"))
104 ((gnuplot-mode) . ("gnuplot" "gnuplot"))
105 ((octave-mode) . ("Octave" "Octave"))
106 ((matlab-mode) . ("Matlab" "Matlab"))
107 ((haskell-mode) . ("Haskell" "Haskell"))
108 ((scala-mode) . ("Scala" "Scala"))
109 ((erlang-mode) . ("Erlang" "Erlang"))
110 ((prolog-mode) . ("Prolog" "Prolog"))
111 ((ocaml-mode) . ("OCaml" "OCaml"))
112 ((sql-mode) . ("SQL" "SQL"))
113 ((xml-mode nxml-mode) . ("XML" "XML"))
114 ((json-mode) . ("JSON" "JSON"))
115 ((diff-mode ediff-mode magit-diff-mode) . ("diff" "diff"))
116 ((asm-mode nasm-mode) . ("Assembly" "Assembly"))
117 ((android-mode) . ("Android" "Android"))
118 ((qt-mode) . ("Qt" "Qt"))
119 ((arduino-mode) . ("Arduino" "Arduino"))
120 ((systemd-mode) . ("Systemd" "Systemd"))
121 ((docker-mode) . ("Docker" "Docker"))
122 ((projectile-rails-mode) . ("Rails" "Rails"))
123 ((slim-mode) . ("Slim" "Slim"))
124 ((sass-mode) . ("Sass" "Sass"))
125 ((spice-mode) . ("SPICE" "Electric"))
127 "Pairs: ([mode-list] . ([name] [icon-name]))."
130 (defun major-mode-icons--major-mode-list-match ()
131 "Return the matched item in `major-mode-list'."
132 (assoc
133 (cl-some ; or use (remove nil '(nil nil (clojure-mode) nil nil ...))
134 (lambda (elem)
135 (when (not (null elem))
136 elem))
137 (mapcar
138 (lambda (element)
139 (member major-mode element))
140 (map-keys major-mode-icons--major-mode-list)))
141 major-mode-icons--major-mode-list))
144 (defun major-mode-icons--major-mode-icon (&optional extra)
145 "Display icon for current buffer's `major-mode' and `EXTRA' info."
146 ;; FIXME: only show icon for first element in major-mode alist.
147 (let* ((match (major-mode-icons--major-mode-list-match))
148 (name (or (car (cdr match))
149 ;; return current major-mode as string for `propertize'
150 ;; when not in `major-mode-alist'.
151 mode-name ; mode-name, %m
153 (icon (car (cdr (cdr match)))))
154 (list
155 (propertize
156 (format "%s" name)
157 'face (if (major-mode-icons--active)
158 '(:foreground "cyan" :height 80)
159 'mode-line-inactive)
160 'display
161 (let ((icon-path
162 (concat major-mode-icons--icons-path icon ".xpm")))
163 (if (and (major-mode-icons--active)
164 (file-exists-p icon-path)
165 (image-type-available-p 'xpm))
166 (create-image icon-path 'xpm nil :ascent 'center)))
168 (propertize " ")
169 ;;; extra
170 (if extra
171 (propertize (format "%s" (or extra ""))
172 'face (if (major-mode-icons--active)
173 '(:foreground "DarkGreen")
174 'mode-line-inactive)))
178 ;;; auto show extra info
179 (defun major-mode-icons--major-mode-extra ()
180 "Extend function `major-mode-icon' with extra info."
181 (let ((extra
182 (cl-case major-mode
183 ('clojure-mode
184 (if (not (equal (cider--modeline-info) "not connected"))
185 (cider--project-name nrepl-project-dir)))
186 ('enh-ruby-mode
187 (if global-rbenv-mode
188 (rbenv--active-ruby-version) ; `rbenv--modestring'
190 ('python-mode
191 (if pyvenv-mode
192 ;; `pyvenv-mode-line-indicator' -> `pyvenv-virtual-env-name'
193 pyvenv-virtual-env-name
194 ;; conda: `conda-env-current-name'
196 )))))
198 ;;;###autoload
199 (defun major-mode-icons-show ()
200 "Show icon on mode-line."
201 (major-mode-icons--major-mode-icon (major-mode-icons--major-mode-extra)))
203 ;;;###autoload
204 (define-minor-mode major-mode-icons-mode
205 "A minor mode of showing icon for major-mode of current buffer."
206 :lighter 'major-mode-icons-show
207 :global t)
209 ;;; ----------------------------------------------------------------------------
211 (provide 'major-mode-icons)
213 ;;; major-mode-icons.el ends here