aboutsummaryrefslogtreecommitdiff
path: root/.emacs.d/rul-lisp/packages/rul-modeline.el
blob: ae250c4b5775762685ebc043b993d4bee7594f2d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
;; Most of the code in this file is based on:
;;   https://git.sr.ht/~protesilaos/dotfiles/tree/cf26bc34/item/emacs/.emacs.d/prot-lisp/prot-modeline.el
;;
;; All Kudos to Prot.

;;;; Faces
(defface rul-modeline-indicator-red
  '((default :inherit bold)
    (((class color) (min-colors 88) (background light))
     :foreground "#880000")
    (((class color) (min-colors 88) (background dark))
     :foreground "#ff9f9f")
    (t :foreground "red"))
  "Face for modeline indicators.")

;;;; Common helper functions
(defcustom rul-modeline-string-truncate-length 9
  "String length after which truncation should be done in small windows."
  :type 'natnum)

(defun rul-modeline--string-truncate-p (str)
  "Return non-nil if STR should be truncated."
  (and (< (window-total-width) split-width-threshold)
       (> (length str) rul-modeline-string-truncate-length)
       (not (one-window-p :no-minibuffer))))

(defun rul-modeline-string-truncate (str)
  "Return truncated STR, if appropriate, else return STR.
Truncation is done up to `rul-modeline-string-truncate-length'."
  (if (rul-modeline--string-truncate-p str)
      (concat (substring str 0 rul-modeline-string-truncate-length) "...")
    str))

;;;; Major mode
(defun rul-modeline-major-mode-indicator ()
  "Return appropriate propertized mode line indicator for the major mode."
  (let ((indicator (cond
                    ((derived-mode-p 'text-mode) "§")
                    ((derived-mode-p 'prog-mode) "λ")
                    ((derived-mode-p 'comint-mode) ">_")
                    (t "◦"))))
    (propertize indicator 'face 'shadow)))

(defun rul-modeline-major-mode-name ()
  "Return capitalized `major-mode' without the -mode suffix."
  (capitalize (string-replace "-mode" "" (symbol-name major-mode))))

(defun rul-modeline-major-mode-help-echo ()
  "Return `help-echo' value for `rul-modeline-major-mode'."
  (if-let ((parent (get major-mode 'derived-mode-parent)))
      (format "Symbol: `%s'.  Derived from: `%s'" major-mode parent)
    (format "Symbol: `%s'." major-mode)))

(defvar-local rul-modeline-major-mode
    (list
     (propertize "%[" 'face 'rul-modeline-indicator-red)
     '(:eval
       (concat
        (rul-modeline-major-mode-indicator)
        " "
        (propertize
         (rul-modeline-string-truncate
          (rul-modeline-major-mode-name))
         'mouse-face 'mode-line-highlight
         'help-echo (rul-modeline-major-mode-help-echo))))
     (propertize "%]" 'face 'rul-modeline-indicator-red))
  "Mode line construct for displaying major modes.")

(with-eval-after-load 'eglot
  (setq mode-line-misc-info
        (delete '(eglot--managed-mode (" [" eglot--mode-line-format "] ")) mode-line-misc-info)))

(defvar-local prot-modeline-eglot
    `(:eval
      (when (and (featurep 'eglot) (mode-line-window-selected-p))
        '(eglot--managed-mode eglot--mode-line-format)))
  "Mode line construct displaying Eglot information.
Specific to the current window's mode line.")

;;;; Miscellaneous
(defvar-local rul-modeline-misc-info
    '(:eval
      (when (mode-line-window-selected-p)
        mode-line-misc-info))
  "Mode line construct displaying `mode-line-misc-info'.
Specific to the current window's mode line.")

;;;; Display current time
(setq display-time-format " %a %e %b, %H:%M ")
(setq display-time-default-load-average nil)
(setq display-time-mail-string "")

;;;; Variables used in the modeline need to be in `risky-local-variable'.
(dolist (construct '(
                     rul-modeline-major-mode
                     rul-modeline-misc-info
                     ))
  (put construct 'risky-local-variable t))

;;;; Finally, define the modeline format
(setq-default mode-line-format
              '("%e"
                mode-line-front-space
                mode-line-buffer-identification
                mode-line-front-space
                rul-modeline-major-mode
                prot-modeline-eglot
                mode-line-format-right-align
                rul-modeline-misc-info
                ))

(provide 'rul-modeline)
nihil fit ex nihilo