Configurable color themes for Emacs 24 and above

Alex Kost 2c0ba50c60 Update version (0.3) and package commentary 11 years ago
.gitignore 7a9cc71d1f Ignore "alect-test.el" 11 years ago
LICENSE b0f72d2189 Add LICENSE 11 years ago
README.md 61dac55c70 Update README 11 years ago
alect-dark-alt-theme.el 602655eb2a Add files for alternative themes 11 years ago
alect-dark-theme.el 2c2fae205e alect.el was renamed into alect-themes.el. 11 years ago
alect-light-alt-theme.el 602655eb2a Add files for alternative themes 11 years ago
alect-light-theme.el 2c2fae205e alect.el was renamed into alect-themes.el. 11 years ago
alect-themes-pkg.el 2c0ba50c60 Update version (0.3) and package commentary 11 years ago
alect-themes.el 2c0ba50c60 Update version (0.3) and package commentary 11 years ago
colors ef4816b149 Improve yellow colors for the light theme 11 years ago

README.md

About

Alect is a package that provides (rather low contrast but colourful enough) configurable light and dark color themes for GNU Emacs 24 or later. I use it only with GUI, so colors in terminal may look not very nice.

History

At first i had only a light theme – it was just a set of customized faces. Then i realized that at night it's better for eyes to use a dark theme (it was derived from zenburn-theme initially, but then the colors were modified a lot). The idea of creating two themes with different colors and the same code base came from solarized-theme. The code of solarized and zenburn themes was used hardly. Many thanks to their authors.

Installation

Manual

Add this to your init file (~/.emacs.d/init.el or ~/.emacs):

(add-to-list 'load-path              "/path/to/alect-themes")
(add-to-list 'custom-theme-load-path "/path/to/alect-themes")

MELPA

The package can be installed from MELPA. (with M-x package-install or M-x list-packages).

If you want to enable (see Usage section) any theme installed with a package system on Emacs start, you should know the following: Emacs loads packages after processing the init file, so loading a theme will fail because the path to a theme is not known yet. That's why you need to initialize the package system before loading the theme:

(setq package-enable-at-startup nil)
(package-initialize)
...
(load-theme ...)

For further details, see (info "(emacs) Package Installation").

Usage

To activate a theme interactively use customize-themes or load-theme:

M-x load-theme RET alect-light

To load a theme on Emacs start, add this to your init file:

(load-theme 'alect-light t)

Configuration

You can find the names and values of all colors used by alect-themes in alect-colors variable. Also you can open colors file in Emacs to get an idea about the used color palette.

There are 2 main ways for configuring the themes:

  • modifying palette (alect-colors variable);
  • overriding face specifications.

Modifying palette

If you don't like how some colors look, you can change alect-colors variable by customizing it or by using alect-generate-colors function (see how the variable is defined in the code).

However those methods redefine the whole variable, so if the palette will be changed in future (it happens sometimes) or a new theme will be added (it's planned), you may not notice that. So you can use another approach if you want to modify only some colors.

Let's say, you don't like cyan-2 color for the light theme as it's too light and red+1 color for the dark theme as it's too bright (and it burns your eyes). You can change those colors by putting this into your .emacs (before loading an alect-theme if you use it on Emacs start):

(eval-after-load 'alect-themes
  '(progn
     (alect-set-color 'light 'cyan-2 "#00a8a8")
     (alect-set-color 'dark 'red+1 "#f03333")))

The function alect-set-color is just a convenient way for modifying alect-colors variable, so if you are playing with it, don't forget to reload an alect-theme for the changes to take effect.

Overriding faces

If you don't like how particular faces look, you can change those by modifying alect-overriding-faces variable. The real power here is that you can use themed color names from alect-colors along with the usual strings with hex values or defined color names (available with M-x list-colors-display).

Let's say, you want green strings, gray comments, more distinguishable mode-line, and of course you don't like those pink (magenta-1) prompts everywhere (minibuffer, comint, ...). Just set that variable like this:

(setq
 alect-overriding-faces
 '((alect-prompt           ((t :foreground blue :weight bold)))
   (font-lock-string-face  ((t :foreground green-1)))
   (font-lock-doc-face     ((t :inherit font-lock-string-face)))
   (font-lock-comment-face ((t :foreground gray)))
   (mode-line-buffer-id    ((t :foreground "yellow" :weight bold)))
   (mode-line              ((((background light))
                             :foreground fg+1 :background "#ffaaaa"
                             :box (:line-width 2 :color bg-2 :style nil))
                            (((background dark))
                             :foreground fg+1 :background "firebrick3"
                             :box (:line-width 2 :color bg-2 :style nil))))))

See these screenshots to compare the original and modified themes.

Alternative themes

Along with 2 original light and dark themes, the package provides 2 inverted (alternative) themes (alect-light-alt and alect-dark-alt). They use the same color palettes, so they look very similar to the original ones. The difference (by default) is that dark and bright colors are reversed.

There is an additional way of configuring alternative themes: with alect-inverted-color-regexp variable (for details, see docstrings of this variable and alect-get-color function). For example, you may set this variable to invert background colors:

(setq alect-inverted-color-regexp "^\\(bg\\)\\([-+]\\)\\([012]\\)$")

See these screenshots for the result.

Emacs 24.3.1 and earlier

While using any theme (not only from this package), you may meet faces that do not look how they should (intended by the theme). For example, if you enable alect-light theme, you can see ugly gray buttons and other faces in the Custom-mode (the left picture) instead of the themed colored buttons (the right picture):

This happens because Emacs applies default face settings even for a themed face. This behaviour is changed in new versions of Emacs (24.4 and above). Happily it can be easily fixed for earlier versions by redefining face-spec-recalc function (can be found on Emacs git mirror):

(defun face-spec-recalc (face frame)
  "Reset the face attributes of FACE on FRAME according to its specs.
This applies the defface/custom spec first, then the custom theme specs,
then the override spec."
  (while (get face 'face-alias)
    (setq face (get face 'face-alias)))
  (face-spec-reset-face face frame)
  ;; If FACE is customized or themed, set the custom spec from
  ;; `theme-face' records, which completely replace the defface spec
  ;; rather than inheriting from it.
  (let ((theme-faces (get face 'theme-face)))
    (if theme-faces
	(dolist (spec (reverse theme-faces))
	  (face-spec-set-2 face frame (cadr spec)))
      (face-spec-set-2 face frame (face-default-spec face))))
  (face-spec-set-2 face frame (get face 'face-override-spec)))

If you put it into your .emacs, you will always get pure themes without unintended face settings.

Screenshots

You can see the following and other screenshots in this imgur album.

C, shell, linum, ido

Themes: alect-light, alect-dark

Font: Terminus-12

Org, markdown

Themes: alect-light, alect-dark

Font: DejaVu Sans Mono-12

Magit

Themes: alect-light, alect-dark

Font: Anonymous Pro-13

Elisp, ido

Themes: alect-dark (default), alect-dark (modified) – the original dark theme and a dark theme with some changed faces (see overriding faces)

Font: Liberation Mono-12

Dired, elisp

Themes: alect-light-alt (modified), alect-dark-alt (modified) – alternative themes, configured to invert background (see configuring alternative themes)

Font: Anonymous Pro-13

Feedback

If you want this package to support more faces, you may send me a letter about your favourite unsupported modes.