在Spacemacs里添加自定义Layer

使用Spacemacs时你可能会发现通过package-install安装的包在重启emacs后消失了。这是因为Spacemacs以Layer的形式自动管理需要的包,这样就避免了Emacs随着使用逐渐变得臃肿。若需要保留安装的包就需要用到自定义Layer。

在Spacemacs里添加自定义Layer非常容易,只需要简单的几步:

  1. 使用configuration-layer/create-layer命令让spacemacs自动创建自定义Layer所需文件。
  2. 编辑自动生成的pacakge.el文件并保存。
  3. 在spacemacs的配置文件里启用自定义Layer。

下面以添加名为openscad的Layer为例,介绍何操作。

新建自定义Layer

按下SPC SPC 后输入 configuration-layer/create-layer,(提示:实际你并不需要输入这么长的命令,通常只需要输入create-layer的几个字符可以在备选列表里找到这个命令了)。

  • 接下来会询问自定义Layer的保存位置,可使用默认的位置~/.emacs.d/private
  • 然后需要输入自定义Layer的名称,这里输入openscad
  • 然后询问是否要生成README文件。
  • 完成后Spacemacs会自动创建自定义Layer的所有的文件,并自动打开新建的package.el文件。

编辑pacakge.el文件

  • openscad-packages后面添加需要用到的emacs包,即通常使用package-install安装的包。我这里打算使用scad-modescad-preview两个包,
    (defconst openscad-packages
      '(scad-mode
        scad-preview)
    
      " ... ")
    
  • 然后还需要为每个包定义初始化函数,函数必须以openscad/init-PACKAGE形式命名。如何初始化可参考相应包的文档,大部分包通常只需使用use-package加载,
(defun openscad/init-scad-mode ()
  (use-package scad-mode)
  (add-to-list 'auto-mode-alist '("\\.scad$" . scad-mode)))

(defun openscad/init-scad-preview ()
  (use-package scad-preview))

启用自定义Layer

  • 使用SPC f e d打开spacemacs的配置文件,找到dotspacemacs-configuration-layers,在其后的list里添加openscad
  • 使用SPC f e R重新加载spacemacs配置或重启emacs后spacemacs会自动安装需要的包并启用。

openscad 示例

下面是~/.emacs.d/private/openscad/packages.el的完整代码:

;;; packages.el --- openscad layer packages file for Spacemacs.
;;
;; Copyright (c) 2012-2020 Sylvain Benner & Contributors
;;
;; Author: garfield <[email protected]>
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;;; License: GPLv3

;;; Commentary:

;; See the Spacemacs documentation and FAQs for instructions on how to implement
;; a new layer:
;;
;;   SPC h SPC layers RET
;;
;;
;; Briefly, each package to be installed or configured by this layer should be
;; added to `openscad-packages'. Then, for each package PACKAGE:
;;
;; - If PACKAGE is not referenced by any other Spacemacs layer, define a
;;   function `openscad/init-PACKAGE' to load and initialize the package.

;; - Otherwise, PACKAGE is already referenced by another Spacemacs layer, so
;;   define the functions `openscad/pre-init-PACKAGE' and/or
;;   `openscad/post-init-PACKAGE' to customize the package as it is loaded.

;;; Code:

(defconst openscad-packages
  '(
    scad-mode
    scad-preview)
  "The list of Lisp packages required by the openscad layer.

Each entry is either:

1. A symbol, which is interpreted as a package to be installed, or

2. A list of the form (PACKAGE KEYS...), where PACKAGE is the
    name of the package to be installed or loaded, and KEYS are
    any number of keyword-value-pairs.

    The following keys are accepted:

    - :excluded (t or nil): Prevent the package from being loaded
      if value is non-nil

    - :location: Specify a custom installation location.
      The following values are legal:

      - The symbol `elpa' (default) means PACKAGE will be
        installed using the Emacs package manager.

      - The symbol `local' directs Spacemacs to load the file at
        `./local/PACKAGE/PACKAGE.el'

      - A list beginning with the symbol `recipe' is a melpa
        recipe.  See: https://github.com/milkypostman/melpa#recipe-format")

(defun openscad/init-scad-mode ()
  (use-package scad-mode)
  (add-to-list 'auto-mode-alist '("\\.scad$" . scad-mode)))

(defun openscad/init-scad-preview ()
  (use-package scad-preview))

;;; packages.el ends here