魔改造によってSolarized.elがEmacs最強のカラーテーマになってしまった件
はじめに
この記事は「Emacs Advent Calendar 2019」の3日目の記事として書いたのです。 昨日は私の「{2019年アップデート} leaf.elで雑然としたEmacs設定ファイル「init.el」をクリーンにする」でした。
まだ空きがあるので、ぜひ参加頂ければと思います!
Emacsのカラーテーマについて
Emacsは「An extensible, customizable, free/libre text editor」です。 その中でカラーテーマはプログラマの個性が一番出る所で、Emacsも当然 細かく 設定できます。
。。。しかし、細かすぎるのです。そして細かすぎるがゆえにどうやって好みの色にしていくのか設定箇所も多岐に渡ります。
その状況をどのように脱却するかについて @zk-phi さんが興味深い考察と実践をされています。
- {Emacs} メタ・カラースキームとしての solarized
- カラースキームスキームとしてのカラースキーム
そのアイデアを元にsolarized-emacsにこれらのPRを送り、無事(大小の衝突がありつつ、、)マージされました。
最初の提案
#330に関連する修正/わざと分けた修正など。
- #342 fix indentation see #330
- #343 Add Cask and Makefile
- #345 Fix package-lint warnings/error
- #346 Remove turning on rainbow-mode magic comment
- #350 Include pkg file information into solarized-theme.el
- #351 call color-rgb-to-hex with 3 arguments when emacs<26
- #353 Enable lexical-binding and some code-refactoring
- #355 add description to create color-theme
- #361 Fix wrong function name in readme
- #362 Fix readme for usage of child theme
- #363 Change user-emacs-directory in minimal-init.el
- #364 Fix file local variables
- #367 fix BODY to solarized-definition
- #372 Merge *color-blend-rgb to *color-blend
- #373 Remove solarized-color-lightness
この記事はsolarizedにマージされた、この新しい機能をどうやって使うのかについて解説をするものです。
Emacsのカラーテーマの仕事
Emacsのカラーテーマの仕事は多くありません。 下記はカラーテーマのテンプレートです。
defthemeによってテーマの名前を宣言し、custom-theme-set-facesとcustom-set-variablesによってフェイスと変数の設定を行い、provide-themeとprovideを実行し、Emacsから利用できるようにする。
しかし2.の手順がとても面倒なのです。
Emacs24のときに現在のテーマの仕組みが導入され、以前のcolor-theme.elから移行する必要があったとき、 emacs-jpの有志によって大量のカラーテーマが変換されました。(ここの経緯はよく分かりませんが。。)
そのカラーテーマ群はemacs-jp/replace-colorthemesに置いてあり、MELPAから color-theme-modern というパッケージ名でインストールできます。
その中の数テーマを眺めてもらえれば、テーマによって custom-theme-set-faces と custom-set-variables の充実度合いが違うことに気づくと思います。
一方でsolarizedのフェイス定義はとても充実していることが分かります。
この作業は一人で管理するものではなく、逆にEmacsコミュニティで共同編集し、共有するものだと思います。 同じようなソースがバラバラに存在するのは嘆かわしいことです。
MELPAで「theme」と検索すると現在257パッケージがヒットします。それぞれにこの定義が書いてあるというのは恐ろしいと思います。管理できないし、報われない。。
solarized-zenbarn
「Emacs Theme Gallery」から1位のzenburnをsolarizedのAPIを使って再現してみます。
私も作りながら記事を書いているので、ぜひ一緒に作ってみるとどうやって使うのか分かりやすいと思います。
コアパレットの用意
zenbarnはbbatsov/zenburn-emacsに置かれており、色の定義はこちらです。
(defvar zenburn-default-colors-alist
'(("zenburn-fg-1" . "#656555")
("zenburn-fg-05" . "#989890")
("zenburn-fg" . "#DCDCCC")
("zenburn-fg+1" . "#FFFFEF")
("zenburn-fg+2" . "#FFFFFD")
("zenburn-bg-2" . "#000000")
("zenburn-bg-1" . "#2B2B2B")
("zenburn-bg-08" . "#303030")
("zenburn-bg-05" . "#383838")
("zenburn-bg" . "#3F3F3F")
("zenburn-bg+05" . "#494949")
("zenburn-bg+1" . "#4F4F4F")
("zenburn-bg+2" . "#5F5F5F")
("zenburn-bg+3" . "#6F6F6F")
("zenburn-red-6" . "#6C3333")
("zenburn-red-5" . "#7C4343")
("zenburn-red-4" . "#8C5353")
("zenburn-red-3" . "#9C6363")
("zenburn-red-2" . "#AC7373")
("zenburn-red-1" . "#BC8383")
("zenburn-red" . "#CC9393")
("zenburn-red+1" . "#DCA3A3")
("zenburn-red+2" . "#ECB3B3")
("zenburn-orange" . "#DFAF8F")
("zenburn-yellow-2" . "#D0BF8F")
("zenburn-yellow-1" . "#E0CF9F")
("zenburn-yellow" . "#F0DFAF")
("zenburn-green-5" . "#2F4F2F")
("zenburn-green-4" . "#3F5F3F")
("zenburn-green-3" . "#4F6F4F")
("zenburn-green-2" . "#5F7F5F")
("zenburn-green-1" . "#6F8F6F")
("zenburn-green" . "#7F9F7F")
("zenburn-green+1" . "#8FB28F")
("zenburn-green+2" . "#9FC59F")
("zenburn-green+3" . "#AFD8AF")
("zenburn-green+4" . "#BFEBBF")
("zenburn-cyan" . "#93E0E3")
("zenburn-blue+3" . "#BDE0F3")
("zenburn-blue+2" . "#ACE0E3")
("zenburn-blue+1" . "#94BFF3")
("zenburn-blue" . "#8CD0D3")
("zenburn-blue-1" . "#7CB8BB")
("zenburn-blue-2" . "#6CA0A3")
("zenburn-blue-3" . "#5C888B")
("zenburn-blue-4" . "#4C7073")
("zenburn-blue-5" . "#366060")
("zenburn-magenta" . "#DC8CC3"))
"List of Zenburn colors.
Each element has the form (NAME . HEX).
`+N' suffixes indicate a color is lighter.
`-N' suffixes indicate a color is darker.")
ここから、下記の色を抜き出します。
- 最暗色・最明色
- ハイライト8色 (
yelloworangeredmagentavioletbluecyangreen)
とりあえず下記の色にしました。
- #3F3F3F #FFFFFD
- #F0DFAF #DFAF8F #CC9393 #DC8CC3 #6C3333 #8CD0D3 #93E0E3 #7F9F7F
init.elの編集
init.elに下記のleafを書きます。
(leaf solarized-theme
:ensure t
:when (version<= "24.1" emacs-version)
:custom ((solarized-distinct-fringe-background . t))
:defun (solarized-create-theme-file-with-palette solarized-color-blend)
:require t
:preface
(defun c/reload-theme ()
(interactive)
(let ((theme-name (save-excursion
(goto-char (point-min))
(re-search-forward "deftheme \\([^ ]*\\)")
(substring-no-properties (match-string 1)))))
(eval-buffer)
(load-theme (intern theme-name) t)))
:config
(solarized-create-theme-file-with-palette 'dark 'solarized-zenburn-dark
'("#3F3F3F" "#FFFFFD" ; base03 (02 01 00 0 1 2) base3
"#F0DFAF" "#DFAF8F" ; yellow orange
"#CC9393" "#DC8CC3" ; red magenta
"#6C3333" "#8CD0D3" ; violet blue
"#93E0E3" "#7F9F7F" ; cyan green
))
(load-theme 'solarized-zenburn-dark 'no-confirm))
なお、私は以下のinit.elを、 /.debug.emacs.d/solarized-theme/init.el に保存し、
emacs -q -l ~/.debug.emacs.d/solarized-theme/init.el で読み込みました。
;; ~/.debug.emacs.d/solarized-theme/init.el
;; you can run like 'emacs -q -l ~/.debug.emacs.d/{{pkg}}/init.el'
(when load-file-name
(setq user-emacs-directory
(expand-file-name (file-name-directory load-file-name))))
(prog1 "leaf"
(prog1 "install leaf"
(custom-set-variables
'(package-archives '(("org" . "https://orgmode.org/elpa/")
("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/"))))
(package-initialize)
(unless (package-installed-p 'leaf)
(package-refresh-contents)
(package-install 'leaf))))
(leaf solarized-theme
:ensure t
:when (version<= "24.1" emacs-version)
:custom ((solarized-distinct-fringe-background . t))
:defun (solarized-create-theme-file-with-palette solarized-color-blend)
:require t
:preface
(defun c/reload-theme ()
(interactive)
(let ((theme-name (save-excursion
(goto-char (point-min))
(re-search-forward "deftheme \\([^ ]*\\)")
(substring-no-properties (match-string 1)))))
(eval-buffer)
(load-theme (intern theme-name) t)))
:config
(solarized-create-theme-file-with-palette 'dark 'solarized-zenburn-dark
'("#3F3F3F" "#FFFFFD" ; base03 (02 01 00 0 1 2) base3
"#F0DFAF" "#DFAF8F" ; yellow orange
"#CC9393" "#DC8CC3" ; red magenta
"#6C3333" "#8CD0D3" ; violet blue
"#93E0E3" "#7F9F7F" ; cyan green
))
(load-theme 'solarized-zenburn-dark 'no-confirm))
すると、このようになりました。いい感じ!
