Emacs 折腾日记(十八)——改变Emacs的样貌

发布于:2025-03-18 ⋅ 阅读:(18) ⋅ 点赞:(0)

截止到上一篇文章为止,之前教程 的内容都看完了,虽然它的后记部分提供了一些后续进阶的内容需要我们自己读手册。但是我不太想继续在elisp上死磕了。看着自己学了那么久的elisp,但是自己的emacs仍然没有半点改变,这个时候各位读者的兴趣一定会大打折扣,是时候试试配置一下自己的emacs了。教程后记中提到的内容等配置的时候涉及到了再来了解吧

所谓人靠衣装马靠鞍,一个编辑器好不好用首先要看的就是它好不好看,对于难看的编辑器可能一眼就要给它发卡了——“你是一个很优秀的编辑器,但是我们不合适”。所有配置时第一件事就是将emacs变帅变好看。

emacs的基础配置

Emacs 在加载的时候会首先读取 ~/.emcas.d/init.el 中的代码。整个配置程序的入口就在这里。但是如果我们一股脑将所有代码都写在这个文件中日后想要维护肯定是不方便的,所以在写配置之前需要了解一些它的模块化

提供一个模块,我们只需要在代码文件最后的位置写上 (provide 'package-name) 这样的代码即可。这里的 provide。可以理解为导出,后面是导出模块的名称。在需要引入模块时,只需要添加一行 (require 'basic)

但是与其他语言类似,有时候会出现找不到对应的模块,这里涉及到一个查找路径的问题。Emacs 中加载路径被保存在变量 load-path 中。该变量是一个list,我们可以将指定路径放入到这个变量中来添加用户定义代码的路径。

load-path 中的目录顺序决定了 Emacs 搜索文件的优先级。如果多个目录中存在同名的 Lisp 文件,Emacs 会优先加载 load-path 中靠前的目录中的文件。因此,你可以通过调整 load-path 的顺序来控制加载的优先级。

为了添加路径到 load-path 中,我们要了解一个新的函数, add-to-list。为什么这里我们不使用 push 或者其他之前学过的操作list的函数呢?最关键的一点是 add-to-list 具有去重的功能,能避免多次重复加入同一个路径。如果我们将用户代码放入到 ~/.emacs.d/lisp 这个目录中,我们可以使用下面的代码

