Dotfile: 用一个 Org 文件管理所有配置

Darksun这篇文章 里介绍了如何通过一个 org file 管理自己的各种配置文件. 思路简单来说, 就是通过 tangle org 文件的代码块, 将其插入座到它们应该在的 地方. 目前我主要使用的还是 Spacemacs 居多, 就试着在这篇文章中将其配置放到 一个 org file 中.


Spacemacs 就是 Emacs 的一套配置。它对 evil 的支持,它的文档完善程度,极大的 减少了 Emacs 的使用门槛, 让你可以将更多精力花在如何使用 Emacs/Org mode 上面.

首先确保你电脑上已经安装了 Emacs, 然后可以通过下面的命令将 Spacemacs 默 认配置下载到本地.

mv ~/.emacs.d ~/.emacs.d.bak
git clone ~/.emacs.d

Spacemacs 有两种配置方法, 一种是通过 ~/.spacemacs 文件, 将所有配置都在其 中. 另一种是可以通过 .spacemaacs.d 目录中的 ~/init.el 来配置. 我个人采用 的是第二种(需确保先删除 ~/.spacemacs 文件).

然后就可以开始你的个性化定制了, 这里分为两种定制, 一种是 小修 你通过修改 Spacemacs 变量配置来定制, 另一种是 大改 你通过 Spacemacs 的 layer 机制, 定制自己的使用场景.


