Spacemacs 的配置

Spacemacs 的配置

Spacemacs 的配置

很早之前就听说过 Spacemacs,并且简单使用了一下,之前有被它的界面和初始化的流畅性震撼过。但是自己尝试去配置时就放弃了,有点复杂,一层一层的 layer,配置一下还会报错。最近一两年,很少有时间折腾 emacs,最近稍微有点时间,想配置一个 vue,于是搜了一下 emacs + vue 相关的,发现 Spacemacs 的配置是最活跃的,经常有很多人在讨论。并且,这个配置出来也已经有一两年的时间了,可以说是经过了市场的验证了。既然这么多人来贡献配置出来的,自然在很多方面是比较成熟的。比单靠自己来配置要节省更多的时间,很多坑可能别人都已经解决。正是抱着这个希望,所以,重新按照教程把 Spacemacs 使用起来了。

1 安利

由于这个是多人参与维护的一个开源配置,功能稳定性还是不错的、界面漂亮、启动速度也很快。最主要的变化是对快捷键的重新定义,原来的快捷键基本上是按照 package 来分组管理的。很多时候,快捷键之间也会有冲突,互相覆盖的情况。Spacemacs 采用独有的分组方式,按照不同的功能类型来分组管理,并用 a-z 字母开头的不同的单词来区分,如 a 代表 applications 应用相关, b 代表 buffers 相关的功能,等等。

这个其实对于我这种使用 emacs 时间比较长的人来说,反倒是很多按键找不到了,每次要 M-x 去找命令,然后记住快捷键。但使用时间长了之后应该差别不大。

但是,它配合 which-key 之后,给人的感觉还是不错的。原来自己也用过 which-key,但是是用的竖直模式,在右边显示出按键提示,经常出现把这个屏幕都挡住,然后回不去的情况,应该是 which-key 的一个问题吧。但使用 spacemacs 之后,发现可以把这个提示放在 bottom 的,并且再也不会出现把屏幕弄乱的情况了,这个体验要好很多。(当然,其他的配置也可以配置在 bottom,甚至觉得默认就应该修改为 bottom,而不是右边,这个是题外话。)

spacemacs 好的地方在于,自己也可以在这些功能分类里面添加自己认为合适的功能。这一点比原来按照包的方式来分类和管理要合理一些。因为总不至于在别的包的按键 map 里面加其他的功能吧。

另外一个就是 major-mode 的按键,全部使用 C-M-m 来做 leader-key ,这个太好了,有统一的使用体验。不管什么模式,可以按相同的按键来使用 major-mode 里面的功能。

2 安装

这个按照官网的指导来:

https://github.com/syl20bnr/spacemacs

将 github 的代码 clone 下来,放在 ~/.emacs.d 文件夹中即可。

但是启动的时候,大多数情况下会失败。因为大陆是有墙的,连不上 melpa。可以在 ~/.spacemacs.d/init.el 中加入大陆的源,就能正常的安装所有依赖的包了:

(defun dotspacemacs/user-init ()
  "Initialization function for user code.
It is called immediately after `dotspacemacs/init', before layer configuration
executes.
 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-default configuration-layer--elpa-archives
                '(("gnu" . "http://elpa.emacs-china.org/gnu/")
                  ("melpa" . "http://elpa.emacs-china.org/melpa/")
                  ("melpa-stable" . "http://elpa.emacs-china.org/melpa-stable/")
                  ("marmalade" . "http://elpa.emacs-china.org/marmalade/")
                  ("org" . "http://elpa.emacs-china.org/org/")
                  ("SC" . "http://elpa.emacs-china.org/sunrise-commander/")
                  ("user42" . "http://elpa.emacs-china.org/user42/"))))

3 layer

Spacemacs 相对于以往的配置,最大的不同就是引入了 layer 这个概念。 layer 是比 package 更高一个层级的抽象。基本上一个 layer 是一个完整的可用的功能集的总称。比如,一个语言 javascript,通常指的是 javascript-mode 的 package。但是实际上,这个包仅仅是提供了语法支持,要想使用得更爽,就需要自动补全,语法检查,跳转等等其他的包的支持。而一个 layer 可能就是所有这些包的配置的一个集合。把所有需要的 package 的配置放在一起,一目了然。

另外,自动补全,语法检查等包,基本上所有的语言都需要,但是所有的语言又不同,全部配置到一起的话,文件内容太多,很多都是不关心的内容。每个语言都单独配置的话,包的基本配置又是相同的,往往每个不同的语言只需要稍微修改或者添加一些功能就可以了。

于是,layer 就可以定义 owner 用于初始化,使用 init-PACKAGE 方法来完成基本的设置,另外,可以使用 post-init-PACKAGE 在不同的 layer 中做一些差异化的定制。这样可以保证跨语言的功能的灵活定制,和可维护性。

4 自带的 layer

Spacemacs 的自带 layer 配置还是相当的丰富的,要求不是很高的时候,大多数只使用自带的 layer 就可以满足了。下面使用了其中的一些自带 layer:

dotspacemacs-configuration-layers
   '(
     ;; ----------------------------------------------------------------
     ;; Example of useful layers you may want to use right away.
     ;; Uncomment some layer names and press <SPC f e R> (Vim style) or
     ;; <M-m f e R> (Emacs style) to install them.
     ;; ----------------------------------------------------------------
     ;; -------- standard --------
     spacemacs-bootstrap
     better-defaults
     chinese
     helm
     (ibuffer :variables ibuffer-group-buffers-by 'projects)
     (syntax-checking :variables
                      syntax-checking-enable-by-default nil
                      syntax-checking-enable-tooltips nil)
     (spell-checking :variables spell-checking-enable-by-default nil)
     (auto-completion :variables
                      auto-completion-enable-sort-by-usage t
                      auto-completion-enable-snippets-in-popup t
                      :disabled-for org markdown)
     git version-control
     (gtags :disabled-for clojure emacs-lisp javascript latex python shell-scripts)
     imenu-list
     nginx
     org graphviz markdown
     emacs-lisp
     csv
     html
     javascript
     (typescript :variables
                 typescript-fmt-on-save t
                 typescript-fmt-tool 'typescript-formatter)
     react
     python
     restclient
     sql
     (shell :variables
            shell-default-shell 'eshell
            shell-default-height 30
            shell-default-position 'bottom)
     shell-scripts windows-scripts
     yaml
     osx
     )

5 better-editing

对于基础编辑功能的改善,由于之前多年的 emacs 使用,有一些很好用的 package 和常用按键配置是不能少的。

5.1 multiple-cursors

multiple-cursors 应该来说,是 emacs 里面最喜欢的一个功能了。编辑,特别是修改代码的神器。

(defun better-editing/init-multiple-cursors ()
  (use-package multiple-cursors
    :defer t
    :bind* (("C-;"     . mc/mark-all-like-this-dwim)
            ("C-:"     . mc/mark-all-like-this-in-defun-dwim)
            ("C->"     . mc/mark-next-like-this)
            ("C-<"     . mc/mark-previous-like-this)
            ("C-M->"   . mc/skip-to-next-like-this)
            ("C-M-<"   . mc/skip-to-previous-like-this)
            ("C-;"     . mc/mark-all-like-this-dwim)
            ("C-:"     . mc/mark-all-like-this-in-defun-dwim)
            ("C-》"     . mc/mark-next-like-this)
            ("C-《"     . mc/mark-previous-like-this)
            ("C-M-》"   . mc/skip-to-next-like-this)
            ("C-M-《"   . mc/skip-to-previous-like-this)
            ("C-S-<mouse-1>" . mc/add-cursor-on-click)
            :map mc/keymap
            ("C-|" . mc/vertical-align-with-space)
            ("C-_" . undo) ;undo-tree-undo point position wrong.
            ("C-—" . undo) ;chinese
            ("M-n" . mc/cycle-forward)
            ("M-p" . mc/cycle-backward))
    :init
    (progn
      (require 'multiple-cursors)
      (setq mc/list-file better-editing/mc-config-file
            mc/insert-numbers-default 1
            mc/cycle-looping-behaviour 'stop))
    :config
    (progn
      (defun mc/my-quit ()
        "Quit from mark mode."
        (interactive)
        (mc/keyboard-quit)
        (multiple-cursors-mode 0))

      (defun mc/mark-all-symbols-like-this-toggle ()
        "Toogle when only one matches!"
        (interactive)
        (if (or multiple-cursors-mode (region-active-p))
            (mc/my-quit)
          (mc/mark-all-symbols-like-this)))

      (defun mc/mark-all-like-this-dwim ()
        "Toggle when not using region. When using region, search first,
if only one candidate searched, then quit!"
        (interactive)
        (if multiple-cursors-mode
            (mc/my-quit)
          (if (not (region-active-p))
              (mc/mark-all-symbols-like-this)
            (mc/mark-all-like-this)
            (unless multiple-cursors-mode
              (mc/my-quit)))))
      (defun mc/mark-all-like-this-in-defun-dwim ()
        "Like `mc/mark-all-like-this-dwim', but only in defun."
        (interactive)
        (if multiple-cursors-mode
            (mc/my-quit)
          (if (not (region-active-p))
              (mc/mark-all-symbols-like-this-in-defun)
            (mc/mark-all-like-this-in-defun)
            (unless multiple-cursors-mode
              (mc/my-quit))))))))

特别是配合一些其他的包,比如 number:

(defun better-editing/init-number ()
  (use-package number
    :defer t
    :commands mc/number/add mc/number/divide mc/number/multiply
    number/add number/sub number/multiply number/divide number/eval
    ))

对应于 multiple-cursors 中的命令:

(defmacro better-editing/defun-mc-number-commands (commands)
  "Create mc number COMMANDS."
  `(progn
     ,@(mapcar
        (lambda (command)
          `(defun ,(intern (concat "mc/" (symbol-name command))) (n)
             ,(concat "Multiply-cursors support for " (symbol-name command) ", N default 1.")
             (interactive (list (mc//number-read-from-minibuffer)))
             (let* ((cmd (lambda () (interactive) (,command n))))
               (mc/execute-command-for-all-cursors cmd))))
        commands)))

(better-editing/defun-mc-number-commands (number/add number/divide number/multiply))

这样就可以使用 mc/insert-numbers 一次插入多个递增的数字:

var|        var1
var|   ->   var2
var|        var3

或者 mc/number/add 将所有的数字加上或者减掉一个数字:

var1        var2
var2   ->   var3
var3        var4

还有下划线和驼峰的互换:

bar_foo           barFoo
bar_foo_tar  ->   barFooTar
tar_bar           tarBar
barFoo            bar_foo
barFooTar   ->    bar_foo_tar
tarBar            tar_bar

5.2 smart-tab

可以将大多数的补全和对齐相关的操作全部集中在 tab 键中,当需要补全时就补全,当不需要补全时,退回到原始的设置。

比如 org-mode 中,默认的 tab 键绑定的是 org-cycle 功能。使用 smart-tab 之后,可以在正文中补全、yas-expand,也可以在 headline 中折叠或者打开。

6 未完待续

Date: 2018-12-26 22:32:14

Author: WEN YANG

Created: 2019-01-03 Thu 22:18

Validate

posted @ 2018-12-28 22:33  yangwen0228  阅读(2494)  评论(0编辑  收藏  举报