;; init.el
(add-to-list 'load-path "~/.emacs.d/lisp")

前面的知识介绍完了,现在我们新建 ~/.emacs.d/lisp/basic.el 文件,进行基础的配置。目前添加的代码主要是取消Emacs上的滚动条、菜单栏、工具栏、以及每次打开的开始界面。

;; basic.el
;; 禁止菜单栏、工具栏、滚动条模式,禁止启动屏幕和文件对话框
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(setq inhibit-splash-screen t) ;; 禁止启动画面

;; 显示行号
(setq display-line-numbers-type 'relative) ;;显示相对行号
(global-display-line-numbers-mode 1)

(provide 'basic)

然后在启动的时候使用它

;; init.el
(add-to-list 'load-path "~/.emacs.d/lisp")
(require 'basic)

重启Emacs就能看到具体的效果了
emacs 启动界面

使用包管理器

要想它变的好看,最好的办法是加载开源大佬提供的主题。作为一个小菜鸡不太可能自己开发重型的功能,我们要做的这是将大佬提供的包整合到自己的配置中。所以我们先来介绍包和包管理器。

这里的包我们可以理解为提供了某种功能的模块,有点类似与C/C++ 的静态库或者Java的类库。

Emacs中的包管理主要通过 package.el 模块提供。它包含了模块的查找,下载,更新以及删除等操作。它的一些常用命令如下:

  • M-x list-packages:列出所有可用的包,并进入包管理界面。
  • M-x package-install:安装指定的包。
  • M-x package-refresh-contents:刷新包列表,获取最新的包信息。
  • M-x package-upgrade:更新所有已安装的包。
  • M-x package-delete:删除指定的包。

Emacs中默认的仓库是 Emacs 默认使用 MELPA(Milkypostman’s Emacs Lisp Package Archive)作为主要的包仓库。MELPA 提供了大量高质量的第三方包。除此之外,还有其他仓库,如:

  • GNU ELPA:官方仓库,包含 Emacs 自带的包。
  • MELPA Stable:提供稳定版本的包。
  • NonGNU ELPA:包含一些非 GNU 的包。

因为国内的网络环境,我们常常需要使用国内的源。这里我们创建一个新的文件 package 用来管理包。

;; package-conf.el
(require 'package)
(setq package-enable-at-startup nil)
(setq package-archives '(("gnu"    . "https://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
                         ("nongnu" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/nongnu/")
                         ("melpa"  . "https://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")))
(package-initialize) ;; You might already have this line
(provide 'package-conf)

这里我使用清华源,各位读者可以选择自己喜欢的源。

上面的代码我们使用 package-enable-at-startup 来控制Emacs是否自动初始化package包管理器。这里为了更灵活我们禁止它自动初始化,改由手动初始化。

我们可以在代码中使用类似于 (package-install 'package-name) 的方式来自动安装包,但是这里介绍更加高级的包管理器——use-package

如果使用Emacs原生的包管理器,那么就是先安装,然后想办法组织包配置的代码,这样将安装与配置分散起来了,不利于管理。使用use-package 可以方便的将它们组织起来。

本质上use-package 提供了一系列的宏将包的安装和包的配置组合到一起,方便维护。而且它还提供了一些高级的特性方便我们灵活的控制各种配置生效的时间。

我们可以使用如下语句进行安装

;; package-conf.el
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

它的基本语法如下:

(use-package package-name
  :keyword1 value1
  :keyword2 value2
  ...)

它的常用关键字如下:

  • :ensure: 确保包已安装。如果包未安装,use-package 会自动安装它,一般使用Emacs自带的包这里设置成nil,安装第三方的包,这里设置成t
  • :init:在包加载之前执行的代码
  • :config: 在包加载之后执行的代码
  • :bind: 为包中的函数绑定快捷键
  • :mode: 为特定文件类型启用包
  • :hook: 在特定模式下启用包
  • :defer: 延迟加载包,直到首次使用包
  • :custom: 设置包的变量

除了这些我们可以使用 :if:when 关键字实现更复杂的条件加载。或者通过 :requires 关键字来指定包的依赖项

配置主题

说了这么多,我们使用 use-package 来安装一个主题来提高一下Emacs的颜值。这里我选用 doom-themes 包中的 doom-dracula 主题。关于ui部分的配置,我们都放在 ~/.emacs.d/lisp/init-ui.el

;; init-ui.el
(use-package doom-themes
  :ensure t
  :config
  (load-theme 'doom-dracula t))
(provide 'init-ui)

我们在init.el 中加载init-ui之后,再次打开效果如下:
dracula 主题

设置字体

我们在介绍文本属性的时候使用过face这个属性,Emacs中跟文字显示相关的属性都是face,它包括:字体、字号、颜色、背景。我们之前介绍了一系列的函数来处理字体字号,但是之前介绍的只能绑定到具体的文字上,默认的字体字号使用那些函数是无法设置的。

我们可以使用 set-face-attribute 来设置字体属性。该函数的定义如下

(set-face-attribute FACE FRAME &rest ARGS)

参数face 表示设置的是哪个部分的字体属性,例如 default(默认字体) 、mode-line (状态栏字体)、region (选中区域字体)等。我们可以使用 M-x list-faces-display 来查看支持的face

参数 frame 表示需要设置哪个窗口框架(通常用 nil 表示当前窗口或所有窗口)的字体属性。

参数 ARGS 来设置具体的字体属性。
以下属性可用于控制字体和样式:

属性名 功能描述 示例值
:family 字体名称(需系统已安装) “Fira Code”, “Consolas”
:height 字号(以百分比或绝对点数表示,默认 100 = 10pt) 120(12pt), 14(14pt)
:weight 字重(如正常、加粗) 'normal, 'bold
:slant 字体倾斜 'normal, 'italic
:width 字体宽度(如压缩或扩展) 'normal, 'condensed
:underline 下划线样式 nil(无), t(实线)
:foreground 前景色(文本颜色) “#FFFFFF”, “red”
:background 背景色 “#333333”
:inherit 继承其他 FACE 的属性 'fixed-pitch

这里我打算使用 Source Code Pro 字体,可以在init-ui.el 中这么设置

(set-face-attribute 'default nil
		    :family "Source Code Pro"
		    :height 120)

到此为止我们已经给Emacs做了基本的美化,日常使用也不那么碍眼了。


网站公告

今日签到

点亮在社区的每一天
去签到