Spacemacs 默认生成的 ~/.spacemacs 文件中有四个函数:

  1. dotspacemacs/layers :: 和 layer 相关的配置在这里, 在这里改一些变量值就行

    (defun dotspacemacs/layers ()
      "Configuration Layers declaration.
    You should not put any user code in this function besides modifying the
    variable values."
       ;; Base distribution to use. This is a layer contained in the directory
       ;; `+distribution'. For now available distributions are `spacemacs-base'
       ;; or `spacemacs'. (default 'spacemacs)
       dotspacemacs-distribution 'spacemacs
       ;; Lazy installation of layers (i.e. layers are installed only when a file
       ;; with a supported type is opened). Possible values are `all', `unused'
       ;; and `nil'. `unused' will lazy install only unused layers (i.e. layers
       ;; not listed in variable `dotspacemacs-configuration-layers'), `all' will
       ;; lazy install any layer that support lazy installation even the layers
       ;; listed in `dotspacemacs-configuration-layers'. `nil' disable the lazy
       ;; installation feature and you have to explicitly list a layer in the
       ;; variable `dotspacemacs-configuration-layers' to install it.
       ;; (default 'unused)
       dotspacemacs-enable-lazy-installation 'unused
       ;; If non-nil then Spacemacs will ask for confirmation before installing
       ;; a layer lazily. (default t)
       dotspacemacs-ask-for-lazy-installation t
       ;; If non-nil layers with lazy install support are lazy installed.
       ;; List of additional paths where to look for configuration layers.
       ;; Paths must have a trailing slash (i.e. `~/.mycontribs/')
       dotspacemacs-configuration-layer-path '()
       ;; List of configuration layers to load.
         (auto-completion :variables auto-completion-enable-sort-by-usage t
                          :disabled-for org markdown)
         (org :variables
              org-enable-reveal-js-support t
              org-download-screenshot-method "screencapture"
              org-download-image-dir "../images"
              org-download-heading-lvl nil
              org-download-timestamp "")
       ;; List of additional packages that will be installed without being
       ;; wrapped in a layer. If you need some configuration for these
       ;; packages, then consider creating a layer. You can also put the
       ;; configuration in `dotspacemacs/user-config'.
       dotspacemacs-additional-packages '()
       ;; A list of packages that cannot be updated.
       dotspacemacs-frozen-packages '()
       ;; A list of packages that will not be installed and loaded.
       dotspacemacs-excluded-packages '(org-projectile)
       ;; Defines the behaviour of Spacemacs when installing packages.
       ;; Possible values are `used-only', `used-but-keep-unused' and `all'.
       ;; `used-only' installs only explicitly used packages and uninstall any
       ;; unused packages as well as their unused dependencies.
       ;; `used-but-keep-unused' installs only the used packages but won't uninstall
       ;; them if they become unused. `all' installs *all* packages supported by
       ;; Spacemacs and never uninstall them. (default is `used-only')
       dotspacemacs-install-packages 'used-only))
  2. dotspacemacs/init :: Spacemacs 初始化的时候调用这里, 同样只在这里改一些变量值就行

    (defun dotspacemacs/init ()
      "Initialization function.
    This function is called at the very startup of Spacemacs initialization
    before layers configuration.
    You should not put any user code in there besides modifying the variable
       dotspacemacs-elpa-https t
       ;; Maximum allowed time in seconds to contact an ELPA repository.
       dotspacemacs-elpa-timeout 5
       dotspacemacs-check-for-update nil
       dotspacemacs-elpa-subdirectory nil
       ;; One of `vim', `emacs' or `hybrid'.
       dotspacemacs-editing-style 'vim
       ;; If non nil output loading progress in `*Messages*' buffer. (default nil)
       dotspacemacs-verbose-loading nil
       ;; 在这里修改你的启动显示图片
       dotspacemacs-startup-banner "~/Library/Mobile Documents/com~apple~CloudDocs/1-参考/8-Personal/head.png"
       ;; List of items to show in startup buffer or an association list of
       ;; the form `(list-type . list-size)`. If nil then it is disabled.
       ;; `recents' `bookmarks' `projects' `agenda' `todos'."
       ;; List sizes may be nil, in which case
       ;; `spacemacs-buffer-startup-lists-length' takes effect.
       dotspacemacs-startup-lists '((recents . 5)
                                    (projects . 3))
       ;; True if the home buffer should respond to resize events.
       dotspacemacs-startup-buffer-responsive t
       ;; Default major mode of the scratch buffer (default `text-mode')
       dotspacemacs-scratch-mode 'emacs-lisp-mode
       ;; List of themes, the first of the list is loaded when spacemacs starts.
       ;; 在这里设置你想的主题配色
       dotspacemacs-themes '(
       ;; If non nil the cursor color matches the state color in GUI Emacs.
       dotspacemacs-colorize-cursor-according-to-state t
       ;; Default font, or prioritized list of fonts. `powerline-scale' allows to
       ;; quickly tweak the mode-line size to make separators look not too crappy.
       dotspacemacs-default-font '("Source Code Pro"
                                   :size 15
                                   :weight normal
                                   :width normal
                                   :powerline-scale 1.1)
       ;; The leader key
       dotspacemacs-leader-key "SPC"
       ;; The key used for Emacs commands (M-x) (after pressing on the leader key).
       dotspacemacs-emacs-command-key "SPC"
       ;; The key used for Vim Ex commands (default ":")
       dotspacemacs-ex-command-key ":"
       ;; The leader key accessible in `emacs state' and `insert state'
       dotspacemacs-emacs-leader-key "M-m"
       ;; Major mode leader key is a shortcut key which is the equivalent of
       ;; pressing `<leader> m`. Set it to `nil` to disable it. (default ",")
       dotspacemacs-major-mode-leader-key ","
       ;; Major mode leader key accessible in `emacs state' and `insert state'.
       ;; (default "C-M-m")
       dotspacemacs-major-mode-emacs-leader-key "C-M-m"
       ;; These variables control whether separate commands are bound in the GUI to
       ;; the key pairs C-i, TAB and C-m, RET.
       ;; Setting it to a non-nil value, allows for separate commands under <C-i>
       ;; and TAB or <C-m> and RET.
       ;; In the terminal, these pairs are generally indistinguishable, so this only
       ;; works in the GUI. (default nil)
       dotspacemacs-distinguish-gui-tab nil
       ;; If non nil `Y' is remapped to `y$' in Evil states. (default nil)
       dotspacemacs-remap-Y-to-y$ nil
       ;; If non-nil, the shift mappings `<' and `>' retain visual state if used
       ;; there. (default t)
       dotspacemacs-retain-visual-state-on-shift t
       ;; If non-nil, J and K move lines up and down when in visual mode.
       ;; (default nil)
       dotspacemacs-visual-line-move-text nil
       ;; If non nil, inverse the meaning of `g' in `:substitute' Evil ex-command.
       ;; (default nil)
       dotspacemacs-ex-substitute-global nil
       ;; Name of the default layout (default "Default")
       dotspacemacs-default-layout-name "Default"
       ;; If non nil the default layout name is displayed in the mode-line.
       ;; (default nil)
       dotspacemacs-display-default-layout nil
       ;; If non nil then the last auto saved layouts are resume automatically upon
       ;; start. (default nil)
       dotspacemacs-auto-resume-layouts nil
       ;; Size (in MB) above which spacemacs will prompt to open the large file
       ;; literally to avoid performance issues. Opening a file literally means that
       ;; no major mode or minor modes are active. (default is 1)
       dotspacemacs-large-file-size 1
       ;; Location where to auto-save files. Possible values are `original' to
       ;; auto-save the file in-place, `cache' to auto-save the file to another
       ;; file stored in the cache directory and `nil' to disable auto-saving.
       ;; (default 'cache)
       dotspacemacs-auto-save-file-location 'cache
       ;; Maximum number of rollback slots to keep in the cache. (default 5)
       dotspacemacs-max-rollback-slots 5
       ;; If non nil, `helm' will try to minimize the space it uses. (default nil)
       dotspacemacs-helm-resize nil
       ;; if non nil, the helm header is hidden when there is only one source.
       ;; (default nil)
       dotspacemacs-helm-no-header nil
       ;; define the position to display `helm', options are `bottom', `top',
       ;; `left', or `right'. (default 'bottom)
       dotspacemacs-helm-position 'bottom
       ;; Controls fuzzy matching in helm. If set to `always', force fuzzy matching
       ;; in all non-asynchronous sources. If set to `source', preserve individual
       ;; source settings. Else, disable fuzzy matching in all sources.
       ;; (default 'always)
       dotspacemacs-helm-use-fuzzy 'always
       ;; If non nil the paste micro-state is enabled. When enabled pressing `p`
       ;; several times cycle between the kill ring content. (default nil)
       dotspacemacs-enable-paste-transient-state nil
       ;; Which-key delay in seconds. The which-key buffer is the popup listing
       ;; the commands bound to the current keystroke sequence. (default 0.4)
       dotspacemacs-which-key-delay 0.4
       ;; Which-key frame position. Possible values are `right', `bottom' and
       ;; `right-then-bottom'. right-then-bottom tries to display the frame to the
       ;; right; if there is insufficient space it displays it at the bottom.
       ;; (default 'bottom)
       dotspacemacs-which-key-position 'bottom
       ;; If non nil a progress bar is displayed when spacemacs is loading. This
       ;; may increase the boot time on some systems and emacs builds, set it to
       ;; nil to boost the loading time. (default t)
       dotspacemacs-loading-progress-bar t
       ;; If non nil the frame is fullscreen when Emacs starts up. (default nil)
       ;; (Emacs 24.4+ only)
       dotspacemacs-fullscreen-at-startup t
       ;; If non nil `spacemacs/toggle-fullscreen' will not use native fullscreen.
       ;; Use to disable fullscreen animations in OSX. (default nil)
       dotspacemacs-fullscreen-use-non-native nil
       ;; If non nil the frame is maximized when Emacs starts up.
       ;; Takes effect only if `dotspacemacs-fullscreen-at-startup' is nil.
       ;; (default nil) (Emacs 24.4+ only)
       dotspacemacs-maximized-at-startup nil
       ;; A value from the range (0..100), in increasing opacity, which describes
       ;; the transparency level of a frame when it's active or selected.
       ;; Transparency can be toggled through `toggle-transparency'. (default 90)
       dotspacemacs-active-transparency 90
       ;; A value from the range (0..100), in increasing opacity, which describes
       ;; the transparency level of a frame when it's inactive or deselected.
       ;; Transparency can be toggled through `toggle-transparency'. (default 90)
       dotspacemacs-inactive-transparency 90
       ;; If non nil show the titles of transient states. (default t)
       dotspacemacs-show-transient-state-title t
       ;; If non nil show the color guide hint for transient state keys. (default t)
       dotspacemacs-show-transient-state-color-guide t
       ;; If non nil unicode symbols are displayed in the mode line. (default t)
       dotspacemacs-mode-line-unicode-symbols t
       ;; If non nil smooth scrolling (native-scrolling) is enabled. Smooth
       ;; scrolling overrides the default behavior of Emacs which recenters point
       ;; when it reaches the top or bottom of the screen. (default t)
       dotspacemacs-smooth-scrolling t
       ;; Control line numbers activation.
       ;; If set to `t' or `relative' line numbers are turned on in all `prog-mode' and
       ;; `text-mode' derivatives. If set to `relative', line numbers are relative.
       ;; This variable can also be set to a property list for finer control:
       ;; '(:relative nil
       ;;   :disabled-for-modes dired-mode
       ;;                       doc-view-mode
       ;;                       markdown-mode
       ;;                       org-mode
       ;;                       pdf-view-mode
       ;;                       text-mode
       ;;   :size-limit-kb 1000)
       ;; (default nil)
       dotspacemacs-line-numbers nil
       ;; Code folding method. Possible values are `evil' and `origami'.
       ;; (default 'evil)
       dotspacemacs-folding-method 'evil
       ;; If non-nil smartparens-strict-mode will be enabled in programming modes.
       ;; (default nil)
       dotspacemacs-smartparens-strict-mode nil
       ;; If non-nil pressing the closing parenthesis `)' key in insert mode passes
       ;; over any automatically added closing parenthesis, bracket, quote, etc…
       ;; This can be temporary disabled by pressing `C-q' before `)'. (default nil)
       dotspacemacs-smart-closing-parenthesis nil
       ;; Select a scope to highlight delimiters. Possible values are `any',
       ;; `current', `all' or `nil'. Default is `all' (highlight any scope and
       ;; emphasis the current one). (default 'all)
       dotspacemacs-highlight-delimiters 'all
       ;; If non nil, advise quit functions to keep server open when quitting.
       ;; (default nil)
       dotspacemacs-persistent-server nil
       ;; List of search tool executable names. Spacemacs uses the first installed
       ;; tool of the list. Supported tools are `ag', `pt', `ack' and `grep'.
       ;; (default '("ag" "pt" "ack" "grep"))
       dotspacemacs-search-tools '("ag" "pt" "ack" "grep")
       ;; The default package repository used if no explicit repository has been
       ;; specified with an installed package.
       ;; Not used for now. (default nil)
       dotspacemacs-default-package-repository nil
       ;; Delete whitespace while saving buffer. Possible values are `all'
       ;; to aggressively delete empty line and long sequences of whitespace,
       ;; `trailing' to delete only the whitespace at end of lines, `changed'to
       ;; delete only whitespace for changed lines or `nil' to disable cleanup.
       ;; (default nil)
       dotspacemacs-whitespace-cleanup 'trailing
  3. dotspacemacs/user-init :: 你自己的配置可以放这里, 在各种 package 装载之前执行

    (defun dotspacemacs/user-init ()
      "Initialization function for user code.
    It is called immediately after `dotspacemacs/init', before layer configuration
     This function is mostly useful for variables that need to be set
    before packages are loaded. If you are unsure, you should try in setting them in
    `dotspacemacs/user-config' first."
      ;; 默认源太慢了, 建议使用子龙山人的国内镜像源
      (setq configuration-layer--elpa-archives
            '(("melpai-cn" . "")
              ("org-cn"   . "")
              ("gnu-cn" . "")))
      ;; 指定自己的 layer 路径
      (setq dotspacemacs-configuration-layer-path "~/.spacemacs.d/layers/")
      ;; 新版插入 source code 快捷键需要这个
      (require 'org-tempo)
      ;; 解决 spacemacs 从 elpa 加载 org 和 emacs 自带 org 版本不一致的冲突
      ;; 可以从源下载最新版本的 Org,并指定该版本的路径
      ;; $ cd ~/src/
      ;; $ git clone
      ;; $ cd org-mode/
      ;; $ make autoloads
      (add-to-list 'load-path "~/Library/Mobile Documents/com~apple~CloudDocs/org/org-mode/lisp")
      ;; 大佬不喜欢 melpa, 插件需要保存到本地, 单独为大佬的插件设置一下存放地址
      (add-to-list 'load-path "~/Library/Mobile Documents/com~apple~CloudDocs/org/ljg-packages")
      (require 'insert-translated-name)
  4. dotspacemacs/user-config :: 你大多数的配置应该放在这里

    (defun dotspacemacs/user-config ()
      "Configuration function for user code.
    This function is called at the very end of Spacemacs initialization after
    layers configuration.
    This is the place where most of your configurations should be done. Unless it is
    explicitly specified that a variable should be set before a package is loaded,
    you should place your code here."
      ;; org-mode 相关设置 ;;
      ;; Since version 0.104, spacemacs uses the org version from the org ELPA
      ;; repository instead of the one shipped with emacs. Then, any org related
      ;; code should not be loaded before dotspacemacs/user-config, otherwise both
      ;; versions will be loaded and will conflict. Because of autoloading, calling
      ;; to org functions will trigger the loading up of the org shipped with emacs
      ;; which will induce conflicts. One way to avoid conflict is to wrap your org
      ;; config code in a with-eval-after-load block like this:
      (with-eval-after-load 'org
        ;; 设置 todo keywords
        (setq org-todo-keywords
              '((sequence "TODO" "HAND" "|" "DONE")))
        ;; 调试好久的颜色,效果超赞!todo keywords 增加背景色
        (setf org-todo-keyword-faces '(("TODO" . (:foreground "white" :background "#95A5A6"   :weight bold))
                                       ("HAND" . (:foreground "white" :background "#2E8B57"  :weight bold))
                                       ("DONE" . (:foreground "white" :background "#3498DB" :weight bold))))
        ;; 设置 bullet list
        (setq org-bullets-bullet-list '("☰" "☷" "☯" "☭"))
        ;; 打开 org-indent mode
        (setq org-startup-indented t)
        ;; Let's have pretty source code blocks
        (setq org-edit-src-content-indentation 0
              org-src-tab-acts-natively t
              org-src-fontify-natively t
              org-confirm-babel-evaluate nil
              org-support-shift-select 'always)
        ;; Org archive
        (setq org-archive-location "%s_archive::date-tree")
        (defadvice org-archive-subtree
          (around org-archive-subtree-to-data-tree activate)
          "org-archive-subtree to date-tree"
              (string= "date-tree"
              (let* ((dct (decode-time (org-current-time)))
                    (y (nth 5 dct))
                    (m (nth 4 dct))
                    (d (nth 3 dct))
                    (this-buffer (current-buffer))
                    (location (org-get-local-archive-location))
                    (afile (org-extract-archive-file location))
                      (format "%s::*** %04d-%02d-%02d %s" afile y m d
                              (format-time-string "%A" (encode-time 0 0 0 d m y)))))
                (message "afile=%s" afile)
                (unless afile
                  (error "Invalid `org-archive-location'"))
                  (switch-to-buffer (find-file-noselect afile))
                  ;; (org-datetree-find-year-create y)
                  ;; (org-datetree-find-month-create y m)
                  ;; (org-datetree-find-day-create y m d)
                  (switch-to-buffer this-buffer))
        ;; Agenda clock report parameters
        (setq org-agenda-prefix-format '((agenda . "%t %s ")))
        (setq org-agenda-clockreport-parameter-plist
              '(:link t :maxlevel 6 :fileskip0 t :compact t :narrow 60 :score 0))
        (setq org-agenda-start-on-weekday nil)
        (setq org-agenda-log-mode-items '(clock))
        (setq org-agenda-include-all-todo t)
        (setq org-agenda-time-leading-zero t)
        (setq org-agenda-use-time-grid nil)
        (setq org-agenda-include-diary nil)
        (setq org-agenda-files (list  "~/Library/Mobile Documents/com~apple~CloudDocs/org/"
                                      "~/Library/Mobile Documents/com~apple~CloudDocs/org/gtd.org_archive"))
        (setq org-default-notes-file "~/Library/Mobile Documents/com~apple~CloudDocs/org/")
        (setq org-refile-targets '("~/Library/Mobile Documents/com~apple~CloudDocs/org/" :maxlevel . 3))
        ;; 使用 reveal.js 来生成 html 版本的 ppt
        (require 'ox-reveal)
        (setq org-reveal-root (concat (expand-file-name "~/Library/Mobile Documents/com~apple~CloudDocs/org/reveal.js")))
        (setq org-reveal-theme "black")
        (setq org-reveal-control t)
        (setq org-reveal-center t)
        (setq org-reveal-progress t)
        ;; 设置快捷键
        (evil-leader/set-key "oc" 'org-capture)
        (evil-leader/set-key "oa" 'org-agenda)
        (evil-leader/set-key "ol" 'org-store-link)
        (evil-leader/set-key "el" 'eval-print-last-sexp)
        (evil-leader/set-key "od" 'org-archive-subtree)
        (evil-leader/set-key "oip" 'org-set-property)
        (evil-leader/set-key "oil" 'org-insert-link)
        (evil-leader/set-key "ois" 'org-time-stamp)
        (evil-leader/set-key "oid" 'org-insert-drawer)
        (evil-leader/set-key "oif" 'org-footnote-action)
        (evil-leader/set-key "oog" (lambda () (interactive) (find-file "~/Library/Mobile Documents/com~apple~CloudDocs/org/")))
        (evil-leader/set-key "ool" (lambda () (interactive) (find-file "~/.spacemacs.d/layers/lijigang/packages.el")))
        (evil-leader/set-key "oit" 'insert-day-progress)
        (global-set-key (kbd "C--") 'org-table-insert-hline)
      ;; 显示相关 ;;
      ;; 在状态栏显示时间
      (display-time-mode 1)
      ;; 折叠时不再显示「...」
      (setq org-ellipsis "▼")
      ;; inline image 不用展示实际大小,可以自定义大小显示
      (setq org-image-actual-width nil)
      (global-hl-line-mode -1)
      (setq-default fill-column 72)
      ;; 打开黄金比例模式, 当前使用的窗口所占比例为 0.618
      ;; 默认把新开的 Window 显示在右侧
      (setq split-height-threshold nil)
      (setq split-width-threshold 0)
      ;; Remove the markup characters, i.e., "/text/" becomes (italized) "text"
      (setq org-hide-emphasis-markers t)
      ;; Turn on visual-line-mode for Org-mode only
      ;; Also install "adaptive-wrap" from elpa
      (add-hook 'org-mode-hook 'turn-on-visual-line-mode)
      ;; more useful frame title, that show either a file or a
      ;; buffer name (if the buffer isn't visiting a file)
      (setq frame-title-format
            '("" " 為學日益, 為道日損 - "
              (:eval (if (buffer-file-name)
                         (abbreviate-file-name (buffer-file-name)) "%b"))))
      ;; 导出相关 ;;
      ;; 安装 XeLaTeX 是另外一个故事了..
      (setq Tex-command-default "XeLaTeX")
      ;; 文学编程相关 ;;
      ;; Tangle Org files when we save them
      (defun tangle-on-save-org-mode-file()
        (when (string= (message "%s" major-mode) "org-mode")
      (add-hook 'after-save-hook 'tangle-on-save-org-mode-file)
      ;; Enable the auto-revert mode globally. This is quite useful when you have
      ;; multiple buffers opened that Org-mode can update after tangling.
      ;; All the buffers will be updated with what changed on the disk.
      ;; 其它杂项 ;;
      (setq default-major-mode 'org-mode)
      (prefer-coding-system 'utf-8)
      (set-default-coding-systems 'utf-8)
      (setq default-buffer-file-coding-system 'utf-8)
      ;; 时间戳使用英文星期
      (setq system-time-locale "C")
      ;; Agenda clock report parameters
      (setq org-agenda-clockreport-parameter-plist
            '(:link t :maxlevel 6 :fileskip0 t :compact t :narrow 60 :score 0))
      (setq org-hierarchical-todo-statistics nil)
      ;; stop emacs asking for confirmation when eval source code
      (setq org-confirm-babel-evaluate nil)
      ;; active Org-babel languages
       '(;; other Babel languages
         (emacs-lisp . t)
         (ditaa . t)
         (python . t)
         (shell . t)
         (plantuml . t)))
      ;; ;;
      ;; artist-mode 左键不能画, 状态问题                  ;;
      (defun artist-mode-toggle-emacs-state ()
        (if artist-mode
      (unless (eq dotspacemacs-editing-style 'emacs)
        (add-hook 'artist-mode-hook #'artist-mode-toggle-emacs-state))
      (global-visual-line-mode 1)
      (setq org-ditaa-jar-path "~/Library/Mobile Documents/com~apple~CloudDocs/org/org-mode/contrib/scripts/ditaa.jar")
      (setq org-plantuml-jar-path
            (expand-file-name "~/Library/Mobile Documents/com~apple~CloudDocs/org/org-resources/plantuml.jar"))


Spacemacs 默认支持了很多的 layer, 常用的功能组合场景都已经设置的很赞了, 只 需要在 小修 里配置相应的 layer 就可以开箱即用. 但总有一些自己独有的需求, 需要按需定制自己的 layer.

官方文档上面对 package 和 layer 的解释:

Layers and packages. What gives?


A set of Emacs Lisp files that, taken together, provide some feature. Packages may be available on a package repository, such as ELPA or MELPA or on a third-party service provider (such as github) or even locally on the disk.


A collected unit of configuration that can be enabled (or disabled) in Spacemacs. A layer typically brings together one or more packages, as well as the glue configuration code required to make them play well with each other and Spacemacs in general.

A layer is simply a folder somewhere in Spacemacs’ layer search path that usually contains these files (listed in loading order).

layers.el declare additional layers

packages.el the packages list and configuration

funcs.el all functions used in the layer should be declared here

config.el layer specific configuration

keybindings.el general key bindings


;;; Code:

(defconst lijigang-packages

(defun lijigang/init-org-page()
  "Initialize org-page to publish blog."
  (use-package org-page
    :ensure t
    :config (progn
          (setq op/site-main-title "遁其一")
          (setq op/personal-github-link "")
          (setq op/repository-directory "~/lijigang")
          (setq op/site-domain "")
          (setq op/theme-root-directory (car (file-expand-wildcards "~/.emacs.d/elpa/org-page-*/themes" t)))
          (setq op/theme 'ljg)
          (setq op/highlight-render 'js)
          (setq op/category-ignore-list '("themes" "assets" "images"))
          (setq op/category-config-alist
              :show-meta t
              :show-comment t
              :uri-generator op/generate-uri
              :uri-template "/blog/%y/%m/%d/%t/"
              :sort-by :date     ;; how to sort the posts
              :category-index nil) ;; generate category index or not
              :show-meta nil
              :show-comment nil
              :uri-generator op/generate-uri
              :uri-template "/"
              :sort-by :date
              :category-index nil)
              :show-meta nil
              :show-comment nil
              :uri-generator op/generate-uri
              :uri-template "/about/"
              :sort-by :date
              :category-index nil)))
          (bind-key "C-c M-p" 'op/do-publication-and-preview-site)))

(defun lijigang/init-dired-icon ()
  "Initialize dired-icon"
  (add-hook 'dired-mode-hook 'dired-icon-mode)
  (add-hook 'dired-mode-hook
            (lambda ()
              (highlight-lines-matching-regexp "\.org$" 'hi-yellow))))

(defun lijigang/init-cnfonts()
  "Initialize cnfonts"
  (use-package cnfonts

(defun lijigang/init-swiper()
  "Initialize swiper"
  (use-package swiper
    (define-key global-map (kbd "C-s") 'swiper)))

(defun lijigang/init-wttrin()
  (use-package wttrin
    :ensure t
    :commands (wttrin)
    (setq wttrin-default-cities '("Beijing"

(defun lijigang/init-beacon()
  "Initialize beacon"
  (use-package beacon
    (beacon-mode 1)
    (setq beacon-color "#666600")))

(defun lijigang/init-pangu-spacing()
  "Initialize pangu-spacing"
  (use-package pangu-spacing
    (global-pangu-spacing-mode 1)
    (setq pangu-spacing-real-insert-separtor t)))

(defun lijigang/init-pyim()
  "Initialize pyim"
  (use-package pyim
    :ensure nil
    :demand t
    (setq pyim-punctuation-translate-p '(no yes auto))
    (setq default-input-method "pyim")
    (setq pyim-default-scheme 'wubi)

    ;; 让 Emacs 启动时自动加载 pyim 词库
    (add-hook 'emacs-startup-hook
              #'(lambda () (pyim-restart-1 t)))

    (setq pyim-page-tooltip 'posframe)
    (setq pyim-dicts '((:name "基础词库" :file "~/Library/Mobile Documents/com~apple~CloudDocs/3-config/wbdict.pyim")))
    (global-set-key (kbd "C-9") 'toggle-input-method)

(defun lijigang/init-posframe ()
  (use-package posframe))
;;; packages.el ends here


(defun make-progress (width percent has-number?)
  (let* ((done (/ percent 100.0))
         (done-width (floor (* width done))))
     (make-string done-width ?/)
     (make-string (- width done-width) ? )
     (if has-number? (concat " " (number-to-string percent) "%"))

(defun insert-day-progress ()
  (let* ((today (time-to-day-in-year (current-time)))
         (percent (floor (* 100 (/ today 365.0)))))
    (insert (make-progress 30 percent t))

;; latex 支持中文
(require 'ox)
(require 'ox-html)
(require 'ox-publish)

(add-to-list 'org-latex-classes '("pdf" "\\documentclass[fontset = mac]{ctexart}
            headheight=15pt    % 标准中没有要求页眉的高度,这里设置成
                               % 15pt 了
\\setCJKmainfont[BoldFont={Microsoft YaHei},ItalicFont={Microsoft YaHei}]{Microsoft YaHei}
                  ("\\section{%s}" . "\\section*{%s}")
                  ("\\subsection{%s}" . "\\subsection*{%s}")
                  ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
                  ("\\paragraph{%s}" . "\\paragraph*{%s}")
                  ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))

(setq org-latex-default-class "pdf")

(setq org-latex-pdf-process
        "xelatex -interaction nonstopmode -output-directory %o %f"
        "xelatex -interaction nonstopmode -output-directory %o %f"
        "xelatex -interaction nonstopmode -output-directory %o %f"
        "rm -fr %b.out %b.log %b.tex auto"

(defun peng-use-xelatex ()
  (let* ((tempfile
      (file-name-base))) (progn (shell-command (concat "rm -rf " tempfile
                               ".bbl " tempfile ".blg " tempfile ".out " tempfile ".log " tempfile
                               ".aux " tempfile ".toc" tempfile ".pdf"))
                    (compile (concat "xelatex "
                             (concat tempfile ".tex")
                             (concat ";rm -rf " tempfile ".bbl " tempfile
                                 ".blg " tempfile ".out " tempfile ".log " tempfile ".aux " tempfile
".toc" ";open " tempfile ".pdf"))))))


(add-to-list 'auto-mode-alist '("\\.org_archive\\'" . org-mode))


(evil-leader/set-key "op" 'org-pomodoro)

 (kbd "C-c p")
 (defhydra hydra-blog (:color blue :hint nil)
    blog  _n_: new post                        _l_: publish last commit
          _r_: reset & publish all             _p_: publish interactively
          _t_: reset & publish to /tmp/blog    _e_: new-repository
   ("n" op/new-post)
   ("r" (progn
          (setq op/item-cache nil)
          (op/do-publication t nil nil t t)))
   ("t" (progn
          (setq op/item-cache nil)
          (op/do-publication t "/tmp/blog" nil t nil)))
   ("l" (op/do-publication nil "HEAD~1" nil t t))
   ("p" op/do-publication)
   ("e" op/new-repository)))


除了 Emacs, Shell 的配置也是比较需要跨机器使用的. 本着拿来主义精神, 我平时以 oh-my-shell 为主:

安装 oh-my-shell

git clone ~/.oh-my-zsh

备份现有的配置文件 ~/.zshrc

mv ~/.zshrc ~/.zshrc.bak


touch ~/.zshrc
# Path to your oh-my-zsh installation.
export ZSH="$HOME/.oh-my-zsh"

# 设置主題


source $ZSH/

将 zsh 设置为默认 shell

chsh -s /bin/zsh


配置一个喜欢的 iTerm 主題配色文件:

touch ~/Arthur.itermcolors
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">
    <key>Ansi 0 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 1 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 10 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 11 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 12 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 13 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 14 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 15 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 2 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 3 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 4 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 5 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 6 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 7 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 8 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Ansi 9 Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Background Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Bold Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Cursor Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Cursor Text Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Foreground Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Selected Text Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>
    <key>Selection Color</key>
      <key>Blue Component</key>
      <key>Green Component</key>
      <key>Red Component</key>

在 iTerm 的配置中, Preferences -> Profiles -> Colors -> Color presets -> Import 选中 Arthur.itemcolors.

然后选择导入的 Arthur 主題即可.