如何配置 spacemacs 使其在启动时执行代码?

How to configure spacemacs so that it executes code when you start it?

前言

我知道这个标题看起来很主观,但我希望这个问题能够为新手顺利介绍 spacemacs 而不是 来自 emacs(我就是这样)。

您可能想知道为什么我决定使用 spacemacs,它是对 emacs 的高度自定义 hack,而不是先花时间去习惯 vanilla emacs。好吧,事实上,我已经尝试使用 emacs 和 vim 很长时间了,因为我可以理解为什么这些软件能够提高生产力并让你感觉更好 "at home" 当 coding/hacking.
不幸的是,当我开始有点习惯 vim 时,您需要花在学习上的时间,最重要的是,您需要花在 配置 上的时间那些软件,对我来说太贵了。
然后我发现了 spacemacs,它吸收了 vim 中的一些优点,emacs 中的一些优点,并将它们组合成一个很好的 mostly预配置包。

问题是大部分配置都是通过emacs-lisp完成的,并希望用户在启动软件时了解代码是如何加载和执行的,我完全不了解(因为我开始意识到我越来越深入地研究代码)。

我想达到的目标

我希望能够启动 emacs,并看到它执行我编写的一些自定义代码,以便:

我希望能够在必要时实际编写这些功能(可能还有许多其他功能)的代码,或者在它们可用时安装它们。

我试过的

(以及什么不起作用)

(天真地)像任何lisp/emacs新手一样配置我的spacemacs:

