diff options
author | Case Duckworth | 2022-10-17 21:41:28 -0500 |
---|---|---|
committer | Case Duckworth | 2022-10-17 21:41:28 -0500 |
commit | aab5bfd074e57d06a79e39d7c7c4760e1f385a06 (patch) | |
tree | 7b111190a44458a970355f7a327cc5278c850293 /lisp/+modeline.el | |
parent | asoi (diff) | |
download | emacs-aab5bfd074e57d06a79e39d7c7c4760e1f385a06.tar.gz emacs-aab5bfd074e57d06a79e39d7c7c4760e1f385a06.zip |
Bankruptcy 9
Diffstat (limited to 'lisp/+modeline.el')
-rw-r--r-- | lisp/+modeline.el | 488 |
1 files changed, 0 insertions, 488 deletions
diff --git a/lisp/+modeline.el b/lisp/+modeline.el deleted file mode 100644 index c6e8463..0000000 --- a/lisp/+modeline.el +++ /dev/null | |||
@@ -1,488 +0,0 @@ | |||
1 | ;;; +modeline.el --- my modeline customizations -*- lexical-binding: t; -*- | ||
2 | |||
3 | ;;; Commentary: | ||
4 | |||
5 | ;; `+modeline.el' is kind of a dumping ground for various | ||
6 | ;; modeline-related functions. I probably don't use everything in | ||
7 | ;; here. Credit given where possible. | ||
8 | |||
9 | ;;; Code: | ||
10 | |||
11 | (require '+util) | ||
12 | (require 'actually-selected-window) | ||
13 | (require 'simple-modeline) | ||
14 | (require 'minions) | ||
15 | |||
16 | (defgroup +modeline nil | ||
17 | "Various customization options for my modeline things." | ||
18 | :prefix "+modeline-" | ||
19 | :group 'simple-modeline) | ||
20 | |||
21 | (defcustom +modeline-default-spacer " " | ||
22 | "Default spacer to use for modeline elements. | ||
23 | All modeline elements take an optional argument, `spacer', which | ||
24 | will default to this string.") | ||
25 | |||
26 | ;;; Combinators | ||
27 | |||
28 | (defun +modeline-concat (segments &optional separator) | ||
29 | "Concatenate multiple functional modeline SEGMENTS. | ||
30 | Each segment in SEGMENTS is a function returning a mode-line | ||
31 | construct. | ||
32 | |||
33 | Segments are separated using SEPARATOR, which defaults to | ||
34 | `+modeline-default-spacer'. Only segments that evaluate to a | ||
35 | non-zero-length string will be separated, for a cleaner look. | ||
36 | |||
37 | This function returns a lambda that should be `:eval'd or | ||
38 | `funcall'd in a mode-line context." | ||
39 | (let ((separator (or separator +modeline-default-spacer))) | ||
40 | (lambda () | ||
41 | (let (this-sep result) | ||
42 | (dolist (segment segments) | ||
43 | (let ((segstr (funcall segment this-sep))) | ||
44 | (when (and segstr | ||
45 | (not (equal segstr ""))) | ||
46 | (push segstr result) | ||
47 | (setq this-sep separator)))) | ||
48 | (apply #'concat | ||
49 | (nreverse result)))))) | ||
50 | |||
51 | (defun +modeline-spacer (&optional n spacer &rest strings) | ||
52 | "Make an N-length SPACER, or prepend SPACER to STRINGS. | ||
53 | When called with no arguments, insert `+modeline-default-spacer'. | ||
54 | N will repeat SPACER N times, and defaults to 1. SPACER defaults | ||
55 | to `+modeline-default-spacer', but can be any string. STRINGS | ||
56 | should form a mode-line construct when `concat'ed." | ||
57 | (declare (indent 2)) | ||
58 | (let ((spacer (or spacer +modeline-default-spacer)) | ||
59 | (n (or n 1)) | ||
60 | (strings (cond((null strings) '("")) | ||
61 | ((equal strings '("")) nil) | ||
62 | ((atom strings) (list strings)) | ||
63 | (t strings))) | ||
64 | r) | ||
65 | (when strings (dotimes (_ n) (push spacer r))) | ||
66 | (apply #'concat (apply #'concat r) strings))) | ||
67 | |||
68 | ;;; Modeline segments | ||
69 | |||
70 | (defun +modeline-sanitize-string (string) | ||
71 | "Sanitize a string for `format-mode-line'." | ||
72 | (when string | ||
73 | (string-replace "%" "%%" string))) | ||
74 | |||
75 | (defcustom +modeline-buffer-name-max-length 0 | ||
76 | "Maximum length of `+modeline-buffer-name'. | ||
77 | If > 0 and < 1, use that portion of the window's width. If > 1, | ||
78 | use that many characters. If anything else, don't limit. If the | ||
79 | buffer name is longer than the max length, it will be shortened | ||
80 | and appended with `truncate-string-ellipsis'." | ||
81 | :type '(choice (const :tag "No maximum length" 0) | ||
82 | (natnum :tag "Number of characters") | ||
83 | (float :tag "Fraction of window's width"))) | ||
84 | |||
85 | (defcustom +modeline-buffer-position nil | ||
86 | "What to put in the `+modeline-buffer-name' position." | ||
87 | :type 'function | ||
88 | :local t) | ||
89 | |||
90 | (defun +modeline-buffer-name (&optional spacer) ; gonsie | ||
91 | "Display the buffer name." | ||
92 | (let ((bufname (string-trim (string-replace "%" "%%%%" (buffer-name))))) | ||
93 | (+modeline-spacer nil spacer | ||
94 | (if (and +modeline-buffer-position (fboundp +modeline-buffer-position)) | ||
95 | (funcall +modeline-buffer-position) | ||
96 | (propertize (cond | ||
97 | ((ignore-errors | ||
98 | (and | ||
99 | (> +modeline-buffer-name-max-length 0) | ||
100 | (< +modeline-buffer-name-max-length 1))) | ||
101 | (truncate-string-to-width bufname | ||
102 | (* (window-total-width) | ||
103 | +modeline-buffer-name-max-length) | ||
104 | nil nil t)) | ||
105 | ((ignore-errors | ||
106 | (> +modeline-buffer-name-max-length 1)) | ||
107 | (truncate-string-to-width bufname | ||
108 | +modeline-buffer-name-max-length | ||
109 | nil nil t)) | ||
110 | (t bufname)) | ||
111 | 'help-echo (or (buffer-file-name) | ||
112 | (buffer-name)) | ||
113 | 'mouse-face 'mode-line-highlight))))) | ||
114 | |||
115 | (defcustom +modeline-minions-icon "&" | ||
116 | "The \"icon\" for `+modeline-minions' button." | ||
117 | :type 'string) | ||
118 | |||
119 | (defun +modeline-minions (&optional spacer) | ||
120 | "Display a button for `minions-minor-modes-menu'." | ||
121 | (+modeline-spacer nil spacer | ||
122 | (propertize | ||
123 | +modeline-minions-icon | ||
124 | 'help-echo "Minor modes menu\nmouse-1: show menu." | ||
125 | 'local-map (purecopy (simple-modeline-make-mouse-map | ||
126 | 'mouse-1 | ||
127 | (lambda (event) | ||
128 | (interactive "e") | ||
129 | (with-selected-window | ||
130 | (posn-window (event-start event)) | ||
131 | (minions-minor-modes-menu))))) | ||
132 | 'mouse-face 'mode-line-highlight))) | ||
133 | |||
134 | (defcustom +modeline-major-mode-faces '((text-mode . font-lock-string-face) | ||
135 | (prog-mode . font-lock-keyword-face) | ||
136 | (t . font-lock-warning-face)) | ||
137 | "Mode->face mapping for `+modeline-major-mode'. | ||
138 | If the current mode is derived from the car of a cell, the face | ||
139 | in the cdr will be applied to the major-mode in the mode line." | ||
140 | :type '(alist :key-type function | ||
141 | :value-type face)) | ||
142 | |||
143 | (defface +modeline-major-mode-face nil | ||
144 | "Face for modeline major-mode.") | ||
145 | |||
146 | (defun +modeline-major-mode (&optional spacer) | ||
147 | "Display the current `major-mode'." | ||
148 | (+modeline-spacer nil spacer | ||
149 | "(" | ||
150 | (propertize ;; (+string-truncate (format-mode-line mode-name) 16) | ||
151 | (format-mode-line mode-name) | ||
152 | 'face (when (actually-selected-window-p) | ||
153 | ;; XXX: This is probably really inefficient. I need to | ||
154 | ;; simply detect which mode it's in when I change major | ||
155 | ;; modes (`change-major-mode-hook') and change the face | ||
156 | ;; there, probably. | ||
157 | ;; (catch :done (dolist (cel +modeline-major-mode-faces) | ||
158 | ;; (when (derived-mode-p (car cel)) | ||
159 | ;; (throw :done (cdr cel)))) | ||
160 | ;; (alist-get t +modeline-major-mode-faces)) | ||
161 | '+modeline-major-mode-face) | ||
162 | 'keymap (let ((map (make-sparse-keymap))) | ||
163 | (bindings--define-key map [mode-line down-mouse-1] | ||
164 | `(menu-item "Menu Bar" ignore | ||
165 | :filter ,(lambda (_) (mouse-menu-major-mode-map)))) | ||
166 | (define-key map [mode-line mouse-2] 'describe-mode) | ||
167 | (bindings--define-key map [mode-line down-mouse-3] | ||
168 | `(menu-item "Minions" minions-minor-modes-menu)) | ||
169 | map) | ||
170 | 'help-echo (+concat (list (format-mode-line mode-name) " mode") | ||
171 | "mouse-1: show menu" | ||
172 | "mouse-2: describe mode" | ||
173 | "mouse-3: display minor modes") | ||
174 | 'mouse-face 'mode-line-highlight) | ||
175 | ")")) | ||
176 | |||
177 | (defcustom +modeline-modified-icon-alist '((ephemeral . "*") | ||
178 | (readonly . "=") | ||
179 | (modified . "+") | ||
180 | (special . "~") | ||
181 | (t . "-")) | ||
182 | "\"Icons\" to display depending on buffer status in modeline. | ||
183 | The CAR of each field is one of `readonly', `modified', | ||
184 | `special', `ephemeral', or t, and the CDR is a string to display | ||
185 | in that mode. | ||
186 | |||
187 | `readonly' is true if the buffer is read-only and visiting a file. | ||
188 | `modified' is true if the buffer is modified. | ||
189 | `special' is true if the buffer is a special-mode or derived buffer. | ||
190 | `ephemeral' is true if the buffer is not visiting a file. | ||
191 | t is the fall-back, shown when nothing else in the alist applies. | ||
192 | |||
193 | The order of elements matters: whichever one matches first is applied." | ||
194 | :type '(alist :key-type symbol | ||
195 | :value-type string) | ||
196 | :options '("readonly" "modified" "special" "t")) | ||
197 | |||
198 | (defcustom +modeline-modified-icon-special-modes '(special-mode) | ||
199 | "Modes to apply the `special-mode' icon to in the | ||
200 | `+modeline-modified'." | ||
201 | :type '(repeat function)) | ||
202 | |||
203 | (defun +modeline-modified (&optional spacer) ; modified from `simple-modeline-status-modified' | ||
204 | "Display a color-coded \"icon\" indicator for the buffer's status." | ||
205 | (let* ((icon (catch :icon | ||
206 | (dolist (cell +modeline-modified-icon-alist) | ||
207 | (when (pcase (car cell) | ||
208 | ('ephemeral (not (buffer-file-name))) | ||
209 | ('readonly buffer-read-only) | ||
210 | ('modified (buffer-modified-p)) | ||
211 | ('special | ||
212 | (apply 'derived-mode-p | ||
213 | +modeline-modified-icon-special-modes)) | ||
214 | ('t t) | ||
215 | (_ nil)) | ||
216 | (throw :icon cell)))))) | ||
217 | (+modeline-spacer nil spacer | ||
218 | (propertize (or (cdr-safe icon) "") | ||
219 | 'help-echo (format "Buffer \"%s\" is %s." | ||
220 | (buffer-name) | ||
221 | (pcase (car-safe icon) | ||
222 | ('t "unmodified") | ||
223 | ('nil "unknown") | ||
224 | (_ (car-safe icon)))))))) | ||
225 | |||
226 | (defun +modeline-narrowed (&optional spacer) | ||
227 | "Display an indication that the buffer is narrowed." | ||
228 | (when (buffer-narrowed-p) | ||
229 | (+modeline-spacer nil spacer | ||
230 | (propertize "N" | ||
231 | 'help-echo (format "%s\n%s" | ||
232 | "Buffer is narrowed." | ||
233 | "mouse-2: widen buffer.") | ||
234 | 'local-map (purecopy (simple-modeline-make-mouse-map | ||
235 | 'mouse-2 'mode-line-widen)) | ||
236 | 'face 'font-lock-doc-face | ||
237 | 'mouse-face 'mode-line-highlight)))) | ||
238 | |||
239 | (defun +modeline-reading-mode (&optional spacer) | ||
240 | "Display an indication that the buffer is in `reading-mode'." | ||
241 | (when reading-mode | ||
242 | (+modeline-spacer nil spacer | ||
243 | (propertize | ||
244 | (concat "R" (when (bound-and-true-p +eww-readable-p) "w")) | ||
245 | 'help-echo (format "%s\n%s" | ||
246 | "Buffer is in reading-mode." | ||
247 | "mouse-2: disable reading-mode.") | ||
248 | 'local-map (purecopy | ||
249 | (simple-modeline-make-mouse-map | ||
250 | 'mouse-2 (lambda (ev) | ||
251 | (interactive "e") | ||
252 | (with-selected-window | ||
253 | (posn-window | ||
254 | (event-start ev)) | ||
255 | (reading-mode -1) | ||
256 | (force-mode-line-update))))) | ||
257 | 'face 'font-lock-doc-face | ||
258 | 'mouse-face 'mode-line-highlight)))) | ||
259 | |||
260 | (define-minor-mode file-percentage-mode | ||
261 | "Toggle the percentage display in the mode line (File Percentage Mode)." | ||
262 | :init-value t :global t :group 'mode-line) | ||
263 | |||
264 | (defun +modeline--percentage () | ||
265 | "Return point's progress through current file as a percentage." | ||
266 | (let ((tot (count-screen-lines (point-min) (point-max) :ignore-invisible))) | ||
267 | (floor (* 100 (/ (float (line-number-at-pos)) tot))))) | ||
268 | |||
269 | (defun +modeline--buffer-contained-in-window-p () | ||
270 | "Whether the buffer is totally contained within its window." | ||
271 | (let ((window-min (save-excursion (move-to-window-line 0) (point))) | ||
272 | (window-max (save-excursion (move-to-window-line -1) (point)))) | ||
273 | (and (<= window-min (point-min)) | ||
274 | (>= window-max (point-max))))) | ||
275 | |||
276 | (defun +modeline-file-percentage (&optional spacer) | ||
277 | "Display the position in the current file." | ||
278 | (when file-percentage-mode | ||
279 | ;; (let ((perc (+modeline--percentage))) | ||
280 | ;; (propertize (+modeline-spacer nil spacer | ||
281 | ;; (cond | ||
282 | ;; ((+modeline--buffer-contained-in-window-p) "All") | ||
283 | ;; ((= (line-number-at-pos) (line-number-at-pos (point-min))) "Top") | ||
284 | ;; ((= (line-number-at-pos) (line-number-at-pos (point-max))) "Bot") | ||
285 | ;; ;; Why the 10 %s? Not sure. `format' knocks them | ||
286 | ;; ;; down to 5, then `format-mode-line' kills all but | ||
287 | ;; ;; two. If I use only 8, the margin is much too | ||
288 | ;; ;; large. Something else is obviously going on, but | ||
289 | ;; ;; I'm at a loss as to what it could be. | ||
290 | ;; (t (format "%d%%%%%%%%%%" perc)))) | ||
291 | ;; ;; TODO: add scroll-up and scroll-down bindings. | ||
292 | ;; )) | ||
293 | (let ((perc (format-mode-line '(-2 "%p")))) | ||
294 | (+modeline-spacer nil spacer | ||
295 | "/" | ||
296 | (pcase perc | ||
297 | ("To" "Top") | ||
298 | ("Bo" "Bot") | ||
299 | ("Al" "All") | ||
300 | (_ (format ".%02d" (string-to-number perc)))))))) | ||
301 | |||
302 | (defun +modeline-file-percentage-ascii-icon (&optional spacer) | ||
303 | (when file-percentage-mode | ||
304 | (+modeline-spacer nil spacer | ||
305 | (let ((perc (format-mode-line '(-2 "%p")))) | ||
306 | (pcase perc | ||
307 | ("To" "/\\") | ||
308 | ("Bo" "\\/") | ||
309 | ("Al" "[]") | ||
310 | (_ (let ((vec (vector "/|" "//" "||" "\\\\" "\\|" "\\|")) | ||
311 | (perc (string-to-number perc))) | ||
312 | (aref vec (floor (/ perc 17)))))))))) | ||
313 | |||
314 | (defun +modeline-file-percentage-icon (&optional spacer) | ||
315 | "Display the position in the current file as an icon." | ||
316 | (when file-percentage-mode | ||
317 | (let ((perc (+modeline--percentage))) | ||
318 | (propertize (+modeline-spacer nil spacer | ||
319 | (cond | ||
320 | ((+modeline--buffer-contained-in-window-p) "111") | ||
321 | ((= perc 0) "000") | ||
322 | ((< perc 20) "001") | ||
323 | ((< perc 40) "010") | ||
324 | ((< perc 60) "011") | ||
325 | ((< perc 80) "100") | ||
326 | ((< perc 100) "101") | ||
327 | ((>= perc 100) "110"))) | ||
328 | 'help-echo (format "Point is %d%% through the buffer." | ||
329 | perc))))) | ||
330 | |||
331 | (define-minor-mode region-indicator-mode | ||
332 | "Toggle the region indicator in the mode line." | ||
333 | :init-value t :global t :group 'mode-line) | ||
334 | |||
335 | (defun +modeline-region (&optional spacer) | ||
336 | "Display an indicator if the region is active." | ||
337 | (when (and region-indicator-mode | ||
338 | (region-active-p)) | ||
339 | (+modeline-spacer nil spacer | ||
340 | (propertize (format "%d%s" | ||
341 | (apply '+ (mapcar (lambda (pos) | ||
342 | (- (cdr pos) | ||
343 | (car pos))) | ||
344 | (region-bounds))) | ||
345 | (if (and (< (point) (mark))) "-" "+")) | ||
346 | 'font-lock-face 'font-lock-variable-name-face)))) | ||
347 | |||
348 | (defun +modeline-line (&optional spacer) | ||
349 | (when line-number-mode | ||
350 | (+modeline-spacer nil spacer | ||
351 | "%3l"))) | ||
352 | |||
353 | (defun +modeline-column (&optional spacer) | ||
354 | (when column-number-mode | ||
355 | (+modeline-spacer nil spacer | ||
356 | "|" | ||
357 | (if column-number-indicator-zero-based "%2c" "%2C")))) | ||
358 | |||
359 | (defcustom +modeline-position-function nil | ||
360 | "Function to use instead of `+modeline-position' in modeline." | ||
361 | :type '(choice (const :tag "Default" nil) | ||
362 | function) | ||
363 | :local t) | ||
364 | |||
365 | (defun +modeline-position (&optional spacer) | ||
366 | "Display the current cursor position. | ||
367 | See `line-number-mode', `column-number-mode', and | ||
368 | `file-percentage-mode'. If `+modeline-position-function' is set | ||
369 | to a function in the current buffer, call that function instead." | ||
370 | (cond ((functionp +modeline-position-function) | ||
371 | (when-let* ((str (funcall +modeline-position-function))) | ||
372 | (+modeline-spacer nil spacer str))) | ||
373 | (t (funcall (+modeline-concat '(+modeline-region | ||
374 | +modeline-line | ||
375 | +modeline-column | ||
376 | +modeline-file-percentage) | ||
377 | ""))))) | ||
378 | |||
379 | (defun +modeline-vc (&optional spacer) | ||
380 | "Display the version control branch of the current buffer in the modeline." | ||
381 | ;; from https://www.gonsie.com/blorg/modeline.html, from Doom | ||
382 | (when-let ((backend (vc-backend buffer-file-name))) | ||
383 | (+modeline-spacer nil spacer | ||
384 | (substring vc-mode (+ (if (eq backend 'Hg) 2 3) 2))))) | ||
385 | |||
386 | (defun +modeline-track (&optional spacer) | ||
387 | "Display `tracking-mode' information." | ||
388 | (when tracking-mode | ||
389 | tracking-mode-line-buffers)) | ||
390 | |||
391 | (defun +modeline-anzu (&optional spacer) | ||
392 | "Display `anzu--update-mode-line'." | ||
393 | (+modeline-spacer nil spacer | ||
394 | (anzu--update-mode-line))) | ||
395 | |||
396 | (defun +modeline-text-scale (&optional spacer) | ||
397 | "Display text scaling level." | ||
398 | ;; adapted from https://github.com/seagle0128/doom-modeline | ||
399 | (when (and (boundp 'text-scale-mode-amount) | ||
400 | (/= text-scale-mode-amount 0)) | ||
401 | (+modeline-spacer nil spacer | ||
402 | (concat (if (> text-scale-mode-amount 0) "+" "-") | ||
403 | (number-to-string text-scale-mode-amount))))) | ||
404 | |||
405 | (defun +modeline-ace-window-display (&optional spacer) | ||
406 | "Display `ace-window-display-mode' information in the modeline." | ||
407 | (when (and +ace-window-display-mode | ||
408 | ace-window-mode) | ||
409 | (+modeline-spacer nil spacer | ||
410 | (window-parameter (selected-window) 'ace-window-path)))) | ||
411 | |||
412 | (defun +modeline-god-mode (&optional spacer) | ||
413 | "Display an icon when `god-mode' is active." | ||
414 | (when (and (boundp 'god-local-mode) god-local-mode) | ||
415 | (+modeline-spacer nil spacer | ||
416 | (propertize "Ω" | ||
417 | 'help-echo (concat "God mode is active." | ||
418 | "\nmouse-1: exit God mode.") | ||
419 | 'local-map (purecopy | ||
420 | (simple-modeline-make-mouse-map | ||
421 | 'mouse-1 (lambda (e) | ||
422 | (interactive "e") | ||
423 | (with-selected-window | ||
424 | (posn-window | ||
425 | (event-start e)) | ||
426 | (god-local-mode -1) | ||
427 | (force-mode-line-update))))) | ||
428 | 'mouse-face 'mode-line-highlight)))) | ||
429 | |||
430 | (defun +modeline-input-method (&optional spacer) | ||
431 | "Display which input method is active." | ||
432 | (when current-input-method | ||
433 | (+modeline-spacer nil spacer | ||
434 | (propertize current-input-method-title | ||
435 | 'help-echo (format | ||
436 | (concat "Current input method: %s\n" | ||
437 | "mouse-1: Describe current input method\n" | ||
438 | "mouse-3: Toggle input method") | ||
439 | current-input-method) | ||
440 | 'local-map (purecopy | ||
441 | (let ((map (make-sparse-keymap))) | ||
442 | (define-key map [mode-line mouse-1] | ||
443 | (lambda (e) | ||
444 | (interactive "e") | ||
445 | (with-selected-window (posn-window (event-start e)) | ||
446 | (describe-current-input-method)))) | ||
447 | (define-key map [mode-line mouse-3] | ||
448 | (lambda (e) | ||
449 | (interactive "e") | ||
450 | (with-selected-window (posn-window (event-start e)) | ||
451 | (toggle-input-method nil :interactive)))) | ||
452 | map)) | ||
453 | 'mouse-face 'mode-line-highlight)))) | ||
454 | |||
455 | (defface +modeline-kmacro-indicator '((t :foreground "Firebrick")) | ||
456 | "Face for the kmacro indicator in the modeline.") | ||
457 | |||
458 | (defun +modeline-kmacro-indicator (&optional spacer) | ||
459 | "Display an indicator when recording a kmacro." | ||
460 | (when defining-kbd-macro | ||
461 | (+modeline-spacer nil spacer | ||
462 | (propertize "●" | ||
463 | 'face '+modeline-kmacro-indicator | ||
464 | 'help-echo (format (concat "Defining a macro\n" | ||
465 | "Current step: %d\n" | ||
466 | "mouse-1: Stop recording") | ||
467 | kmacro-counter) | ||
468 | 'local-map (purecopy (simple-modeline-make-mouse-map | ||
469 | 'mouse-1 (lambda (e) | ||
470 | (interactive "e") | ||
471 | (with-selected-window | ||
472 | (posn-window (event-start e)) | ||
473 | (kmacro-end-macro nil))))) | ||
474 | 'mouse-face 'mode-line-highlight)))) | ||
475 | |||
476 | (defface +nyan-mode-line nil | ||
477 | "Face for nyan-cat in mode line.") | ||
478 | |||
479 | (defun +modeline-nyan-on-focused (&optional spacer) | ||
480 | "Display the cat from `nyan-mode', but only on the focused window." | ||
481 | (require 'nyan-mode) | ||
482 | (when (and (or nyan-mode (bound-and-true-p +nyan-local-mode)) | ||
483 | (actually-selected-window-p)) | ||
484 | (+modeline-spacer nil spacer | ||
485 | (propertize (nyan-create) 'face '+nyan-mode-line)))) | ||
486 | |||
487 | (provide '+modeline) | ||
488 | ;;; +modeline.el ends here | ||