呃……一般来说大家都叫“配置文件”,是吧。当然我也是这么叫的。那就让我们还是继续延续这个名字,就叫 Emacs配置文件。
那么配置文件是我们定制和扩展Emacs最重要的地方,一般来说,最常用的配置文件是 =.emacs= 。当然也可以是别的文件,具体可以查阅 GNU Emacs Manual。
然而随着使用的日久,日积月累,定制的设置越来越多, =.emacs= 变得越来越庞大,渐渐的就会增大到难以维护的地步。直到某日在 emacser.cn 看到王纯业的 组织 .emacs 的文件内容的技巧 ,将配置信息分成多个文件,维护的困难才稍稍得以缓解。但是即使是拆分以后,文件仍然会变得很大,而且还在不断增大,维护起来仍然压力很大。有没有好的解决办法呢? ahei 的DEA我还没有去仔细看过,毕竟他那个太大了,我的配置还没有大到那个地步。我希望的是简洁高效的解决办法。能够在我的配置文件里面只有我最关心的内容,不带一点多余的东西呢?
直到最近开始着手探索 Lisp,体会到 Lisp语言强大的描述能力和抽象能力,随即萌发了将众多的配置细节直接用写成简洁清晰的 =list= ,然后用 Lisp Code进行处理,这样就可以去掉配置文件里面那些无穷无尽的方法调用了。 走了这个路子之后,原来的“配置文件”就摇身一变,变成“配置程序”了。
.emacs
闲话不说了,开始捞干的吧。让我们先从最基本的 =.emacs= 开始。在这种方式下 =.emacs= 文件就非常简单了。它的核心部分一共只有两行。
(mapc ' load (directory-files "~/Shell/config/emacs.init" t "^[a-zA-Z0-9].*.el$"))
第一行通过 =load-path= 注册扩展文件的所在位置。第二行通过 =mapcar= 函数逐个装载 "=~/Shell/config/emacs.init=" 目录下的所有配置文件。就是这么简单。其余的内容多数都是 Emacs Customization 添加的代码。或者换句话说,现在的 =.emacs= 文件完全留给 Emacs用了。
其实在采用这种方式之前,我是不用什么 Customization 的。当然,不用的代价是显而易见的。问题在于在原来那种配置方式之下, =.emacs= 本身就已经够烦够乱了,如果 Emacs的 Customization 再往里面添乱,就更难维护和控制了。不过现在没事了。我自己使用的一共只有两行,剩下的所有地方随便它写吧。所以呢,我现在至少还用 Customization修改了一下 ansi-color,默认颜色里面的深蓝色的目录实在是太刺眼了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
;; custom - set - variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won ' t work right.
' (ansi-color-faces-vector [default default default italic underline bold bold-italic modeline])
' (ansi-color-names-vector ["black" "red" "PaleGreen" "yellow" "DodgerBlue1" "magenta" "cyan" "white"]))
另外,还有一个地方需要提到一下, 在 =.emacs= 里面我还保留了一段中文字体的设置。以前 emacser.com 里面有人发过字体设置的东西。但是由于 GNU Emacs 23以后基本都在 daemon方式下工作,如果直接使用原来那种方式设置中文字体的话,在 emacsclient中是无效的,所以要把它加到 =make-frame= 的hook里面。这样每次 =emacsclient -c= 生成的 frame就都是指定的中文字体了。 当然这下面这个函数还有一个缺陷,就是如果不是使用 daemon 方式的话…… 你懂得,鱼和熊掌,不可兼得。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
(lambda(arg)
( if ( >= (length (frame - list)) 1 )
( set - fontset - font " fontset-startup " ' chinese-gbk (font-spec :family "文泉驿微米黑") nil ' prepend)
)
) t
)
color-theme.el
那么我自己的配置信息写在哪些地方呢?让我们看看 "=~/Shell/config/emacs.init="目录下的都有哪些文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
dove@bash - 4.1 $ du - sh * .el
8 .0K calendar - setup.el
28K color - theme.el
28K dove - ext.el
4 .0K keybindings.el
8 .0K org - mode.el
8 .0K plugins.el
4 .0K settings.el
2 : 2024 : 13 : 03 : 35 : ~/ Shell / config / emacs.init
dove@bash - 4.1 $ du - sh .emacs
4 .0K .emacs
2 : 2025 : 13 : 04 : 07 : ~/ Shell / config / emacs.init
dove@bash - 4.1 $
就是这些地方了。每个文件的作用从文件名上就能清晰的看出来。只有这个"=dove-ext.el="文件需要解释一下,这里存放的是我自己编写的所有扩展函数。
下面让我们逐个看一看这些文件的内容。"=calendar-setup.el=" 就不说了,这个文件基本上就是从网上搜来的,我自己也就是定义几个节日而已。
"=color-theme.el=" 是主题设置文件。基本上就是 =color-theme-gnome2= 的翻版,我自己做了一些简单的修改。之所以把他存在一个单独的文件里面主要是因为 =color-theme= 实在是太长了,放在哪个文件里都会影响其他的内容。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
(defun my - color - theme ()
" Color theme created 2010-04-09. "
; (interactive)
(color - theme - install
' (my-color-theme
; ((background - color . " #102C29 " )
((background - color . " darkslategrey " )
; (( background - color . " black " )
(background - mode . dark)
(border - color . " black " )
(cursor - color . " LightGray " )
; ... ... ... ... theme 太长,中间省略了
(woman - bold - face ((t (:bold t :weight bold))))
(woman - italic - face ((t (:foreground " beige " ))))
(woman - unknown - face ((t (:foreground " LightSalmon " ))))
(zmacs - region ((t (:background " dark cyan " :foreground " cyan " )))))))
(eval - when - compile (require ' color-theme))
(color - theme - initialize)
(add - hook ' after-make-frame-functions
(lambda (arg)
""
(my - color - theme)) t)
另外我在加载 color-theme 的时候做了一个处理,把 =my-color-theme= 加到 =after-make-frame-functions= 这个 hook里面去,这样只有创建 frame的时候才会执行 =my-color-theme= 。 如果不是 =X= 环境,例如用 =emacs -nw= 的时候,就不要加载 =my-color-theme= 了。因为这个主题到了终端模式下,那个背景颜色根本没法看(汗一个)。虽然偶自己从来都是工作在 =X= 里面的。
这个问题在网上找到的有些解决办法是判断一下是不是 =window-system= ,这种办法到了 daemon模式下是会出错的。看来 Emacs 23 以后的 daemon 模式下的配置方法还是需要进一步深入研究的。什么东西都放到 =after-make-frame-functions= 这个地方毕竟也不是个事儿。
settings.el
下一个来看的是 settings.el。 settings 的任务其实很简单,就是设置全局变量。全局变量的设置就是 =setq= 嘛。这个事情简单的不能再简单了。但是无数的 =setq= 无论是写起来还是读起来都会让人很郁闷。还好,我们记得 =setq= 不但可以设置一个变量,它实际上可以处理一个 =list= 。嗨,既然说它可以,为什么还要让他闲着呢? 让我们动手吧,把所有的变量和值写在一个 =list= 里面,多余的 =setq= 通通都删掉吧。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
(tool - bar - mode - 1 )
(icomplete - mode 1 )
(scroll - bar - mode - 1 )
;(ruler - mode - 1 )
(setq save - abbrevs t
x - select - enable - clipboard t
ispell - dictionary " english "
frame - title - format " %b %n %I "
inhibit - startup - message t
column - number - mode t
; ... ... ... ... 内容太多,中间省略
ido - toggle - regexp t
dim: switch - window - relative nil
shell - file - name " /usr/bin/bash "
default - major - mode ' text-mode
)
;; Misc
(setq - default abbrev - mode t
line - spacing 4
)
(setenv " EMACSSHELL " shell - file - name)
未完待续 …… ……