用sly-el-indent获得更好的Elisp缩进

以前用Emacs默认的lisp-indent-function缩进Elisp,能用是能用,但是有些复杂的代码的缩进会变得有点奇怪。往往需要手动调整一下,或者用换行作为work-around,做出来的效果才差强人意。

后来开始写Common Lisp,发现Sly自带了一个很强大的缩进工具sly-cl-indent,把以前写Lisp代码的时候的痛点一扫而光。

然而sly-cl-indent是为了Common Lisp设计的,昨天写了个sly-el-indent包裹了sly-cl-indent,这样在写Elisp的时候也能获得sly-cl-indent强大而灵活的缩进功能。

加载sly-el-indent后,执行

(add-hook 'emacs-lisp-hook
            (function sly-el-indent-setup))

就可以让Emacs对Elisp文件使用sly-cl-indent的缩进逻辑缩进了。

最后放张图,左边是sly-el-indent,右面是默认的lisp-indent-function

11 个赞

单独分了一个包出来, 不用去下载sly里的sly-cl-indent

1 个赞

:+1:好东西,拿走拿走

不错,不错,已经用上了。

修复了letf letf*不能被正确缩进的问题

  • 你用的sly,我记得sly不如slime更actively maintained?
  • 跟单独的package相比,用一个文件wrap sly-cl-indent更能自动在sly-cl-indent更新之后享受到更新?

遇到bug有人能修就行。CL都十几年没变化了,slime和sly想加什么新功能都没借口。

slime的indent function已经集成到emacs里,叫做cl-indent,但是cl-indent的效果还是没sly-cl-indent效果好。我之前都在用cl-indent,你可以参考下我这个配置

(use-package cl-indent
  :after elisp-mode
  :demand
  :doc "Better indentation mode."
  :config
  (setq lisp-indent-function #'common-lisp-indent-function)
  (defvar cm/correct-indentation-list
    '((defface . nil)
      (defalias . nil)
      (define-minor-mode . 1)
      (define-derived-mode . 3)
      (defface . 1)
      ;; (unwind-protect . 1)
      (define-globalized-minor-mode . nil)
      ;; Fix `use-pacakge' indentation.
      (use-package . 1)))
  (pcase-dolist (`(,sym . ,spec) cm/correct-indentation-list)
    (put sym 'common-lisp-indent-function-for-elisp spec)))

并不是每个人都想为了一个缩进功能下载整个sly吧。而且sly把sly-cl-indent放在lib文件夹里,在添加load-path的时候这个lib文件夹会被忽略,sly是用自己的特殊方法加载的。

已更新,cl-loop 太好用。

跑个题,这种引用外部链接的效果到底是怎么输入的?我一直不清楚,这也是种Markdown语法吗?

单独一行链接就行 https://emacs-china.org/raw/10580/5 你可以看我怎么输入的

原来如此,使用带括号的那种输入链接的方法反而只能生成带下划线的传统链接,谢谢

你记反了,slime 才是万年沒更新的那个。

沒借口?我上周拿 VSC 写了下 Reason React 一比较发现 slime/sly 连个像样的 breakpoint 都沒有,太丟人了。

real programmer don’t use breakpoint :ghost:

终于找到给major mode补充缩进的例子可以参考了(要是有着色就更好了)!抱走~~

之前一直想给AucTeX添加pseudo-code的缩进和着色支持,苦于elisp入门(可能都不到)的水准,想找个例子模仿着改而不得,这个真是帮大忙了 :slight_smile:

这也是个很好的参考(也许直接可以用得上),代码加注释才 200 多行。

1 个赞

不支持 cl-defun/cl-defmacro ? 以下定义的参数没有像锯齿一样缩进:

(cl-defun func (&optional
                optionA
                &key
                keyA
                keyB
                &allow-other-keys
                &rest
                rest-part))

支持啊,LaTeX中竟然连if语句的缩进也没有,对cls等配置文件的高亮和缩进支持基本等于没有,开始我还以为是我设置不对,查了查好像就是没有这种功能。有人说这需要更好的TeX的parser才能做到,但是我也不清楚TeX比起其他语言有何不同,AucTeX连这种基本功能也没有。

已经修复。当时直接从cl.el抄的映射表,但是cl.el会吧cl-defun映射到defun*,然后defun*默认没有定义缩进,就出问题了。

1 个赞

又发现一个问题。

假设宏定义如下:

(cl-defmacro foo (&rest body &key path lexical &allow-other-keys)
  "DOC"
  (declare (indent defun) (debug t))
  `,@body)

调用的时候带/不带参数,缩进表现不一致:

;; 缩进2格
(foo :path "/path/to/file"
  (dosomething))

;; 缩进4格
(foo
    (dosomething))