3

Is there a way to indent cl-flet, cl-labels etc. using the CL style without resorting to (setq lisp-indent-function #'common-lisp-indent-function)?

cl-indent.el claims that:

common-lisp-indent-function is also a suitable function for indenting Emacs lisp code.

But this is far from true. It misindents the :types of defcustoms, the docstring of define-minor-mode, and more.

Tianxiang Xiong
  • 3,848
  • 16
  • 27

3 Answers3

2

This is not possible with the current codebase, there is an open bug for it. Fixing it should be a matter of copying the functionality from cl-indent.el without getting the misindenting of defcustom, define-minor-mode, etc.

npostavs
  • 9,033
  • 1
  • 21
  • 53
1

Define the indentation for a given function/macro etc. by putting the indentation spec on the function etc. symbol as property common-lisp-indent-function. As one possible example:

(put 'cl-flet
     'common-lisp-indent-function
     '((&whole 4 &rest (&whole 1 &lambda &body)) &body))
Drew
  • 75,699
  • 9
  • 109
  • 225
  • 1
    But this doesn't work unless `lisp-indent-function` property is set to `common-lisp-indent-function`, right? That's what I find from my experiments. – Tianxiang Xiong Feb 03 '18 at 20:42
  • I tried `(put 'cl-flet 'lisp-indent-function #'common-lisp-indent-function)` so that `common-lisp-indent-function` applies only applies to `cl-flet`, but that's not indenting properly either. – Tianxiang Xiong Feb 03 '18 at 21:20
0

The following code indents flet like lists. It's not perfect, because the sublist needs to be closed, before it is recognized.

(setq-default lisp-indent-function 'elisp-flet-indent-function)

(defvar elisp-flet-style-macros
  (let ((macs '(flet flet* values macrolet labels)))
    (append macs (mapcar (lambda (sym)
                           (intern (format "cl-%s" (symbol-name sym))))
                         macs))))

(dolist (mac elisp-flet-style-macros)
  (put mac 'lisp-indent-function 'defun))

(defun elisp-flet-indent-function (indent-point state)
  "Handle `flet'-like lists, otherwise call `lisp-indent-function'."
  (cond
   ((ignore-errors
      (save-excursion
        (backward-up-list 3)
        (down-list)
        (when (memq (intern (thing-at-point 'symbol))
                    elisp-flet-style-macros)
          (forward-sexp 2)
          (>= (point) indent-point))))
    (lisp-indent-defform state indent-point))
   (t (lisp-indent-function indent-point state))))
politza
  • 3,316
  • 14
  • 16