solarized.el (24540B)
1 ;;; solarized.el --- Solarized theme -*- lexical-binding: t -*- 2 3 ;; Copyright (C) 2011-2025 Bozhidar Batsov 4 5 ;; Author: Bozhidar Batsov <bozhidar@batsov.dev> 6 ;; Author: Thomas Frössman <thomasf@jossystem.se> 7 8 ;; This program is free software; you can redistribute it and/or modify 9 ;; it under the terms of the GNU General Public License as published by 10 ;; the Free Software Foundation, either version 3 of the License, or 11 ;; (at your option) any later version. 12 13 ;; This program is distributed in the hope that it will be useful, 14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 ;; GNU General Public License for more details. 17 18 ;; You should have received a copy of the GNU General Public License 19 ;; along with this program. If not, see <http://www.gnu.org/licenses/>. 20 21 ;;; Commentary: 22 23 ;; Main solarized file 24 25 ;;; Code: 26 27 (require 'cl-lib) 28 (require 'color) 29 (require 'solarized-faces) 30 31 ;;; Options 32 33 (defgroup solarized nil 34 "Solarized theme options. 35 The theme has to be reloaded after changing anything in this group." 36 :group 'faces) 37 38 (defcustom solarized-theme-dir (locate-user-emacs-file "themes/") 39 "Directory to save theme file." 40 :type 'directory 41 :group 'solarized) 42 43 (defcustom solarized-distinct-fringe-background nil 44 "Make the fringe background different from the normal background color. 45 Also affects `linum-mode' background." 46 :type 'boolean 47 :group 'solarized) 48 49 (defcustom solarized-distinct-doc-face nil 50 "Make `font-lock-doc-face' stand out more. 51 Related discussion: https://github.com/bbatsov/solarized-emacs/issues/158" 52 :type 'boolean 53 :group 'solarized) 54 55 (defcustom solarized-highlight-numbers nil 56 "Highlight all numbers. 57 Applies color to `font-lock-number-face' and `highlight-numbers' mode. 58 Many tree-sitter based modes use `font-lock-number-face'." 59 :type 'boolean 60 :group 'solarized) 61 62 (defcustom solarized-use-variable-pitch t 63 "Use variable pitch face for some headings and titles." 64 :type 'boolean 65 :group 'solarized) 66 67 (defcustom solarized-use-less-bold nil 68 "Use bold weight less often." 69 :type 'boolean 70 :group 'solarized) 71 72 (defcustom solarized-use-more-italic nil 73 "Use italic slant more often." 74 :type 'boolean 75 :group 'solarized) 76 77 (defcustom solarized-emphasize-indicators t 78 "Use more colors for indicators such as git:gutter, flycheck and similar." 79 :type 'boolean 80 :group 'solarized) 81 82 (defcustom solarized-high-contrast-mode-line nil 83 "Make the active/inactive mode line stand out more." 84 :type 'boolean 85 :group 'solarized) 86 87 (defcustom solarized-height-minus-1 0.8 88 "Font size -1." 89 :type 'number 90 :group 'solarized) 91 92 (defcustom solarized-height-plus-1 1.1 93 "Font size +1." 94 :type 'number 95 :group 'solarized) 96 97 (defcustom solarized-height-plus-2 1.15 98 "Font size +2." 99 :type 'number 100 :group 'solarized) 101 102 (defcustom solarized-height-plus-3 1.2 103 "Font size +3." 104 :type 'number 105 :group 'solarized) 106 107 (defcustom solarized-height-plus-4 1.3 108 "Font size +4." 109 :type 'number 110 :group 'solarized) 111 112 (defcustom solarized-scale-org-headlines t 113 "Whether `org-mode' headlines should be scaled." 114 :type 'boolean 115 :group 'solarized) 116 117 (defcustom solarized-scale-markdown-headlines nil 118 "Whether `markdown-mode' headlines should be scaled." 119 :type 'boolean 120 :group 'solarized) 121 122 (defcustom solarized-scale-outline-headlines t 123 "Whether `outline-mode' headlines should be scaled." 124 :type 'boolean 125 :group 'solarized) 126 127 (defcustom solarized-palette-darker-accent-alpha 0.8 128 "The alpha value when blending dark variants of accent colors. 129 Used in `solarized-create-color-palette'." 130 :type 'number 131 :group 'solarized) 132 133 (defcustom solarized-palette-lighter-accent-alpha 0.8 134 "The alpha value when blending light variants of accent colors. 135 Used in `solarized-create-color-palette'." 136 :type 'number 137 :group 'solarized) 138 139 ;;; Utilities 140 141 (defun solarized-color-clamp-lab (lab) 142 "Restricts a LAB colorspace color if it is out of bounds." 143 (list (min (max (nth 0 lab) 0.0) 100.0) 144 (min (max (nth 1 lab) -128) 127) 145 (min (max (nth 2 lab) -128) 127))) 146 147 (defun solarized-color-rgb-to-hex (red green blue &optional digits-per-component round) 148 "Return hexadecimal #RGB notation for the color specified by RED GREEN BLUE. 149 RED, GREEN, and BLUE should be numbers between 0.0 and 1.0, inclusive. 150 Optional argument DIGITS-PER-COMPONENT can be either 4 (the default) 151 or 2; use the latter if you need a 24-bit specification of a color. 152 Optional argument ROUND rounds values which probably is what you usually want." 153 (or digits-per-component (setq digits-per-component 4)) 154 (let* ((maxval (if (= digits-per-component 2) 255 65535)) 155 (fmt (if (= digits-per-component 2) "#%02x%02x%02x" "#%04x%04x%04x"))) 156 (if round 157 (format fmt (+ 0.5 (* red maxval)) (+ 0.5 (* green maxval)) (+ 0.5 (* blue maxval))) 158 (format fmt (* red maxval) (* green maxval) (* blue maxval))))) 159 160 ;;;###autoload 161 (defun solarized-color-blend (color1 color2 alpha &optional digits-per-component) 162 "Blends COLOR1 onto COLOR2 with ALPHA. 163 164 COLOR1 and COLOR2 should be color names (e.g. \"white\") or RGB 165 triplet strings (e.g. \"#ff12ec\"). 166 167 Alpha should be a float between 0 and 1. 168 169 Optional argument DIGITS-PER-COMPONENT can be either 4 (the default) or 2; 170 use the latter if you need a 24-bit specification of a color." 171 (let ((args (mapcar 'color-clamp 172 (apply 'color-lab-to-srgb 173 (solarized-color-clamp-lab 174 (cl-mapcar 175 (lambda (v1 v2) (+ v1 (* alpha (- v2 v1)))) 176 (apply 'color-srgb-to-lab (color-name-to-rgb color2)) 177 (apply 'color-srgb-to-lab (color-name-to-rgb color1)))))))) 178 (apply 'solarized-color-rgb-to-hex `(,@args ,digits-per-component t)))) 179 180 ;;;###autoload 181 (defun solarized-create-color-palette (core-palette &optional variant) 182 "Create color-palette from CORE-PALETTE. 183 184 The returned color-palette has the same format as `solarized-color-palette'." 185 (let* ((darkest-base (nth 0 core-palette)) 186 (brightest-base (nth 1 core-palette)) 187 (yellow (nth 2 core-palette)) 188 (orange (nth 3 core-palette)) 189 (red (nth 4 core-palette)) 190 (magenta (nth 5 core-palette)) 191 (violet (nth 6 core-palette)) 192 (blue (nth 7 core-palette)) 193 (cyan (nth 8 core-palette)) 194 (green (nth 9 core-palette)) 195 (bg-base (if (eq variant 'light) brightest-base darkest-base)) 196 (fg-base (if (eq variant 'light) darkest-base brightest-base)) 197 (bg-1 (if (eq variant 'light) 0.82 0.85)) 198 (bg-2 (if (eq variant 'light) 0.68 0.60)) 199 (fg-1 (if (eq variant 'light) 0.38 0.30)) 200 (fg-2 (if (eq variant 'light) 0.30 0.45))) 201 202 `((base03 . ,(solarized-color-blend darkest-base brightest-base 1.00 2)) 203 (base02 . ,(solarized-color-blend darkest-base brightest-base 0.97 2)) 204 (base01 . ,(solarized-color-blend darkest-base brightest-base 0.65 2)) 205 (base00 . ,(solarized-color-blend darkest-base brightest-base 0.60 2)) 206 (base0 . ,(solarized-color-blend darkest-base brightest-base 0.48 2)) 207 (base1 . ,(solarized-color-blend darkest-base brightest-base 0.42 2)) 208 (base2 . ,(solarized-color-blend darkest-base brightest-base 0.06 2)) 209 (base3 . ,(solarized-color-blend darkest-base brightest-base 0.00 2)) 210 211 ;; Solarized accented colors 212 (yellow . ,yellow) 213 (orange . ,orange) 214 (red . ,red) 215 (magenta . ,magenta) 216 (violet . ,violet) 217 (blue . ,blue) 218 (cyan . ,cyan) 219 (green . ,green) 220 221 ;; Darker and lighter accented colors 222 ;; Only use these in exceptional circumstances! 223 (yellow-d . ,(solarized-color-blend darkest-base yellow solarized-palette-darker-accent-alpha 2)) 224 (yellow-l . ,(solarized-color-blend brightest-base yellow solarized-palette-lighter-accent-alpha 2)) 225 (orange-d . ,(solarized-color-blend darkest-base orange solarized-palette-darker-accent-alpha 2)) 226 (orange-l . ,(solarized-color-blend brightest-base orange solarized-palette-lighter-accent-alpha 2)) 227 (red-d . ,(solarized-color-blend darkest-base red solarized-palette-darker-accent-alpha 2)) 228 (red-l . ,(solarized-color-blend brightest-base red solarized-palette-lighter-accent-alpha 2)) 229 (magenta-d . ,(solarized-color-blend darkest-base magenta solarized-palette-darker-accent-alpha 2)) 230 (magenta-l . ,(solarized-color-blend brightest-base magenta solarized-palette-lighter-accent-alpha 2)) 231 (violet-d . ,(solarized-color-blend darkest-base violet solarized-palette-darker-accent-alpha 2)) 232 (violet-l . ,(solarized-color-blend brightest-base violet solarized-palette-lighter-accent-alpha 2)) 233 (blue-d . ,(solarized-color-blend darkest-base blue solarized-palette-darker-accent-alpha 2)) 234 (blue-l . ,(solarized-color-blend brightest-base blue solarized-palette-lighter-accent-alpha 2)) 235 (cyan-d . ,(solarized-color-blend darkest-base cyan solarized-palette-darker-accent-alpha 2)) 236 (cyan-l . ,(solarized-color-blend brightest-base cyan solarized-palette-lighter-accent-alpha 2)) 237 (green-d . ,(solarized-color-blend darkest-base green solarized-palette-darker-accent-alpha 2)) 238 (green-l . ,(solarized-color-blend brightest-base green solarized-palette-lighter-accent-alpha 2)) 239 240 (yellow-1bg . ,(solarized-color-blend bg-base yellow bg-1 2)) 241 (orange-1bg . ,(solarized-color-blend bg-base orange bg-1 2)) 242 (red-1bg . ,(solarized-color-blend bg-base red bg-1 2)) 243 (magenta-1bg . ,(solarized-color-blend bg-base magenta bg-1 2)) 244 (blue-1bg . ,(solarized-color-blend bg-base blue bg-1 2)) 245 (cyan-1bg . ,(solarized-color-blend bg-base cyan bg-1 2)) 246 (green-1bg . ,(solarized-color-blend bg-base green bg-1 2)) 247 (violet-1bg . ,(solarized-color-blend bg-base violet bg-1 2)) 248 249 (yellow-1fg . ,(solarized-color-blend fg-base yellow fg-1 2)) 250 (orange-1fg . ,(solarized-color-blend fg-base orange fg-1 2)) 251 (red-1fg . ,(solarized-color-blend fg-base red fg-1 2)) 252 (magenta-1fg . ,(solarized-color-blend fg-base magenta fg-1 2)) 253 (violet-1fg . ,(solarized-color-blend fg-base violet fg-1 2)) 254 (blue-1fg . ,(solarized-color-blend fg-base blue fg-1 2)) 255 (cyan-1fg . ,(solarized-color-blend fg-base cyan fg-1 2)) 256 (green-1fg . ,(solarized-color-blend fg-base green fg-1 2)) 257 258 (yellow-2bg . ,(solarized-color-blend bg-base yellow bg-2 2)) 259 (orange-2bg . ,(solarized-color-blend bg-base orange bg-2 2)) 260 (red-2bg . ,(solarized-color-blend bg-base red bg-2 2)) 261 (magenta-2bg . ,(solarized-color-blend bg-base magenta bg-2 2)) 262 (violet-2bg . ,(solarized-color-blend bg-base violet bg-2 2)) 263 (blue-2bg . ,(solarized-color-blend bg-base blue bg-2 2)) 264 (cyan-2bg . ,(solarized-color-blend bg-base cyan bg-2 2)) 265 (green-2bg . ,(solarized-color-blend bg-base green bg-2 2)) 266 267 (yellow-2fg . ,(solarized-color-blend fg-base yellow fg-2 2)) 268 (orange-2fg . ,(solarized-color-blend fg-base orange fg-2 2)) 269 (red-2fg . ,(solarized-color-blend fg-base red fg-2 2)) 270 (magenta-2fg . ,(solarized-color-blend fg-base magenta fg-2 2)) 271 (violet-2fg . ,(solarized-color-blend fg-base violet fg-2 2)) 272 (blue-2fg . ,(solarized-color-blend fg-base blue fg-2 2)) 273 (cyan-2fg . ,(solarized-color-blend fg-base cyan fg-2 2)) 274 (green-2fg . ,(solarized-color-blend fg-base green fg-2 2))))) 275 276 ;;; Setup Start 277 (defmacro solarized-with-color-variables (variant theme-name color-palette &optional childtheme-sexp) 278 "Eval `solarized-definition' in solarized COLOR-PALETTE for THEME-NAME. 279 VARIANT is \\='dark or \\='light. 280 When optional argument CHILDTHEME-SEXP sexp is supplied it\\='s invoked to further 281 customize the resulting theme." 282 (declare (indent defun)) 283 (let ((color-palette* (eval color-palette))) 284 `(let* ((class '((class color) (min-colors 89))) 285 (light-class (append '((background light)) class)) 286 (dark-class (append '((background dark)) class)) 287 (theme-name ,theme-name) 288 (variant ,variant) 289 ,@(mapcar (lambda (elm) `(,(car elm) ,(cdr elm))) color-palette*) 290 291 (s-base03 base03) 292 (s-base02 base02) 293 (s-base01 base01) 294 (s-base00 base00) 295 (s-base3 base3) 296 (s-base2 base2) 297 (s-base1 base1) 298 (s-base0 base0) 299 300 ;; Solarized palette names, use these instead of -fg -bg... 301 (base03 (if (eq variant 'light) s-base3 s-base03)) 302 (base02 (if (eq variant 'light) s-base2 s-base02)) 303 (base01 (if (eq variant 'light) s-base1 s-base01)) 304 (base00 (if (eq variant 'light) s-base0 s-base00)) 305 (base0 (if (eq variant 'light) s-base00 s-base0)) 306 (base1 (if (eq variant 'light) s-base01 s-base1)) 307 (base2 (if (eq variant 'light) s-base02 s-base2)) 308 (base3 (if (eq variant 'light) s-base03 s-base3)) 309 310 ;; Line drawing color 311 ;; 312 ;; NOTE only use this for very thin lines that are hard to see using base02, in low 313 ;; color displays base02 might be used instead 314 (s-line (if (eq variant 'light) "#cccec4" "#284b54")) 315 316 ;; Light/Dark adaptive higher/lower contrast accented colors 317 ;; 318 ;; NOTE Only use these in exceptional circumstances! 319 (yellow-hc (if (eq variant 'light) yellow-d yellow-l)) 320 (yellow-lc (if (eq variant 'light) yellow-l yellow-d)) 321 (orange-hc (if (eq variant 'light) orange-d orange-l)) 322 (orange-lc (if (eq variant 'light) orange-l orange-d)) 323 (red-hc (if (eq variant 'light) red-d red-l)) 324 (red-lc (if (eq variant 'light) red-l red-d)) 325 (magenta-hc (if (eq variant 'light) magenta-d magenta-l)) 326 (magenta-lc (if (eq variant 'light) magenta-l magenta-d)) 327 (violet-hc (if (eq variant 'light) violet-d violet-l)) 328 (violet-lc (if (eq variant 'light) violet-l violet-d)) 329 (blue-hc (if (eq variant 'light) blue-d blue-l)) 330 (blue-lc (if (eq variant 'light) blue-l blue-d)) 331 (cyan-hc (if (eq variant 'light) cyan-d cyan-l)) 332 (cyan-lc (if (eq variant 'light) cyan-l cyan-d)) 333 (green-hc (if (eq variant 'light) green-d green-l)) 334 (green-lc (if (eq variant 'light) green-l green-d)) 335 336 ;; customize based face properties 337 (s-maybe-bold (if solarized-use-less-bold 338 'unspecified 'bold)) 339 (s-maybe-italic (if solarized-use-more-italic 340 'italic 'normal)) 341 (s-variable-pitch (if solarized-use-variable-pitch 342 'variable-pitch 'default)) 343 (s-fringe-bg (if solarized-distinct-fringe-background 344 base02 base03)) 345 (s-fringe-fg base01) 346 347 (s-header-line-fg (if solarized-high-contrast-mode-line 348 base1 base0)) 349 (s-header-line-bg (if solarized-high-contrast-mode-line 350 base02 base03)) 351 (s-header-line-underline (if solarized-high-contrast-mode-line 352 nil base02)) 353 354 (s-mode-line-fg (if solarized-high-contrast-mode-line 355 base03 base0)) 356 (s-mode-line-bg (if solarized-high-contrast-mode-line 357 base0 base02)) 358 (s-mode-line-underline (if solarized-high-contrast-mode-line 359 nil s-line)) 360 361 (s-mode-line-buffer-id-fg (if solarized-high-contrast-mode-line 362 'unspecified base1)) 363 (s-mode-line-inactive-fg (if solarized-high-contrast-mode-line 364 base0 base01)) 365 (s-mode-line-inactive-bg (if solarized-high-contrast-mode-line 366 base02 base03)) 367 (s-mode-line-inactive-bc (if solarized-high-contrast-mode-line 368 base02 base02)) 369 370 ;; diff colors 371 (s-diff-A-bg red-1bg) 372 (s-diff-A-fg red-1fg) 373 (s-diff-fine-A-bg red-2bg) 374 (s-diff-fine-A-fg red-2fg) 375 376 (s-diff-B-bg green-1bg) 377 (s-diff-B-fg green-1fg) 378 (s-diff-fine-B-bg green-2bg) 379 (s-diff-fine-B-fg green-2fg) 380 381 (s-diff-Ancestor-bg yellow-1bg) 382 (s-diff-Ancestor-fg yellow-1fg) 383 (s-diff-fine-Ancestor-bg yellow-2bg) 384 (s-diff-fine-Ancestor-fg yellow-2fg) 385 386 (s-diff-C-bg blue-1bg) 387 (s-diff-C-fg blue-1fg) 388 (s-diff-fine-C-bg blue-2bg) 389 (s-diff-fine-C-fg blue-2fg) 390 (s-diff-context-fg base0) 391 (s-diff-heading-bg base02) 392 393 (s-diffstat-added-fg green) 394 (s-diffstat-changed-fg blue) 395 (s-diffstat-removed-fg red)) 396 397 ;; silence the byte compiler 398 (ignore class light-class dark-class theme-name variant 399 ,@(mapcar 'car color-palette*) 400 s-base03 s-base02 s-base01 s-base00 s-base3 s-base2 401 s-base1 s-base0 base03 base02 base01 base00 base0 base1 402 base2 base3 s-line yellow-hc yellow-lc orange-hc 403 orange-lc red-hc red-lc magenta-hc magenta-lc violet-hc 404 violet-lc blue-hc blue-lc cyan-hc cyan-lc green-hc 405 green-lc s-maybe-bold s-maybe-italic s-variable-pitch 406 s-fringe-bg s-fringe-fg s-header-line-fg s-header-line-bg 407 s-header-line-underline s-mode-line-fg s-mode-line-bg 408 s-mode-line-underline s-mode-line-buffer-id-fg 409 s-mode-line-inactive-fg s-mode-line-inactive-bg 410 s-mode-line-inactive-bc s-diff-A-bg s-diff-A-fg 411 s-diff-fine-A-bg s-diff-fine-A-fg s-diff-B-bg s-diff-B-fg 412 s-diff-fine-B-bg s-diff-fine-B-fg s-diff-Ancestor-bg 413 s-diff-Ancestor-fg s-diff-fine-Ancestor-bg 414 s-diff-fine-Ancestor-fg s-diff-C-bg s-diff-C-fg 415 s-diff-fine-C-bg s-diff-fine-C-fg s-diff-context-fg 416 s-diff-heading-bg s-diffstat-added-fg 417 s-diffstat-changed-fg s-diffstat-removed-fg) 418 ;; Emit the child theme's faces *before* the base definition. 419 ;; `custom-theme-set-faces' keeps the first spec it sees for a 420 ;; given face, so this is what lets a child theme override the 421 ;; base faces (#352). Doing it through ordering, rather than by 422 ;; binding `custom--inhibit-theme-enable' to nil, means we no 423 ;; longer force the faces to apply during loading and thus honor 424 ;; `load-theme's NO-ENABLE argument (#420, #325). 425 ,@(eval childtheme-sexp) 426 ,@solarized-definition))) 427 428 (defmacro solarized-with-color-variables-with-palette (variant theme-name core-palette &optional childtheme-sexp) 429 "Create a VARIANT of the theme named THEME-NAME with CORE-PALETTE. 430 431 When optional argument CHILDTHEME-SEXP sexp is supplied it's invoked to further 432 customize the resulting theme. 433 434 CORE-PALETTE is core color-palette." 435 (declare (indent 2)) 436 (let ((color-palette (solarized-create-color-palette (eval core-palette) (eval variant)))) 437 `(solarized-with-color-variables ,variant ,theme-name ',color-palette ,childtheme-sexp))) 438 439 (defun solarized-create-theme-file (variant theme-name color-palette &optional childtheme-sexp overwrite) 440 "Create a VARIANT of the theme named THEME-NAME with COLOR-PALETTE. 441 442 When optional argument CHILDTHEME-SEXP sexp is supplied it's invoked to further 443 customize the resulting theme. 444 445 CORE-PALETTE is core color-palette. 446 If OVERWRITE is non-nil, overwrite theme file if exist." 447 (declare (indent 2)) 448 (add-to-list 'custom-theme-load-path solarized-theme-dir) 449 (let ((path (expand-file-name (format "%s.el" theme-name) 450 solarized-theme-dir))) 451 (unless (file-directory-p solarized-theme-dir) 452 (make-directory solarized-theme-dir)) 453 (when (or overwrite (not (file-readable-p path))) 454 (with-temp-file (expand-file-name (format "%s-theme.el" theme-name) 455 solarized-theme-dir) 456 (mapc (lambda (elm) 457 (insert (pp-to-string elm))) 458 `((require 'solarized) 459 (deftheme ,theme-name 460 ,(format "The %s colour theme of Solarized colour theme flavor." theme-name)) 461 (solarized-with-color-variables ',variant ',theme-name ',color-palette ',childtheme-sexp) 462 (provide-theme ',theme-name) 463 (provide ',(intern (format "%s-theme" theme-name))))))) 464 path)) 465 466 (defun solarized-create-theme-file-with-palette (variant theme-name core-palette &optional childtheme-sexp overwrite) 467 "Create a VARIANT of the theme named THEME-NAME with CORE-PALETTE. 468 469 When optional argument CHILDTHEME-SEXP sexp is supplied it's invoked to further 470 customize the resulting theme. 471 472 CORE-PALETTE is core color-palette. 473 If OVERWRITE is non-nil, overwrite theme file if exist." 474 (declare (indent 2)) 475 (let ((color-palette (solarized-create-color-palette core-palette variant))) 476 (apply #'solarized-create-theme-file (list variant theme-name color-palette childtheme-sexp overwrite)))) 477 478 (define-obsolete-function-alias 'create-solarized-theme-file 'solarized-create-theme-file "1.3.0") 479 480 (defconst solarized--themes 481 '(solarized-dark 482 solarized-light 483 solarized-dark-high-contrast 484 solarized-light-high-contrast 485 solarized-gruvbox-dark 486 solarized-gruvbox-light 487 solarized-selenized-dark 488 solarized-selenized-light 489 solarized-selenized-black 490 solarized-selenized-white 491 solarized-zenburn 492 solarized-wombat-dark) 493 "List of all bundled Solarized theme variants.") 494 495 (defvar solarized--current nil 496 "The currently active Solarized theme, or nil.") 497 498 (defun solarized--set-current (theme) 499 "Record THEME as the active Solarized theme. 500 Called from `enable-theme-functions'." 501 (when (memq theme solarized--themes) 502 (setq solarized--current theme))) 503 504 (defun solarized--clear-current (theme) 505 "Clear the active Solarized theme if THEME is being disabled. 506 Called from `disable-theme-functions'." 507 (when (eq theme solarized--current) 508 (setq solarized--current nil))) 509 510 (when (boundp 'enable-theme-functions) 511 (add-hook 'enable-theme-functions #'solarized--set-current) 512 (add-hook 'disable-theme-functions #'solarized--clear-current)) 513 514 (defun solarized-reload (&optional theme) 515 "Reload the Solarized theme. 516 You can specify the variant to reload manually with THEME. 517 518 Useful after changing some configuration options or tweaking some colors." 519 (interactive) 520 (let ((theme (or theme solarized--current (car custom-enabled-themes)))) 521 (disable-theme theme) 522 (load-theme theme t))) 523 524 ;;;###autoload 525 (defun solarized-toggle-theme () 526 "Toggle between the light and dark variants of Solarized." 527 (interactive) 528 (let ((current-theme (or solarized--current (car custom-enabled-themes)))) 529 (cond 530 ((eq current-theme 'solarized-dark) (solarized-reload 'solarized-light)) 531 ((eq current-theme 'solarized-light) (solarized-reload 'solarized-dark)) 532 (t (message "You're not currently running a Solarized theme"))))) 533 534 ;;;###autoload 535 (defun solarized-select-theme () 536 "Select and load a Solarized theme variant interactively." 537 (interactive) 538 (let* ((names (mapcar #'symbol-name solarized--themes)) 539 (choice (intern (completing-read "Solarized theme: " names nil t)))) 540 (mapc #'disable-theme solarized--themes) 541 (load-theme choice t))) 542 543 ;;; Footer 544 545 ;;;###autoload 546 (when (and (boundp 'custom-theme-load-path) load-file-name) 547 (add-to-list 'custom-theme-load-path 548 (file-name-as-directory (file-name-directory load-file-name)))) 549 550 (provide 'solarized) 551 552 ;; Local Variables: 553 ;; indent-tabs-mode: nil 554 ;; End: 555 556 ;;; solarized.el ends here