(defun dotspacemacs/user-config ()
  "Configuration function for user code.
 This function is called at the very end of Spacemacs initialization after
layers configuration. You are free to put any user code."

  ;; TODO
  ;; - Display whitespaces
  ;; - Install workgroups2

  ;; interface  ;; this works
  (setq powerline-default-separator 'arrow)

  ;; mouse scroll  ;; this works? maybe
  (setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) ;; one line at a time
  (setq mouse-wheel-progressive-speed nil) ;; don't accelerate scrolling

  ;; middle click copy-paste  ;; this works
  (setq x-select-enable-primary t)

  ;; diff-hl  ;; this used to work but now does not
  (diff-hl-flydiff-mode)
  (setq diff-hl-side 'left)

  ;; rust  ;; this works (and seems the right way to do it)
  (add-hook 'rust-mode-hook #'racer-mode)
  (add-hook 'racer-mode-hook #'eldoc-mode)

  ;; neotree  ;; this works? maybe
  (setq neo-show-hidden-files nil)

  ;; toggle preferences  ;; this does not work
  (spacemacs/toggle-automatic-symbol-highlight-on)
  (spacemacs/toggle-line-numbers-on)

  ;; COrrect DOuble CAps  ;; this does not works either (should be a hook)
  (doublecaps-mode 1)
)

问题

我意识到有一个叫做 "major-modes" 和 "minor-modes" 的概念分别适用于所有缓冲区或仅适用于特定的缓冲区实例,但我也很困惑 emacs 有它的事实拥有全局变量和局部变量(似乎可以通过 (setq) 自定义),spacemacs 也有自定义变量或方法 (spacemacs/toggle-something-on) 还有 (custom-set-variables),这也是我想做的大部分事情可以使用 "hooks" 实现。

spacemacs 文档让我完全无能为力,因为它主要假设你知道事情是如何工作的,而 emacs 文档就像核电站维护指南。

有人可以放心使用 spacemacs 给我一个 "entry point" 来理解这些概念吗?

我希望能够回答以下问题:"Oh, I want to customize that behavior, where do I need to code? What are the methods I should call? What are the methods I should NOT call? What variable can I change/create? What is actually executed when I put my code here?...etc"

以下是您需要了解的入门信息:

  • 您应该触摸以自定义 Spacemacs 的 唯一 文件是 ~/.spacemacs(或者 ~/.spacemacs.d/init.el,如果您更喜欢目录)。你不应该触摸 ~/.emacs.d 内的任何东西。你也不应该有任何 ~/.emacs 文件。

  • 您应该通读一次 ~/.spacemacs 文件以查看所有可能的配置选项,它们都有详细的文档。

  • ~/.spacemacs 文件由以下函数构成:

    • dotspacemacs/layers:这里是配置你想要的Spacemacs功能的地方,比如激活层,你需要的附加包,你不需要的排除包,等等……你不应该 add/remove 那里有任何变量或代码,只是 修改 现有值。

    • dotspacemacs/init: 在这里你可以enable/disable Spacemacs 提供的自定义,比如改变leader key,使用https更新,打开行号等......你不应该 add/remove 那里的任何变量或代码,只是 修改 现有值。

    • dotspacemacs/user-init:这是您将在加载包之前自定义Spacemacs的地方。只有在少数情况下才需要这样做,只有当变量应该在 before 加载包被加载时才需要。例如,将 ranger-override-dired 设置为 t,这样当 ranger 加载时,它将执行所需的操作来覆盖 dired 的功能。在加载包后这样做是行不通的,因为它会很晚。如果您不确定在 dotspacemacs/user-config 中或 dotspacemacs/user-config 中放置自定义项,您更有可能希望在 dotspacemacs/user-config 中进行自定义项。先在那里试试,如果不行你可以试试这里设置变量。

    • dotspacemacs/user-config: 这是您最有可能放置所有个人配置的地方。这将在所有包加载和配置后执行,因此它将覆盖任何其他配置。

  • Emacs 配置是在 Emacs lisp 中完成的,因此您需要了解它的基本知识才能配置 Spacemacs,没有其他方法。 真正 基础知识:

    • (<function>): 函数调用。
    • (<function> <arg_1> <arg_2> …): 带参数的函数调用。
    • (setq <variable> <value>): 设置一个变量的值。

关于您的问题:

注意:我看到您说其中一些配置不起作用,但它们对我来说可以正常工作。请尝试在 gitter 上请求一些帮助以帮助您调试它。

  • «行号显示在我打开的任何缓冲区中»:已经存在一个配置选项,您可以在 ~/.spacemacs(其中一个作为 reader :-) 的练习)。

  • «git 实时更改显示在左侧»:我将 (setq diff-hl-side 'left) 放在 user-config这是有效的。 IIRC 这不可能在 Emacs 的终端(非 GUI)模式下自定义。

  • «光标悬停时符号突出显示»:这可以通过 SPC t h a 切换。您可以在开始时通过从 user-config 调用 (spacemacs/toggle-automatic-symbol-highlight-on) 来启用它。请注意,提供此功能的软件包存在一些问题,并且与其他一些软件包不兼容 (https://github.com/syl20bnr/spacemacs/issues/2706, https://github.com/syl20bnr/spacemacs/issues/3475)。

  • «我的 "home page" 显示了一个项目列表,我可以加载最近的一个,它会记住上次的缓冲区配置» : 如果您在 dotspacemacs-startup-lists 变量中包含 projects,则应该可以看到最近的项目列表。记住上次的 windows 布局可以通过将 dotspacemacs-auto-resume-layouts 设置为 t 来完成。如果您希望能够使用每个项目的布局,则必须了解 layouts。例如:

    • SPC p l 以新视角打开项目
    • 更改此项目的 window 配置
    • SPC p l让你打开一个项目的新视角
    • 为此项目更改 window 配置
    • 使用SPC l n在项目之间切换
    • 退出 Spacemacs
    • 启动 Spacemacs,并以 SPC l n 的视角回到您的项目(仅适用于 dotspacemacs-auto-resume-layouts 设置为 t)。
  • «TODO 显示空格»:可以用 SPC t w 切换缓冲区,或 SPC t C-w 切换所有缓冲区。您可以在 user-config 中使用 (spacemacs/toggle-whitespace-globally-on) 在启动时启用它。

  • «;; rust»:在 develop 上,只要您使用 rust 层,就不需要这样做。不过现在 master 可能还没有。

一些补充信息

  • major-modeminor-mode。这些与它们仅适用于一个或所有缓冲区这一事实无关。相反,每个缓冲区一个,而只有一个major-mode(如python-moderuby-mode、 ETC…)。每个缓冲区 可以有 几个 minor-mode(如 linum-mode)。某些 minor-modeglobal,因为它们会影响所有缓冲区,例如 global-centered-cursor-mode.

  • Emacs lisp 变量可以是 globalbuffer-local。更改 global 变量将影响所有缓冲区。使用 (setq … 更改 buffer-local 变量将仅影响当前缓冲区。可以使用 (setq-default … 更改 buffer-local 变量的默认值。这将更改所有新创建的缓冲区的值。

    buffer-local 变量具有默认值,但在进入某些给定模式时它们可能会被 hooks 覆盖。为某种缓冲区修改此类值应将函数添加到挂钩中,例如:

    (setq-default fill-column 80)
    (add-hook 'mail-mode-hook (lambda () (setq fill-column 72)))
    (add-hook 'python-mode-hook (lambda () (setq fill-column 79)))
    
  • Spacemacs 确实为某些功能提供了一些切换功能。它们被称为 (spacemacs/toggle-…) 并在末尾添加 -on-off 启用或禁用它们。

  • (custom-set-variables) 是 Emacs 的 customize 部分的一部分,目前 Spacemacs 应该避免这种情况,因为它们的行为没有明确定义(https://github.com/syl20bnr/spacemacs/pull/5168可能会解决这个问题)。

  • «我希望能够回答问题:"Oh, I want to customize that behavior, where do I need to code? What are the methods I should call? What are the methods I should NOT call? What variable can I change/create? What is actually executed when I put my code here?...etc"»:

    Spacemacs 与 Emacs 或 vim 一样,是一个强大的工具。就像每一个强大的工具一样,它需要一些时间来适应它,以适应它。如果你想开始驾驶飞机,你不会凭直觉知道按什么按钮来做这个或那个。如果你想有所成就,你必须阅读一本很长的手册,或者找一位讲师。 Spacemacs 也是如此。 有一个 documentation, a quick-start and a migrating from vim documents. They are quite long, but it's because the range of possibilities are as-long as the documents. The other way is to get help from some "instructor", i.e. Spacemacs regular contributors. I would recommend you to come to the gitter room 非常活跃,希望对您有所帮助。