关于emacs-lisp-mode中缩进的对齐

我用的spacemacs中的默认配置,感觉elisp缩进的样子很丑。如果是同一对括号内的,默认总是与上一个symbol对齐,这样有时候代码会很宽。

但是我看到别人提交的代码大多不是这样对齐的,比如org-mode的源代码一般比较紧凑。是不是有什么默认配置可以改对齐方式的?

当然现在这种对齐方式的好处就是,比较容易看出语句关系,但缺点就是不太紧凑。

好吧,可能现在这样才是最标准的: https://mumble.net/~campbell/scheme/style.txt

举个例子?代码过宽时一般用换行来解决。

Emacs 默认的缩进是标准的。不清楚 Spacemacs,但我觉得它不会改。Org 源代码的缩进也是标准的(重新缩进下,文件也不会变)。

不同 Lisp (如 Emacs Lisp、Common Lisp 和 Scheme)的缩进规范很可能不完全一样。

比如我随便在 org.el 中找了一个函数,按照默认的缩进,是这样的:

(defun org-set-emph-re (var val)
  "Set variable and compute the emphasis regular expression."
  (set var val)
  (when (and (boundp 'org-emphasis-alist)
	     (boundp 'org-emphasis-regexp-components)
	     org-emphasis-alist org-emphasis-regexp-components)
    (let* ((e org-emphasis-regexp-components)
	   (pre (car e))
	   (post (nth 1 e))
	   (border (nth 2 e))
	   (body (nth 3 e))
	   (nl (nth 4 e))
	   (body1 (concat body "*?"))
	   (markers (mapconcat 'car org-emphasis-alist ""))
	   (vmarkers (mapconcat
		      (lambda (x) (if (eq (nth 2 x) 'verbatim) (car x) ""))
		      org-emphasis-alist "")))
      ;; make sure special characters appear at the right position in the class
      (if (string-match "\\^" markers)
	  (setq markers (concat (replace-match "" t t markers) "^")))
      (if (string-match "-" markers)
	  (setq markers (concat (replace-match "" t t markers) "-")))
      (if (string-match "\\^" vmarkers)
	  (setq vmarkers (concat (replace-match "" t t vmarkers) "^")))
      (if (string-match "-" vmarkers)
	  (setq vmarkers (concat (replace-match "" t t vmarkers) "-")))
      (if (> nl 0)
          (setq body1 (concat body1 "\\(?:\n" body "*?\\)\\{0,"
                              (int-to-string nl) "\\}")))
      ;; Make the regexp
      (setq org-emph-re
	    (concat "\\([" pre "]\\|^\\)"
		    "\\("
		    "\\([" markers "]\\)"
		    "\\("
		    "[^" border "]\\|"
		    "[^" border "]"
		    body1
		    "[^" border "]"
		    "\\)"
		    "\\3\\)"
		    "\\([" post "]\\|$\\)"))
      (setq org-verbatim-re
	    (concat "\\([" pre "]\\|^\\)"
		    "\\("
		    "\\([" vmarkers "]\\)"
		    "\\("
		    "[^" border "]\\|"
		    "[^" border "]"
		    body1
		    "[^" border "]"
		    "\\)"
		    "\\3\\)"
		    "\\([" post  "]\\|$\\)")))))

但是在 org.el 中它是这样的(因为太长,所以只截取一部分):

可以看出它采用了一种很奇怪的方式来缩进,难道都是手动缩进成这样的吗?

org.el 中用 TAB 和 Space 混合缩进,如果你没有修改 tab-width (默认是 8)的话,看起来会是正常的。

是故意的吗?

应该是吧,用纯 Tab 没法对齐(比如需要 12 个字符宽度的缩进,就是能用 1 个 Tab 和 4 个空格了)。另外由于 8 个空格换成 1 个 Tab,能节省 7 bits,但现在(2017)意义不大,主要看个人喜好吧。新写的代码一般都只用空格了,但旧的代码一般也不会改掉。

感谢 @xuchunyang,澄清了我长久以来的疑惑