summaryrefslogtreecommitdiff
path: root/themes/dupre-theme.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-01-26 01:18:02 -0600
committerCraig Jennings <c@cjennings.net>2026-01-26 01:18:02 -0600
commit51418d3b375f5223b98a3b7865ab428886e5acbc (patch)
tree901d188584ead435abaf33efb7aa431bd04af6e5 /themes/dupre-theme.el
parent92e2b82170f77ef2b21686916485fb2e3f61efb6 (diff)
feat(theme): restructure dupre-theme into modular architecture
Split monolithic theme into three files following modus-themes pattern: - dupre-palette.el: 30 base colors + 28 semantic mappings - dupre-faces.el: 150+ face definitions organized by package - dupre-theme.el: thin entry point that loads palette and faces Applied 60-30-10 color design rule: - 60% neutrals (grays for comments, metadata, lower headings) - 30% signature blue (#67809c) for keywords, links, directories - 10% accents (gold for h1, green for strings, terracotta for functions)
Diffstat (limited to 'themes/dupre-theme.el')
-rw-r--r--themes/dupre-theme.el160
1 files changed, 37 insertions, 123 deletions
diff --git a/themes/dupre-theme.el b/themes/dupre-theme.el
index 96c775f3..5edb1a17 100644
--- a/themes/dupre-theme.el
+++ b/themes/dupre-theme.el
@@ -1,126 +1,58 @@
;;; dupre-theme.el --- A dark and elegant theme for Emacs -*- lexical-binding: t -*-
-;; Version: 0.0.2
+;; Version: 1.0.0
;; Author: Craig Jennings <c@cjennings.net>
;; URL: https://github.com/cjennings/dupre-theme
;; Keywords: dark theme faces
;;; Commentary:
-;; A modified version of the distinguished theme by Kim Silkebækken
-;; <kim.silkebaekken@gmail.com>. This version by Craig Jennings
-;; <c@cjennings.net>.
+;; A dark, warm theme for Emacs with 150+ face definitions.
+;; Originally based on the distinguished theme by Kim Silkebaekken.
+;;
+;; This theme is optimized for GUI Emacs. Terminal fallbacks are basic.
+;;
+;; Color palette follows a warm aesthetic:
+;; - Yellow (#d7af5f) as primary accent
+;; - Blue (#67809c) for keywords and navigation
+;; - Green (#a4ac64) for strings and success
+;; - Red (#d47c59) for functions and emphasis
+;;
+;; File structure:
+;; - dupre-theme.el (this file) - Theme definition and entry point
+;; - dupre-palette.el - Color definitions and semantic mappings
+;; - dupre-faces.el - All face specifications (~150 faces)
;;; Code:
+(eval-and-compile
+ ;; Add themes directory to load-path for require
+ (when-let ((dir (file-name-directory (or load-file-name
+ buffer-file-name
+ (locate-library "dupre-theme")))))
+ (unless (member dir load-path)
+ (add-to-list 'load-path dir))))
+
+(require 'dupre-palette)
+(require 'dupre-faces)
+
(defgroup dupre-theme nil
"Options for the `dupre' colour theme."
:group 'faces)
(deftheme dupre
- "A dark and elegant theme for Emacs.")
-
-(let* ((dupre-fg (if (display-graphic-p) "#f0fef0" "color-231"))
- (dupre-bg (if (display-graphic-p) "#000000" "color-232"))
- (dupre-bg+0 (if (display-graphic-p) "#151311" "color-234"))
- (dupre-bg+1 (if (display-graphic-p) "#252321" "color-236"))
- (dupre-bg+2 (if (display-graphic-p) "#474544" "color-238"))
- (dupre-gray-2 (if (display-graphic-p) "#58574e" "color-240"))
- (dupre-gray-1 (if (display-graphic-p) "#6c6a60" "color-242"))
- (dupre-gray (if (display-graphic-p) "#969385" "color-243"))
- (dupre-gray+1 (if (display-graphic-p) "#b4b1a2" "color-250"))
- (dupre-gray+2 (if (display-graphic-p) "#d0cbc0" "color-252"))
- (dupre-steel (if (display-graphic-p) "#8a9496" "color-245"))
- (dupre-steel+1 (if (display-graphic-p) "#acb0b3" "color-247"))
- (dupre-steel+2 (if (display-graphic-p) "#c0c7ca" "color-251"))
- (dupre-blue (if (display-graphic-p) "#67809c" "color-173"))
- (dupre-blue+1 (if (display-graphic-p) "#b2c3cc" "color-66" ))
- (dupre-blue+2 (if (display-graphic-p) "#d9e2ff" "color-69" ))
- (dupre-green-2 (if (display-graphic-p) "#646d14" "color-22" ))
- (dupre-green-1 (if (display-graphic-p) "#869038" "color-28" ))
- (dupre-green (if (display-graphic-p) "#a4ac64" "color-143"))
- (dupre-green+1 (if (display-graphic-p) "#ccc768" "color-67" ))
- (dupre-red-3 (if (display-graphic-p) "#3f1c0f" "color-124"))
- (dupre-red-2 (if (display-graphic-p) "#7c2a09" "color-196"))
- (dupre-red-1 (if (display-graphic-p) "#a7502d" "color-160"))
- (dupre-red (if (display-graphic-p) "#d47c59" "color-179"))
- (dupre-red+1 (if (display-graphic-p) "#edb08f" "color-173"))
- (dupre-red+2 (if (display-graphic-p) "#edbca2" "color-208"))
- (dupre-yellow-2 (if (display-graphic-p) "#875f00" "color-94"))
- (dupre-yellow-1 (if (display-graphic-p) "#ffd700" "color-220"))
- (dupre-yellow (if (display-graphic-p) "#d7af5f" "color-226"))
- (dupre-yellow+1 (if (display-graphic-p) "#ffd75f" "color-137"))
- (dupre-yellow+2 (if (display-graphic-p) "#f9ee98" "color-228"))
- (dupre-intense-red (if (display-graphic-p) "#ff2a00" "color-202")))
-
- ;; Tell Emacs “this is a dark theme”
- (custom-theme-set-variables
- 'dupre
- `(frame-background-mode 'dark)
- `(fringe-mode 8))
-
- (custom-theme-set-faces
- 'dupre
-
- ;; basics
- `(default ((t (:foreground ,dupre-fg :background ,dupre-bg))))
- `(cursor ((t (:background ,dupre-fg))))
- `(hl-line ((t (:background ,dupre-bg+0))))
- `(minibuffer-prompt ((t (:foreground ,dupre-green :weight bold))))
- `(region ((t (:background ,dupre-bg+2))))
- `(fringe ((t (:foreground ,dupre-gray-2 :background ,dupre-bg+1))))
- `(vertical-border ((t (:foreground ,dupre-bg+2))))
- `(mode-line ((t (:foreground ,dupre-gray+2 :background ,dupre-bg+2
- :box (:line-width -1 :style released-button)))))
- `(mode-line-inactive ((t (:foreground ,dupre-gray :background ,dupre-bg+1
- :box (:line-width -1 :style released-button)))))
- `(mode-line-buffer-id ((t (:foreground ,dupre-yellow :weight bold))))
- `(button ((t (:foreground ,dupre-blue+1 :underline t))))
-
- ;; font-lock
- `(font-lock-builtin-face ((t (:foreground ,dupre-yellow :weight bold))))
- `(font-lock-comment-face ((t (:foreground ,dupre-gray :slant italic))))
- `(font-lock-comment-delimiter-face ((t (:foreground ,dupre-bg+2))))
- `(font-lock-doc-face ((t (:foreground ,dupre-gray))))
- `(font-lock-constant-face ((t (:foreground ,dupre-yellow+1 :weight bold))))
- `(font-lock-function-name-face ((t (:foreground ,dupre-red :weight bold))))
- `(font-lock-keyword-face ((t (:foreground ,dupre-blue :weight bold))))
- `(font-lock-negation-char-face ((t (:foreground ,dupre-yellow :weight bold))))
- `(font-lock-preprocessor-face ((t (:foreground ,dupre-steel+1 :weight bold :slant italic))))
- `(font-lock-regexp-grouping-construct ((t (:foreground ,dupre-yellow :weight bold))))
- `(font-lock-regexp-grouping-backslash ((t (:foreground ,dupre-red :weight bold))))
- `(font-lock-string-face ((t (:foreground ,dupre-green))))
- `(font-lock-type-face ((t (:foreground ,dupre-green+1 :weight bold))))
- `(font-lock-variable-name-face ((t (:foreground ,dupre-blue+1 :slant italic))))
- `(font-lock-warning-face ((t (:foreground ,dupre-intense-red :weight bold))))
+ "A dark and elegant theme for Emacs with warm undertones."
+ :background-mode 'dark
+ :kind 'color-scheme)
- ;; show-paren
- `(show-paren-match ((t (:foreground ,dupre-fg :background ,dupre-green-2 :weight bold))))
- `(show-paren-mismatch ((t (:foreground ,dupre-fg :background ,dupre-intense-red :weight bold))))
+;; Set theme variables
+(custom-theme-set-variables
+ 'dupre
+ '(frame-background-mode 'dark)
+ '(fringe-mode 8))
- ;; isearch
- `(isearch ((t (:foreground ,dupre-fg :background ,dupre-green-2
- :weight bold :box (:line-width -1 :style released-button)))))
- `(isearch-fail ((t (:foreground ,dupre-fg :background ,dupre-red-1
- :weight bold :box (:line-width -1 :style released-button)))))
- `(lazy-highlight ((t (:foreground ,dupre-bg :background ,dupre-yellow+1
- :weight bold :box (:line-width -1 :style released-button)))))
-
- ;; line numbers (Emacs ≥26.1)
- (when (>= emacs-major-version 26)
- `(line-number ((t (:foreground ,dupre-gray-1 :background ,dupre-bg+1))))
- `(line-number-current-line ((t (:foreground ,dupre-yellow :background ,dupre-bg+1 :weight bold)))))
-
- ;; tab-line (Emacs ≥27.1)
- (when (>= emacs-major-version 27)
- `(tab-line ((t (:inherit mode-line :background ,dupre-bg+1 :box (:line-width 4 :color ,dupre-bg+1)))))
- `(tab-line-tab ((t (:inherit tab-line))))
- `(tab-line-tab-inactive ((t (:inherit tab-line :foreground ,dupre-gray))))
- `(tab-line-tab-current ((t (:background ,dupre-bg+2 …))))
- `(tab-line-highlight ((t (:background ,dupre-bg+1 …)))))
-
- ) ; closes the WHEN
- ) ; closes custom-theme-set-faces
+;; Apply all face definitions
+(dupre-theme-set-faces)
;;;###autoload
(when load-file-name
@@ -129,21 +61,3 @@
(provide-theme 'dupre)
;;; dupre-theme.el ends here
-
-;; --------------------------------- ERT Tests ---------------------------------
-
-(require 'ert)
-
-(ert-deftest dupre-theme-default-face ()
- "dupre-theme should set the default face correctly."
- (load-theme 'dupre t)
- ;; In a graphical Emacs we expect "#000000"/"#f0fef0"
- (let ((bg (face-attribute 'default :background))
- (fg (face-attribute 'default :foreground)))
- (should (string= bg "#000000"))
- (should (string= fg "#f0fef0"))))
-
-(ert-deftest dupre-theme-comment-face-italic ()
- "Comments should be rendered in italic slant."
- (load-theme 'dupre t)
- (should (eq (face-attribute 'font-lock-comment-face :slant) 'italic)))