├── discobolus.png
├── .editorconfig
├── LICENSE
├── themes
├── myron-grayscale-theme.el
├── myron-theme-template.el
├── myron-storm-theme.el
├── myron-test-theme.el
├── myron-mcfay-theme.el
├── myron-kobo-theme.el
├── myron-whisper-theme.el
├── myron-dogman-theme.el
├── myron-struan-theme.el
└── myron-room-theme.el
├── readme.org
├── myron-themes-cache.el
└── myron-themes.el
/discobolus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neeasade/myron-themes/HEAD/discobolus.png
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 |
7 | [*.el]
8 | indent_size = 2
9 | indent_style = space
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 neeasade
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/themes/myron-grayscale-theme.el:
--------------------------------------------------------------------------------
1 | ;; -*- lexical-binding: t; -*-
2 | ;; inspo: base16-grayscale
3 |
4 | (require 'myron-themes)
5 |
6 | (defun myron-grayscale-colors (background)
7 | "Get the grayscale foreground colors against a specific BACKGROUND."
8 | (->> '(:background 0
9 | :foreground 6
10 | :faded 3
11 | :primary 4
12 | :assumed 5
13 | :alt 3
14 | :strings 4)
15 | (-partition 2)
16 | (-mapcat (-lambda ((label contrast))
17 | (list label (ct-contrast-min background background contrast))))
18 | (ht<-plist)))
19 |
20 | (defun myron-grayscale-create ()
21 | "Create the colors for the grayscale theme."
22 | (-let*
23 | ((background
24 | ;; "#e9e9e9"
25 | "#f3f3f3"
26 | ;; "#f7f7f7"
27 | ;; "#e0e0e0"
28 | ))
29 | (->> '(:focused 3
30 | :weak 4
31 | :strong 7)
32 | (-partition 2)
33 | (-map (-lambda ((label distance))
34 | (list label (ct-change background distance 'ct-edit-lab-l-dec))))
35 | (append `((:normal ,background)))
36 | (-mapcat (-lambda ((label bg)) (list label (myron-grayscale-colors bg))))
37 | (ht<-plist))))
38 |
39 | (deftheme myron-grayscale)
40 | (myron-themes--define 'myron-grayscale)
41 |
42 | (provide-theme 'myron-grayscale)
43 | (provide 'myron-grayscale-theme)
44 | ;;; myron-grayscale-theme.el ends here
45 |
--------------------------------------------------------------------------------
/themes/myron-theme-template.el:
--------------------------------------------------------------------------------
1 | ;; -*- lexical-binding: t; -*-
2 | ;; template the foobar theme
3 |
4 | (require 'myron-themes)
5 |
6 | (defun myron-foobar-colors (background)
7 | "Get the foobar foreground colors against a specific BACKGROUND."
8 | (let* ((colors (->> (ct-make-hsl 240 80 43.596)
9 | (ct-rotation-hsv 5)
10 | (--map (ct-contrast-clamp it background 4.1)))))
11 | (ht<-plist
12 | `(:background ,background
13 | :foreground ,(ct-contrast-min background background 6.0)
14 | :assumed ,(-> (nth 1 colors)
15 | (ct-edit-lch-c 90)
16 | (ct-contrast-max background 2.6))
17 |
18 | ,@(-interleave
19 | '(:primary :faded :alt :strings)
20 | (-select-by-indices '(0 4 3 3) colors))))))
21 |
22 | (defun myron-foobar-create ()
23 | "Create the colors for the foobar theme."
24 | (-let* ((background (ct-make-hsluv 180 100 94))
25 | (background+ (-> (myron-foobar-colors background)
26 | (ht-get :primary)
27 | (ct-edit-lch-c 80)
28 | (ct-steal 'hsluv-l background>))))
29 |
30 | (ht<-plist
31 | (list
32 | :focused (myron-foobar-colors background+)
33 | :normal (myron-foobar-colors background)
34 | :weak (myron-foobar-colors background>)
35 | :strong (myron-foobar-colors background>>)))))
36 |
37 | (deftheme myron-foobar)
38 | (myron-themes--define 'myron-foobar)
39 |
40 | (myron-themes-evil-cursor-color (myron-themes-get :assumed))
41 |
42 | (provide-theme 'myron-foobar)
43 | (provide 'myron-foobar-theme)
44 | ;;; myron-foobar-theme.el ends here
45 |
--------------------------------------------------------------------------------
/themes/myron-storm-theme.el:
--------------------------------------------------------------------------------
1 | ;; -*- lexical-binding: t; -*-
2 | ;; authored during a storm
3 | ;; lower contrast
4 |
5 | (require 'myron-themes)
6 |
7 | (defun myron-storm-colors (bg)
8 | "Get the storm foreground colors against a specific BG."
9 | (let ((fg-ratio 4)
10 | (return (ht)))
11 |
12 | (ht-set return :background bg)
13 | (ht-set return :foreground (ct-contrast-min bg bg fg-ratio))
14 | (ht-set return :faded (ct-contrast-min bg bg (- fg-ratio 1)))
15 |
16 | (->> (ct-rotation-hsluv 6 bg)
17 | (-map (lambda (c)
18 | (ct-iterate c
19 | (-compose 'ct-edit-hsluv-l-dec 'ct-edit-hsluv-s-inc)
20 | (lambda (step) (> (ct-contrast-ratio step bg) fg-ratio)))))
21 | ;; todo: revisit assumed color
22 | (-select-by-indices '(2 1 0 4))
23 | (-interleave '(:primary :assumed :strings :alt))
24 | (-partition 2)
25 | (-map (-lambda ((k v)) (ht-set return k v))))
26 |
27 | return))
28 |
29 | (defun myron-storm-create ()
30 | "Create the colors for the storm theme."
31 | (-let*
32 | ((background (ct-make-lab 94 -5 0))
33 | (background> (ct-change background 5 'ct-edit-hsluv-l-dec))
34 | (background>> (ct-change background 7 'ct-edit-hsluv-l-dec))
35 | (normal-parts (myron-storm-colors background))
36 | ((&hash :alt :assumed :primary :faded :foreground) normal-parts)
37 |
38 | (background+ (ct-edit-hsluv-l primary (ct-get-hsluv-l background>))))
39 |
40 | (ht
41 | (:normal normal-parts)
42 | (:weak (myron-storm-colors background>))
43 | (:strong (myron-storm-colors background>>))
44 | (:focused (myron-storm-colors background+)))))
45 |
46 | (deftheme myron-storm)
47 | (myron-themes--define 'myron-storm)
48 |
49 | (provide-theme 'myron-storm)
50 | (provide 'myron-storm-theme)
51 | ;;; myron-storm-theme.el ends here
52 |
--------------------------------------------------------------------------------
/themes/myron-test-theme.el:
--------------------------------------------------------------------------------
1 | ;; -*- lexical-binding: t; -*-
2 | ;; placeholder for themes being developed
3 |
4 | (require 'myron-themes)
5 |
6 | (defun myron-test-colors (background)
7 | "get the foreground colors against a specific background"
8 | (let* ((colors (-->
9 | (ct-make-hsl 240 80 43.596)
10 |
11 | (ct-rotation-hsv it 72)
12 |
13 | (--map (ct-contrast-clamp it background 4.1) it))))
14 |
15 | (ht<-plist
16 | `(:background ,background
17 | :foreground ,(ct-contrast-min background background 6.0)
18 |
19 | :assumed ,(-> (nth 1 colors)
20 | (ct-edit-lch-c 90)
21 | (ct-contrast-max background 2.6))
22 |
23 | ,@(-interleave
24 | '(:primary :faded :alt :strings)
25 | ;; (-select-by-indices '(0 4 3 2) colors)
26 | ;; what if strings and types were the same color
27 | (-select-by-indices '(0 4 3 3) colors))))))
28 |
29 | (defun myron-test-create ()
30 | (-let*
31 | (
32 | (background (ct-make-hsluv 180 100 94))
33 | ;; (background (ct-make-hsluv 180 100 90))
34 | (normal-parts (myron-test-colors background))
35 | ((&hash :alt :assumed :primary :faded :foreground) normal-parts)
36 | (background> background)
37 | (background>> background)
38 |
39 | (background+
40 | (-> primary
41 | (ct-edit-lch-c 20)
42 | (ct-edit-hsluv-l
43 | (ct-get-hsluv-l background>>)))))
44 |
45 | (ht<-plist
46 | (list
47 | :focused (myron-test-colors background+)
48 | :normal normal-parts
49 | :weak (myron-test-colors background>)
50 | :strong (myron-test-colors background>>)))))
51 |
52 | (deftheme myron-test)
53 | (plist-put myron--cache 'myron-test (myron-test-create))
54 |
55 | (myron-theme-define 'myron-test)
56 |
57 | ;; (myron-evil-cursor-color (myron-get :assumed))
58 |
59 | (provide-theme 'myron-test)
60 | (provide 'myron-test-theme)
61 | ;;; myron-test-theme.el ends here
62 |
--------------------------------------------------------------------------------
/themes/myron-mcfay-theme.el:
--------------------------------------------------------------------------------
1 | ;; -*- lexical-binding: t; -*-
2 | ;; namesake: Jamie McFay, from the James Clavell novel Gai-Jin
3 |
4 | (require 'myron-themes)
5 |
6 | (defun myron-mcfay-colors (background)
7 | "Get the mcfay foreground colors against a specific BACKGROUND."
8 | (let* ((colors (->> (ct-make-hsluv 270 75 43.596)
9 | (ct-rotation-lch -8)
10 | (-select-by-indices '(7 1 2 4))
11 | (-map (lambda (c) (ct-edit-hsluv-l c 43.596)))
12 | (-map (lambda (c) (ct-contrast-min c background 4.3))))))
13 |
14 | (ht
15 | (:background background)
16 | (:foreground (ct-contrast-min background background 7.7))
17 | (:faded (ct-contrast-min background background 4.3))
18 | (:primary (nth 0 colors))
19 | (:assumed (nth 1 colors))
20 | (:alt (nth 2 colors))
21 | (:strings (ct-edit-lch-c (nth 3 colors) 100)))))
22 |
23 | (defun myron-mcfay-create ()
24 | "Create the colors for the mcfay theme."
25 | (-let*
26 | (
27 | ;; /slightly/ cool
28 | (background (ct-make-lab 93 -0.5 -1))
29 | (normal-parts (myron-mcfay-colors background))
30 | ((&hash :alt :assumed :primary :faded :foreground) normal-parts)
31 |
32 | (background> (-> background
33 | (ct-change 4 'ct-edit-lab-l-dec)
34 | (ct-steal 'hsluv-h alt)))
35 |
36 | (background>> (-> background
37 | (ct-change 7 'ct-edit-lab-l-dec)
38 | (ct-steal 'hsluv-h primary)))
39 |
40 | (background+ (-> alt
41 | (ct-edit-lch-c 20)
42 | (ct-steal 'hsluv-l background>>))))
43 |
44 | (ht
45 | (:focused (myron-mcfay-colors background+))
46 | (:normal normal-parts)
47 | (:weak (myron-mcfay-colors background>))
48 | (:strong (myron-mcfay-colors background>>)))))
49 |
50 | (deftheme myron-mcfay)
51 | (myron-themes--define 'myron-mcfay
52 | '((cursor :background alt)))
53 |
54 | (provide-theme 'myron-mcfay)
55 | (provide 'myron-mcfay-theme)
56 | ;;; myron-mcfay-theme.el ends here
57 |
--------------------------------------------------------------------------------
/themes/myron-kobo-theme.el:
--------------------------------------------------------------------------------
1 | ;; -*- lexical-binding: t; -*-
2 | ;; bg and fg inspired by my kobo reader running plato
3 | ;; the hue is to add a tint of spice
4 |
5 | (require 'myron-themes)
6 |
7 | (defun myron-kobo-colors (background hue)
8 | "Get the kobo foreground colors against a specific BACKGROUND."
9 | (->> '(:background 0
10 | :foreground 5.5
11 | :assumed 5.5
12 | :strings 3
13 | :alt 3
14 | :faded 4
15 | :primary 4)
16 | (-partition 2)
17 | (-mapcat (-lambda ((label contrast))
18 | (let ((color (ct-contrast-min background background contrast)))
19 | (if (-contains-p '(:primary :alt :strings) label)
20 | (list label (ct-aedit-hsluv color (list hue 100 l)))
21 | (list label color)))))
22 | (ht<-plist)))
23 |
24 | (defun myron-kobo-create ()
25 | "Create the colors for the kobo theme."
26 | ;; to get this bg I took a pic of my kobo with my phone camera
27 | (-let* ((background "#d7d2cf"
28 | ;; bg fg from camshot of kobo on phone
29 | ;; (ct-contrast-ratio "#d7d2cf" "#4c4d5a")
30 | ;; 5.566905771576383
31 | )
32 | (hue 90))
33 | (->> (list
34 | :normal background
35 |
36 | ;; the unique thing about this theme - a *lighter* weak bg
37 | :weak (ct-change background 1.5 'ct-edit-lab-l-inc)
38 |
39 | ;; torn on whether or not to give focus bg a flare
40 | ;; syncing strong+focused works b/c in practice, focus selection on a strong bg is not used
41 | :strong (ct-change background 3 'ct-edit-lab-l-dec)
42 | :focused (ct-change background 2.5 'ct-edit-lab-l-dec)
43 |
44 | ;; (-> background
45 | ;; (ct-edit-hsluv-h hue)
46 | ;; (ct-edit-hsluv-s 10)
47 | ;; (ct-change 1.5 'ct-edit-lab-l-dec))
48 | )
49 | (-partition 2)
50 | (-mapcat (-lambda ((label bg)) (list label (myron-kobo-colors bg hue))))
51 | (ht<-plist))))
52 |
53 | (deftheme myron-kobo)
54 |
55 | (myron-themes--define 'myron-kobo
56 | '((font-lock-type-face :foreground foreground)
57 | (cursor :background faded)))
58 |
59 | (provide-theme 'myron-kobo)
60 | (provide 'myron-kobo-theme)
61 | ;;; myron-kobo-theme.el ends here
62 |
--------------------------------------------------------------------------------
/themes/myron-whisper-theme.el:
--------------------------------------------------------------------------------
1 | ;; -*- lexical-binding: t; -*-
2 | ;; a soft warm theme
3 |
4 | (require 'myron-themes)
5 |
6 | (defun myron-whisper-colors (background hue)
7 | "Get the whisper foreground colors against a specific BACKGROUND."
8 | (->> '(
9 | ;; :background 0
10 | ;; :foreground 5.5
11 | ;; :assumed 5.5
12 | :foreground 3
13 | :assumed 3
14 | :strings 3
15 | :alt 3
16 | :faded 4
17 | :primary 4
18 | )
19 | (-partition 2)
20 | (-mapcat (-lambda ((label contrast))
21 | (let ((color (ct-contrast-min background background 4.6)))
22 | (if (-contains-p '(:primary :alt :strings) label)
23 | (list label (ct-aedit-lch color (list l 100 hue)))
24 | ;; (list label (ct-aedit-hsluv color (list hue 100 l)))
25 | (list label color)))))
26 | (ht<-plist)
27 | (ht-merge (-ht :background background))))
28 |
29 | (defun myron-whisper-create ()
30 | "Create the colors for the whisper theme."
31 | ;; to get this bg I took a pic of my whisper with my phone camera
32 | (-let* (
33 | (bg-hue 0)
34 |
35 | (background (ct-make-hsv bg-hue 12 100))
36 |
37 | (hue (mod (+ bg-hue 180) 360))
38 | (hue 200)
39 | (hue 190)
40 | )
41 | (->> (list
42 | :normal background
43 |
44 | :weak (ct-change background 1.5 'ct-edit-lab-l-dec)
45 | :strong (ct-change background 3 'ct-edit-lab-l-dec)
46 |
47 | :focused
48 | (->
49 | (ct-change background 3 'ct-edit-lab-l-dec)
50 | (ct-edit-hsluv-s 100)
51 | ;; (ct-edit-lch-h-inc bg-hue)
52 | )
53 |
54 | ;; (-> background
55 | ;; ;; (ct-edit-hsluv-h hue)
56 | ;; (ct-edit-hsluv-s-inc 10)
57 | ;; (ct-change 1.5 'ct-edit-lab-l-dec))
58 | )
59 | (-partition 2)
60 | (-mapcat (-lambda ((label bg)) (list label (myron-whisper-colors bg hue))))
61 | (ht<-plist))))
62 |
63 | (deftheme myron-whisper)
64 |
65 | (myron-themes--define 'myron-whisper
66 | '((font-lock-type-face :foreground foreground)
67 | (cursor :background faded)))
68 |
69 | (provide-theme 'myron-whisper)
70 | (provide 'myron-whisper-theme)
71 | ;;; myron-whisper-theme.el ends here
72 |
--------------------------------------------------------------------------------
/themes/myron-dogman-theme.el:
--------------------------------------------------------------------------------
1 | ;; -*- lexical-binding: t; -*-
2 | ;; named for dogman of the first law series
3 | ;; the main colors of this theme came so naturally, late at night, in an escape
4 | ;; the backgrounds (weak/strong/focused) took more time
5 |
6 | (require 'myron-themes)
7 |
8 | (defun myron-dogman-colors (background)
9 | "Get the dogman foreground colors against a specific BACKGROUND."
10 | (let* ((colors (->> (ct-make-hsl 240 80 43.596)
11 | (ct-rotation-hsv 5)
12 | (--map (ct-contrast-clamp it background 4.1)))))
13 | (ht<-plist
14 | `(:background ,background
15 | :foreground ,(ct-contrast-min background background 6.0)
16 | :assumed ,(-> (nth 1 colors)
17 | (ct-edit-lch-c 90)
18 | (ct-contrast-max background 2.6))
19 |
20 | ,@(-interleave
21 | '(:primary :faded :alt :strings)
22 | ;; (-select-by-indices '(0 4 3 2) colors)
23 | ;; what if strings and types were the same color
24 | (-select-by-indices '(0 4 3 3) colors))))))
25 |
26 | (defun myron-dogman-create ()
27 | "Create the colors for the dogman theme."
28 | (-let* ((background (ct-make-hsluv 180 100 94))
29 | ;; (background "#fdf6e3")
30 | ;; (background (ct-make-hsluv 180 100 90))
31 |
32 | (background> (ct-change background 4
33 | (-compose
34 | 'ct-edit-hsv-v-dec
35 | 'ct-edit-hsv-v-dec
36 | 'ct-edit-lab-a-inc)))
37 |
38 | (background>> (ct-change background> 6
39 | (-compose
40 | 'ct-edit-lab-a-inc
41 | 'ct-edit-lab-b-inc)))
42 |
43 | (background+ (-> (myron-dogman-colors background)
44 | (ht-get :primary)
45 | (ct-edit-lch-c 80)
46 | (ct-steal 'hsluv-l background>))))
47 |
48 | (ht<-plist
49 | (list
50 | :focused (myron-dogman-colors background+)
51 | :normal (myron-dogman-colors background)
52 | :weak (myron-dogman-colors background>)
53 | :strong (myron-dogman-colors background>>)))))
54 |
55 | (deftheme myron-dogman)
56 | (myron-themes--define 'myron-dogman
57 | '((cursor :background assumed)))
58 |
59 | (provide-theme 'myron-dogman)
60 | (provide 'myron-dogman-theme)
61 | ;;; myron-dogman-theme.el ends here
62 |
--------------------------------------------------------------------------------
/themes/myron-struan-theme.el:
--------------------------------------------------------------------------------
1 | ;; -*- lexical-binding: t; -*-
2 | ;; namesake: the Struan family, from James Clavell's Asian Saga series
3 |
4 | (require 'myron-themes)
5 |
6 | (defun myron-struan-colors (background)
7 | "Get the struan foreground colors against a specific BACKGROUND."
8 | (let* ((colors (->> (ct-make-hsluv 265 60 40)
9 | (ct-rotation-hsluv 6)
10 | (-select-by-indices '(1 5 2 3))
11 | (-map (lambda (c) (ct-edit-hsluv-l c 80)))
12 | (-map (lambda (c) (ct-contrast-min c background 4.3)))))
13 |
14 | (foreground (ct-contrast-min background background 7))
15 | (faded (ct-contrast-min (ct-aedit-hsl
16 | ;; (nth 2 colors)
17 | (ct-contrast-min background background 5.5)
18 | (list h 80 70))
19 | background 4.3)))
20 |
21 | (ht<-plist (list :background background
22 | :foreground foreground
23 | :faded faded
24 | :primary (nth 0 colors)
25 | :assumed (nth 1 colors)
26 | :alt (nth 2 colors)
27 | :strings (-> (nth 3 colors)
28 | (ct-aedit-lch (list (+ l 10) 100 h))
29 | (ct-contrast-min background 4.3))))))
30 |
31 | (defun myron-struan-create ()
32 | "Create the colors for the struan theme."
33 | (-let*
34 | ((background (ct-make-lab 93 2 4))
35 | (normal-parts (myron-struan-colors background))
36 | ((&hash :alt :assumed :primary :faded :foreground) normal-parts)
37 |
38 | (background>
39 | (-> background
40 | (ct-change 4 'ct-edit-lab-l-dec)
41 | (ct-steal 'hsluv-h alt)))
42 |
43 | (background>>
44 | (-> background
45 | (ct-change 7 'ct-edit-lab-l-dec)
46 | (ct-steal 'hsluv-h primary)))
47 |
48 | (background+
49 | (-> alt
50 | (ct-edit-lch-c 25)
51 | (ct-steal 'hsluv-l background>>))))
52 |
53 | (ht
54 | (:normal normal-parts)
55 | (:weak (myron-struan-colors background>))
56 | (:strong (myron-struan-colors background>>))
57 | (:focused (ht-merge normal-parts (ht (:background background+)))))))
58 |
59 |
60 | (deftheme myron-struan)
61 | (myron-themes--define 'myron-struan)
62 |
63 | (provide-theme 'myron-struan)
64 | (provide 'myron-struan-theme)
65 | ;;; myron-struan-theme.el ends here
66 |
--------------------------------------------------------------------------------
/themes/myron-room-theme.el:
--------------------------------------------------------------------------------
1 | ;; -*- lexical-binding: t; -*-
2 | ;; it's warm outside, it's cool in here
3 | ;; I'm not feeling very well
4 |
5 | (require 'myron-themes)
6 |
7 | (defun myron-room-colors (background hue)
8 | "Get the room foreground colors against a specific BACKGROUND."
9 | (->> '(:background 0
10 | :foreground 6
11 | :faded 3
12 | :primary 4
13 | ;; todo: something with assumed color
14 | :assumed 6
15 | :alt 3
16 | :strings 4)
17 | (-partition 2)
18 | (-mapcat (-lambda ((label contrast))
19 | (list label
20 | (cond
21 | ((eq :strings label)
22 | (-> (ct-contrast-min background background contrast)
23 | (ct-edit-hsluv-h hue)
24 | (ct-edit-lch-c 100)
25 | (ct-complement)))
26 | ((-contains-p '(:primary :alt) label)
27 | (-> (ct-contrast-min background background contrast)
28 | (ct-edit-hsluv-h hue)
29 | ;; (ct-edit-hsluv-s 100)
30 | (ct-edit-lch-c 100)))
31 | (t (ct-contrast-min background background contrast))))))
32 | ;; (-mapcat (-lambda ((label contrast))
33 | ;; (list label (ct-contrast-min background background contrast))))
34 | (ht<-plist)))
35 |
36 | (defun myron-room-create ()
37 | "Create the colors for the room theme."
38 | (-let*
39 | (;; maybe a darker bg
40 | (background "#f0f0f0")
41 |
42 | (hue (ct-get-hsluv-h "#ebe5f4"))
43 |
44 | ((background> background>>) (->> '(:weak 4
45 | :strong 7)
46 | (-partition 2)
47 | (-map (-lambda ((label distance))
48 | (ct-change background distance 'ct-edit-lab-l-dec)))))
49 | (background+ (-> (ht-get (myron-room-colors background hue) :alt)
50 | ;; (ct-edit-lch-h 40)
51 | (ct-complement)
52 | (ct-edit-lch-c 100)
53 | (ct-steal 'hsluv-l background>))))
54 | (ht<-plist
55 | (list
56 | :focused (myron-room-colors background+ hue)
57 | :normal (myron-room-colors background hue)
58 | :weak (myron-room-colors background> hue)
59 | :strong (myron-room-colors background>> hue)))))
60 |
61 | (deftheme myron-room)
62 | (myron-themes--define 'myron-room
63 | '((cursor :background alt)))
64 |
65 | (provide-theme 'myron-room)
66 | (provide 'myron-room-theme)
67 | ;;; myron-room-theme.el ends here
68 |
--------------------------------------------------------------------------------
/readme.org:
--------------------------------------------------------------------------------
1 | #+html:

2 |
3 | * ~Myron Themes~ 🟠 🔴 🟡 🟤 🟢 🟣 🔵
4 |
5 | Yet more *artisanal* light themes for [[https://emacs.sexy/][emacs]].
6 |
7 | - Bootstraps [[https://github.com/base16-project/base16-emacs][base16-emacs]] for wide emacs package coverage
8 | - Constant contrast across different [[#Emphasis][emphasis]] contexts
9 | - Conformity of markup texts to look like org mode (markdown, rst, adoc)
10 | - Built with [[https://github.com/neeasade/ct.el][ct.el]] (macro technology!!)
11 |
12 | ** Screenshots
13 |
14 | See [[https://notes.neeasade.net/tarps.html][here]] for a code preview of all themes. Some flagship themes below:
15 |
16 | | *mcfay* [[https://i.imgur.com/Fk4VBkP.png]] |
17 | | *struan* [[https://i.imgur.com/xxCuyoT.png]] |
18 | | *dogman* [[https://i.imgur.com/RlpnKZe.png]] |
19 |
20 | ** Installation
21 |
22 | Install with [[https://github.com/raxod502/straight.el][straight.el]]:
23 |
24 | #+begin_src emacs-lisp
25 | (straight-use-package '(myron-themes :host github :repo "neeasade/myron-themes" :files ("*.el" "themes/*.el")))
26 | #+end_src
27 |
28 | ** Colors
29 |
30 | Myron colorschemes come flavored against different backgrounds, for different levels of emphasis. This can be used to ensure the same contrast level across different contexts. The schemes are stored in a nested hash table, with a helper to access them -- EG ~(myron-get :primary :strong)~ to get the primary foreground color meant to be used against the strong background (which you could get with ~(myron-get :background :strong)~). The available background keys are: ~:normal :weak :strong :focused~. For each of those, the following foregrounds are available:
31 |
32 | | label | meaning (foreground) | example |
33 | |-------------+------------------------+----------------------------------------------|
34 | | :foreground | default | |
35 | | :faded | faded | comments |
36 | | :primary | identity | functions, variables |
37 | | :assumed | assumptions/core stuff | builtins, key words |
38 | | :alt | accent | types, matching string within search results |
39 | | :strings | strings | strings |
40 |
41 | Some thoughts on my general theme opinions:
42 |
43 | - Strings are important enough to get their own color for emphasis because they often represent the edges or barriers at which things communicate
44 | - Identity between functions and variables can be blended (lisp-1 type of feel)
45 | - The focused background is important/should be used to show what's highlighted or where interactive focus is
46 | - It appears I hate the color red generally (in thin lines it looks the same as black to me), except magenta/pinkish tones for the identity foreground
47 | - I generally lean higher contrast
48 | - note: I'm colorblind
49 |
50 | ** Contrast dumping
51 |
52 | Calling ~myron-show-contrasts~ will show the contrast ratios of all the foregrounds against all the backgrounds.
53 |
54 | ** Terminal usage
55 |
56 | Use these themes in a terminal supporting truecolors, and set the following before loading the themes:
57 |
58 | #+begin_src emacs-lisp
59 | (setq base16-theme-256-color-source 'colors)
60 | #+end_src
61 |
62 | ** Thanks/Previous inspo
63 |
64 | - [[https://github.com/MetroWind/lab-theme][lab-theme]]
65 | - [[https://github.com/waymondo/apropospriate-theme][aproprospriate]]
66 | - [[https://github.com/belak/base16-emacs][base16-emacs]]
67 |
--------------------------------------------------------------------------------
/myron-themes-cache.el:
--------------------------------------------------------------------------------
1 | ;; -*- lexical-binding: t; -*-
2 | (defvar myron-themes-cache
3 | '(myron-dogman
4 | #s(hash-table test equal data
5 | (:strong
6 | #s(hash-table test equal data
7 | (:strings "#026d00" :alt "#026d00" :faded "#006b47" :primary "#6d34e3"
8 | :assumed "#d144a7" :foreground "#064d51" :background "#92d9dd"))
9 | :weak
10 | #s(hash-table test equal data
11 | (:strings "#0e7900" :alt "#0e7900" :faded "#007753" :primary "#7940ef"
12 | :assumed "#e14db9" :foreground "#005953" :background "#92ede7"))
13 | :normal
14 | #s(hash-table test equal data
15 | (:strings "#1a8500" :alt "#1a8500" :faded "#00825e" :primary "#854cfb"
16 | :assumed "#f256c9" :foreground "#036458" :background "#9efff3"))
17 | :focused
18 | #s(hash-table test equal data
19 | (:strings "#0e7900" :alt "#0e7900" :faded "#007753" :primary "#7940ef"
20 | :assumed "#e14db9" :foreground "#524b6a" :background "#e0d9f8"))
21 | :meta
22 | #s(hash-table test equal data
23 | (:diff-remove-highlight "#f2c7ce" :diff-add-highlight "#9ef57d" :diff-remove
24 | "#f5d6db" :diff-add "#c7f9b7"))))
25 | myron-grayscale
26 | #s(hash-table test equal data
27 | (:strong
28 | #s(hash-table test equal data
29 | (:strings "#636363" :alt "#767676" :assumed "#545454" :primary "#636363"
30 | :faded "#767676" :foreground "#494949" :background "#d3d3d3"))
31 | :weak
32 | #s(hash-table test equal data
33 | (:strings "#6b6b6b" :alt "#7f7f7f" :assumed "#5c5c5c" :primary "#6b6b6b"
34 | :faded "#7f7f7f" :foreground "#515151" :background "#e0e0e0"))
35 | :focused
36 | #s(hash-table test equal data
37 | (:strings "#6e6e6e" :alt "#828282" :assumed "#5f5f5f" :primary "#6e6e6e"
38 | :faded "#828282" :foreground "#535353" :background "#e4e4e4"))
39 | :normal
40 | #s(hash-table test equal data
41 | (:strings "#777777" :alt "#8c8c8c" :assumed "#686868" :primary "#777777"
42 | :faded "#8c8c8c" :foreground "#5c5c5c" :background "#f3f3f3"))
43 | :meta
44 | #s(hash-table test equal data
45 | (:diff-remove-highlight "#f2cbd1" :diff-add-highlight "#abf68d" :diff-remove
46 | "#f6dce0" :diff-add "#d8face"))))
47 | myron-kobo
48 | #s(hash-table test equal data
49 | (:focused
50 | #s(hash-table test equal data
51 | (:primary "#5a5f00" :faded "#5f5a57" :alt "#6e7400" :strings "#6e7400"
52 | :assumed "#4b4643" :foreground "#4b4643" :background "#ccc7c4"))
53 | :strong
54 | #s(hash-table test equal data
55 | (:primary "#595e00" :faded "#5e5956" :alt "#6c7100" :strings "#6c7100"
56 | :assumed "#4a4542" :foreground "#4a4542" :background "#cac5c2"))
57 | :weak
58 | #s(hash-table test equal data
59 | (:primary "#666b00" :faded "#6b6663" :alt "#7a8000" :strings "#7a8000"
60 | :assumed "#57524f" :foreground "#57524f" :background "#ded9d6"))
61 | :normal
62 | #s(hash-table test equal data
63 | (:primary "#626700" :faded "#67625f" :alt "#757b00" :strings "#757b00"
64 | :assumed "#524d4a" :foreground "#524d4a" :background "#d7d2cf"))
65 | :meta
66 | #s(hash-table test equal data
67 | (:diff-remove-highlight "#efbac3" :diff-add-highlight "#95ea74" :diff-remove
68 | "#eeb4be" :diff-add "#92e572"))))
69 | myron-mcfay
70 | #s(hash-table test equal data
71 | (:focused
72 | #s(hash-table test equal data
73 | (:background "#a6d0ed" :foreground "#0c3653" :faded "#335d7a" :primary
74 | "#ad0066" :assumed "#0055b8" :alt "#005f87" :strings "#006c00"))
75 | :normal
76 | #s(hash-table test equal data
77 | (:background "#e8ebec" :foreground "#444748" :faded "#6a6d6e" :primary
78 | "#c6007f" :assumed "#0065c8" :alt "#006e96" :strings "#007c00"))
79 | :weak
80 | #s(hash-table test equal data
81 | (:background "#d6d7d8" :foreground "#3a3b3c" :faded "#606162" :primary
82 | "#bb0074" :assumed "#005ec1" :alt "#006890" :strings "#007500"))
83 | :strong
84 | #s(hash-table test equal data
85 | (:background "#cdcacb" :foreground "#353233" :faded "#5b5859" :primary
86 | "#ae0067" :assumed "#0055b8" :alt "#005f87" :strings "#006d00"))
87 | :meta
88 | #s(hash-table test equal data
89 | (:diff-remove-highlight "#f0c0c8" :diff-add-highlight "#9bef7b" :diff-remove
90 | "#f4d2d7" :diff-add "#bbf8a7"))))
91 | myron-room
92 | #s(hash-table test equal data
93 | (:strong
94 | #s(hash-table test equal data
95 | (:strings "#a66300" :alt "#0094ab" :assumed "#474747" :primary "#007e97"
96 | :faded "#747474" :foreground "#474747" :background "#d0d0d0"))
97 | :weak
98 | #s(hash-table test equal data
99 | (:strings "#b56800" :alt "#009eb5" :assumed "#4f4f4f" :primary "#00879f"
100 | :faded "#7d7d7d" :foreground "#4f4f4f" :background "#dddddd"))
101 | :normal
102 | #s(hash-table test equal data
103 | (:strings "#cb7000" :alt "#00acc3" :assumed "#5a5a5a" :primary "#0095ac"
104 | :faded "#8a8a8a" :foreground "#5a5a5a" :background "#f0f0f0"))
105 | :focused
106 | #s(hash-table test equal data
107 | (:strings "#626d1e" :alt "#9454ff" :assumed "#6e4338" :primary "#803bea"
108 | :faded "#9e7368" :foreground "#6e4338" :background "#fed3c8"))
109 | :meta
110 | #s(hash-table test equal data
111 | (:diff-remove-highlight "#f1c8ce" :diff-add-highlight "#a3f483" :diff-remove
112 | "#f5d9dd" :diff-add "#cff9c2"))))
113 | myron-storm
114 | #s(hash-table test equal data
115 | (:normal
116 | #s(hash-table test equal data
117 | (:background "#e3f0ed" :foreground "#697673" :faded "#7e8b88" :primary
118 | "#a356a4" :assumed "#108082" :strings "#0e8618" :alt "#a95e5b"))
119 | :weak
120 | #s(hash-table test equal data
121 | (:background "#ccd9d6" :foreground "#5b6865" :faded "#6e7b78" :primary
122 | "#924894" :assumed "#067074" :strings "#05760f" :alt "#984f49"))
123 | :strong
124 | #s(hash-table test equal data
125 | (:background "#c3d0cd" :foreground "#55625f" :faded "#687572" :primary
126 | "#8b418d" :assumed "#026a6f" :strings "#006f0a" :alt "#924942"))
127 | :focused
128 | #s(hash-table test equal data
129 | (:background "#ecccec" :foreground "#7a5a7a" :faded "#8e6e8e" :primary
130 | "#a74908" :assumed "#a74446" :strings "#a138a1" :alt "#00716d"))
131 | :meta
132 | #s(hash-table test equal data
133 | (:diff-remove-highlight "#efc0c8" :diff-add-highlight "#99f078" :diff-remove
134 | "#f4d5da" :diff-add "#c5f9b5"))))
135 | myron-struan
136 | #s(hash-table test equal data
137 | (:normal
138 | #s(hash-table test equal data
139 | (:strings "#677400" :alt "#916156" :assumed "#2a7783" :primary "#8f5d7f"
140 | :faded "#a35a29" :foreground "#544b45" :background "#f2e9e3"))
141 | :weak
142 | #s(hash-table test equal data
143 | (:strings "#5b6700" :alt "#845449" :assumed "#1d6a76" :primary "#825072"
144 | :faded "#a93b2f" :foreground "#483f3e" :background "#ded5d4"))
145 | :strong
146 | #s(hash-table test equal data
147 | (:strings "#535f00" :alt "#7d4d42" :assumed "#15626e" :primary "#7b496b"
148 | :faded "#a1276b" :foreground "#40373c" :background "#d2c9ce"))
149 | :focused
150 | #s(hash-table test equal data
151 | (:strings "#677400" :alt "#916156" :assumed "#2a7783" :primary "#8f5d7f"
152 | :faded "#a35a29" :foreground "#544b45" :background "#e1c5c0"))
153 | :meta
154 | #s(hash-table test equal data
155 | (:diff-remove-highlight "#f0c0c8" :diff-add-highlight "#9aef7b" :diff-remove
156 | "#f4d2d7" :diff-add "#bbf8a9")))))
157 | "Cache value for the themes. Internal use only.")
158 | (provide 'myron-themes-cache)
--------------------------------------------------------------------------------
/myron-themes.el:
--------------------------------------------------------------------------------
1 | ;;; myron-themes.el --- A collection of light color themes -*- coding: utf-8; lexical-binding: t -*-
2 | ;; Copyright (C) 2025 neeasade
3 | ;; SPDX-License-Identifier: MIT
4 | ;; Author: neeasade
5 | ;; URL: https://github.com/neeasade/myron-themes
6 | ;; Package-Requires: ((emacs "25.1") (ct "0.3") (helpful "0.19") (ht "2.3") (base16-theme "3.0"))
7 | ;; Version: 0.1
8 |
9 | ;;; Commentary:
10 | ;; A set of color themes built on top of the base16-themes.
11 |
12 | ;;; Code:
13 |
14 | (require 'base16-theme)
15 | (require 'ct)
16 | (require 'helpful)
17 | (require 'ht)
18 | (require 'myron-themes-cache)
19 |
20 | (defvar myron-themes-colors nil "The color values for the loaded myron theme.")
21 |
22 | (defgroup myron-themes nil
23 | "Myron color themes for EMACS."
24 | :group 'myron-themes
25 | :prefix "myron-themes")
26 |
27 | (defcustom myron-themes-use-cache t
28 | "A toggle to use the colors as authored.
29 |
30 | To compute the colors on your machine, set to nil."
31 | :type 'boolean
32 | :group 'myron)
33 |
34 | (defun myron-themes-get (label &optional background-emphasis)
35 | "Get the color value of LABEL on some BACKGROUND-EMPHASIS."
36 | (or (ht-get* myron-themes-colors (or background-emphasis :normal) label)
37 | (when (not background-emphasis) (ht-get* myron-themes-colors :meta label))))
38 |
39 | (defun myron-themes--show-contrast-against (bg-level)
40 | "Show contrast levels of fg colors in myron-themes-colors against BG-LEVEL."
41 | (-map (lambda (fg-label)
42 | (-let* ((foreground (myron-themes-get fg-label bg-level))
43 | (background (myron-themes-get :background bg-level))
44 | (contrast-ratio (ct-contrast-ratio foreground background)))
45 | (format "%s %.1f %s" foreground contrast-ratio fg-label)))
46 | '(:foreground :faded :primary :assumed :alt :strings)))
47 |
48 | (defun myron-themes-show-contrasts ()
49 | "Message the contrast ratios of colors of different background emphasis levels."
50 | (interactive)
51 | (->> '(:focused :strong :weak :normal)
52 | (-map (-juxt 'identity (-partial 'myron-themes-get :background)))
53 | (-mapcat
54 | (-lambda ((bg-level bg-color))
55 | `(,(format "Against background %s %s" bg-level bg-color)
56 | ,@(myron-themes--show-contrast-against bg-level)
57 | "------")))
58 | (--map (concat it "\n"))
59 | (apply 'concat)
60 | (message)))
61 |
62 | (defun myron-themes-to-base16 (&optional emphasis)
63 | "Return `myron-themes-colors' colors as a base16 plist using EMPHASIS."
64 | (-let* ((emphasis (or emphasis :normal))
65 | (background-f (myron-themes-get :background :focused))
66 | ((&hash :alt :strings :assumed :primary :faded :foreground :background) (ht-get myron-themes-colors emphasis)))
67 | ;; The comments on the sections here are from the base16 styling guidelines, not necessarily
68 | ;; what the emacs base16 theme package follows (observations commented following ":").
69 | ;; guidelines location: http://chriskempson.com/projects/base16/
70 | (list
71 | :base00 background ;; Default Background
72 | :base01 background-f ;; search match, Lighter Background (Used for status bars) : search bg
73 | :base02 background-f ;; Selection Background
74 | :base03 faded ;; Comments, Invisibles, Line Highlighting
75 | :base04 faded ;; Dark Foreground (Used for status bars) : paren-face
76 | :base05 foreground ;; Default Foreground, Caret, Delimiters, Operators
77 | :base06 faded ;; Light Foreground (Not often used)
78 | :base07 background ;; Light Background (Not often used) : nb. unused
79 | :base08 alt ;; Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted : org-todo
80 | :base09 foreground ;; Integers, Boolean, Constants, XML Attributes, Markup Link Url
81 | :base0A alt ;; Types, Classes, Markup Bold, Search Text Background
82 | :base0B strings ;; Strings, Inherited Class, Markup Code, Diff Inserted
83 | :base0C assumed ;; Support, Regular Expressions, Escape Characters, Markup Quotes
84 | :base0D primary ;; Functions, Methods, Attribute IDs, Headings : search fg, prompt
85 | :base0E assumed ;; Keywords, Storage, Selector, Markup Italic, Diff Changed : org-date, keyword
86 | :base0F faded ;; Deprecated, Opening/Closing Embedded Language Tags, e.g. : used as fg in various smol places
87 | )))
88 |
89 | (defun myron-themes--get-function-sexp (sym)
90 | "Get SYM as a quoted list, using helpful.el."
91 | (read (seq-let (buffer point _) (helpful--definition sym t)
92 | (helpful--source sym t buffer point))))
93 |
94 | (defun myron-themes--markup-map ()
95 | "List of org faces to markup-faces for non-org modes."
96 | '(
97 | ;; HEADINGS
98 | org-level-1 (adoc-title-0-face markdown-header-face-1 rst-level-1)
99 | org-level-2 (adoc-title-1-face markdown-header-face-2 rst-level-2)
100 | org-level-3 (adoc-title-2-face markdown-header-face-3 rst-level-3)
101 | org-level-4 (adoc-title-3-face markdown-header-face-4 rst-level-4)
102 | org-level-5 (adoc-title-4-face markdown-header-face-5 rst-level-5)
103 |
104 | ;; the leading #'s of the headings in markdown
105 | ;; using org-level-4 so it's not thicc on nested markdown headings
106 | org-level-4 (markdown-header-delimiter-face)
107 |
108 | ;; INLINE CODE
109 | ;; nb: rst-literal applies for both inline-code and blocks of code
110 | org-code (adoc-typewriter-face markdown-inline-code-face)
111 |
112 | ;; BLOCKS OF CODE
113 | org-block (adoc-verbatim-face adoc-native-code-face adoc-code-face markdown-code-face rst-literal)
114 |
115 | ;; BUILTINS/META
116 | bold (adoc-bold-face markdown-bold-face rst-emphasis2)
117 | italic (adoc-emphasis-face rst-emphasis1)
118 |
119 | org-meta-line (adoc-complex-replacement-face
120 | adoc-meta-hide-face
121 | markdown-markup-face
122 | adoc-markup-face ; maybe?
123 | adoc-meta-face
124 | rst-directive
125 | rst-adornment)
126 |
127 | ;; non-org modes make the distinction between labels and destinations
128 | ;; org mode when showing link markup treats url/dest as default face, so I'm choosing to match that
129 | default (adoc-internal-reference-face markdown-url-face)
130 | org-link (adoc-reference-face
131 | markdown-link-face
132 | rst-reference
133 | rst-external
134 | lui-button-face
135 | button)
136 |
137 | ;; org list elements have no face
138 | default (markdown-list-face adoc-list-face rst-block)
139 |
140 | org-checkbox markdown-gfm-checkbox-face))
141 |
142 | (defun myron-themes--make-faces (&optional theme-overrides)
143 | "Make the face->color map for the current theme.
144 |
145 | Optionally transform colors with a THEME-OVERRIDES function."
146 | (let*
147 | (
148 | ;; steal the list that's hardcoded in base16-theme-define
149 | ;; cf https://github.com/belak/base16-emacs/blob/93b1513a9994355492314e809cdbfb0d21f1e30d/base16-theme.el#L186
150 | (original-theme (->> (myron-themes--get-function-sexp 'base16-theme-define)
151 | (nth 4)
152 | (nth 3)
153 | (-second-item)))
154 |
155 | ;; todo: consider it might be more natural to create normal_faded,
156 | ;; strong_background aliases instead of calling myron-themes-get througout
157 | ;; this section (eg consistency with theme-overrides)
158 |
159 | ;; note individual changes
160 | (theme-changes
161 | `(
162 | (cursor :background primary)
163 | (fringe :background unspecified)
164 |
165 | (font-lock-comment-delimiter-face :foreground faded)
166 | (font-lock-comment-face :background unspecified)
167 |
168 | ((window-divider vertical-border) :foreground faded)
169 |
170 | ;; identity
171 | (font-lock-function-name-face :foreground primary)
172 | (font-lock-variable-name-face :foreground primary)
173 |
174 | ((outline-1 outline-2 outline-3 outline-4 outline-5) :foreground foreground)
175 | ((whitespace-space whitespace-tab) :background unspecified)
176 | ((org-date flycheck-warning flycheck-info) :underline unspecified)
177 |
178 | (secondary-selection :background ,(myron-themes-get :background :strong))
179 |
180 | (parenthesis :foreground faded)
181 |
182 | (prescient-primary-highlight :foreground alt)
183 | ;; maybe this should be assumed or primary
184 | (prescient-secondary-highlight :foreground strings)
185 |
186 | ((orderless-match-face-0 orderless-match-face-1 orderless-match-face-2 orderless-match-face-3)
187 | :foreground alt)
188 |
189 | (completions-common-part :foreground ,(myron-themes-get :alt :weak)) ; weak for corfu popup
190 |
191 | (magit-diff-context-highlight :background ,(myron-themes-get :background :weak))
192 |
193 | ;; todo: this appears to not be doing anything
194 | ;; (magit-diff-file-heading :extend t)
195 | (corfu-bar :background faded)
196 | (company-tooltip-scrollbar-thumb :background faded)
197 | (company-tooltip-scrollbar-track :background ,(myron-themes-get :background :weak))
198 |
199 | (completions-annotations :foreground faded)
200 |
201 | ((magit-diff-hunk-heading magit-diff-hunk-heading-highlight) :extend unspecified)
202 |
203 | (magit-diff-hunk-heading :background ,(myron-themes-get :background :strong))
204 | (magit-diff-hunk-heading-highlight :background ,(myron-themes-get :background :focused))
205 | (magit-diff-added :background ,(myron-themes-get :diff-add))
206 | (magit-diff-removed :background ,(myron-themes-get :diff-remove))
207 | (magit-diff-added-highlight :background ,(myron-themes-get :diff-add-highlight))
208 | (magit-diff-removed-highlight :background ,(myron-themes-get :diff-remove-highlight))
209 |
210 | ,@(-map
211 | (-lambda ((face back-label fore-label))
212 | (->> `(,face :inverse-video nil
213 | :background ,(myron-themes-get :background back-label)
214 | :foreground ,(myron-themes-get (or fore-label :foreground) back-label))))
215 | `(
216 | ;; (avy-lead-face :strong :primary)
217 | ;; (avy-lead-face-0 :strong :assumed)
218 | ;; (avy-lead-face-1 :strong :alt)
219 | ;; (avy-lead-face-2 :strong :strings)
220 |
221 | ;; maybe button? a button-active notion?
222 | (avy-lead-face :strong :assumed)
223 | (avy-lead-face-0 :strong :assumed)
224 | (avy-lead-face-1 :strong :assumed)
225 | (avy-lead-face-2 :strong :assumed)
226 |
227 | (eros-result-overlay-face :strong)
228 | (cider-result-overlay-face :strong)
229 |
230 | (comint-highlight-prompt :normal :assumed)
231 |
232 | (tooltip :weak)
233 |
234 | (lsp-ui-sideline-global :weak :alt)
235 | (lsp-ui-sideline-current-symbol :weak :alt)
236 |
237 | (magit-blame-heading :weak)
238 |
239 | ;; focus bois
240 | ,@(--map (list it :focused)
241 | '(show-paren-match show-paren-match-expression
242 | line-number-current-line
243 | corfu-current ivy-current-match isearch))
244 |
245 | ;; all the org builtin stuff:
246 | ;; this assumes sort of a soft alt,
247 | ;; faded might be more appropriate,
248 | ;; but then intent gets mixed with commenting
249 | (org-drawer :normal :alt)
250 | (org-meta-line :normal :alt)
251 | (org-document-info-keyword :normal :alt)
252 |
253 | (org-todo :strong :strings)
254 | (org-headline-todo :normal)
255 |
256 | (org-done :weak :faded)
257 | (org-headline-done :normal :faded)
258 |
259 | (mode-line-inactive :weak)
260 | (mode-line :strong)
261 |
262 | (lazy-highlight :strong)
263 |
264 | (org-link :weak :alt)
265 | (org-code :weak)
266 |
267 | (org-block :normal)
268 | (org-block-begin-line :normal)
269 | (org-block-end-line :normal)
270 |
271 | ;; todo: only want this if we can get (:extend t) to work above
272 | ;; (magit-diff-file-heading :strong)
273 |
274 | (diff-header :strong)
275 | (diff-hunk-header :strong)
276 | (diff-function :strong)
277 | (diff-file-header :weak)
278 |
279 | (line-number :weak :faded)))
280 |
281 | ;; inheritors
282 | ,@(-mapcat
283 | (-lambda ((parent children))
284 | (--map (apply 'list it :inherit parent
285 | (--mapcat (list it 'unspecified)
286 | '(:foreground :background :underline :box :height)))
287 | (-list children)))
288 | (-partition 2
289 | `(
290 | ,@(myron-themes--markup-map)
291 |
292 | tooltip (corfu-default)
293 |
294 | ;; diff consistency:
295 | default smerge-markers
296 |
297 | magit-diff-added (diff-added smerge-upper)
298 | magit-diff-removed (diff-removed smerge-lower)
299 |
300 | magit-diff-added-highlight (diff-refine-added smerge-refined-added)
301 | magit-diff-removed-highlight (diff-refine-removed smerge-refined-removed)
302 |
303 | ;; abuse diff colors in other contexts for consistency:
304 |
305 | ;; success:
306 | magit-diff-added cider-test-success-face
307 |
308 | ;; failure:
309 | magit-diff-removed (whitespace-line)
310 | magit-diff-removed-highlight (cider-error-overlay-face
311 | cider-test-error-face
312 | cider-test-failure-face
313 | error
314 | show-paren-mismatch))))
315 |
316 | ,@theme-overrides))
317 |
318 | ;; allow multi-face, multi-attr conf
319 | (theme-changes
320 | (->> theme-changes
321 | (-mapcat (-lambda ((faces . kvs))
322 | (-map (lambda (face) `(,face ,@kvs))
323 | (-list faces))))
324 | (-mapcat (-lambda ((face . kvs))
325 | (-map (lambda (kv) `(,face ,@kv))
326 | (-partition 2 kvs))))))
327 |
328 | (new-theme
329 | ;; apply our individual changes to the original theme
330 | (-reduce-from
331 | (-lambda (state (face key value))
332 | (if (-contains-p (-map #'-first-item state) face)
333 | (-map (lambda (entry)
334 | (if (eq (-first-item entry) face)
335 | `(,face ,@(plist-put (cdr entry) key value))
336 | entry))
337 | state)
338 | (cons (list face key value) state)))
339 | original-theme
340 | theme-changes)))
341 |
342 | ;; original-theme
343 | new-theme))
344 |
345 |
346 |
347 | (defun myron-themes-termcolors ()
348 | "Export current myron theme to a list of terminal colors."
349 | ;; stealing default base16 export order for now
350 | (--map (plist-get (myron-themes-to-base16) it)
351 | '(:base00 :base08 :base0B :base0A :base0D :base0E :base0C :base05
352 | :base03 :base09 :base01 :base02 :base04 :base06 :base0F :base07)))
353 |
354 | (defun myron-themes--create-meta-colors (colors)
355 | "Add the meta color table to COLORS."
356 |
357 | (ht-set! colors
358 | :meta
359 | (-let* (((bg bg-weak _) (--map (ht-get* colors it :background) '(:normal :weak :strong)))
360 | ;; (color-strings (ht-get* colors :normal :strings))
361 | ;; (strings-hue (ct-get-hsluv-h (ht-get* colors :normal :strings)))
362 | (green (ct-make-hsluv 120 70 (ct-get-hsluv-l bg)))
363 | ;; a little oomf
364 | (red (ct-make-hsluv 0 70 (- (ct-get-hsluv-l bg) 5)))
365 | (light-delta (apply '- (-map 'ct-get-hsluv-l (list bg bg-weak))))
366 | (light-delta (* 0.7 light-delta))
367 | (dark-green (ct-edit-hsluv-l-dec green light-delta))
368 | (dark-red (ct-edit-hsluv-l-dec red light-delta))
369 | ((green red dark-green dark-red) (--map (ct-edit-hsluv-l-dec it 0.5)
370 | (list green red dark-green dark-red))))
371 | (ht<-plist
372 | `(:diff-add ,green
373 | :diff-remove ,red
374 | :diff-add-highlight ,dark-green
375 | :diff-remove-highlight ,dark-red
376 | ;; :interactive-background ,(ct-aedit-hsluv bg-weak (list strings-hue 5 l))
377 | ;; :interactive-background-highlight ,(ct-aedit-hsluv bg-strong (list strings-hue 5 l))
378 |
379 | ;; todo: instead of percent, perhaps this should be based on a distance of some sort
380 | :subtle ,(ct-lessen (ht-get* colors :normal :background) 3)))))
381 | colors)
382 |
383 | (defun myron-themes--define (theme-name &optional theme-overrides)
384 | "Define theme THEME-NAME, optionally change faces with function THEME-OVERRIDES."
385 | (setq myron-themes-colors (if myron-themes-use-cache
386 | (plist-get myron-themes-cache theme-name)
387 | (myron-themes--create-meta-colors
388 | (funcall (intern (format "%s-create" theme-name))))))
389 |
390 | (base16-theme-set-faces theme-name
391 | (append (myron-themes-to-base16) (ht-to-plist (ht-get myron-themes-colors :normal)))
392 | (myron-themes--make-faces theme-overrides))
393 |
394 | (custom-theme-set-variables theme-name
395 | `(ansi-color-names-vector ,(apply 'vector (-take 8 (myron-themes-termcolors))))))
396 |
397 | ;;;###autoload
398 | (when (and (boundp 'custom-theme-load-path) load-file-name)
399 | (let* ((base (file-name-directory load-file-name))
400 | (dir (expand-file-name "themes/" base)))
401 | (add-to-list 'custom-theme-load-path
402 | (or (and (file-directory-p dir) dir)
403 | base))))
404 |
405 | (provide 'myron-themes)
406 | ;;; myron-themes.el ends here
407 |
--------------------------------------------------------------------------------