[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
cl-macs: default indentation for all arglists with top-level &body
From: |
akater |
Subject: |
cl-macs: default indentation for all arglists with top-level &body |
Date: |
Sun, 11 Apr 2021 12:35:34 +0000 |
signature.asc
Description: PGP signature
0001-cl-macs-default-indentation-for-all-arglists-with-to.patch
Description: cl-macs: indent via top-level &body
(This has been discussed earlier on the list --- more on this later.)
In Common Lisp, ~&body~ keyword is the same as ~&rest~ modulo
indentation:
#+begin_quote
&body is identical in function to &rest, but it can be used to inform
certain output-formatting and editing functions that the remainder of the
form is treated as a body, and should be indented accordingly.
#+end_quote
--- [[http://clhs.lisp.se/Body/03_dd.htm][CLHS, 3.4.4 Macro Lambda Lists]]
cl-macs does support ~&body~; however toplevel ~&body~ does not affect
indentation. This can be fixed by augmenting the definition of
~cl--transform-lambda~ as follows:
#+begin_example emacs-lisp
(when-let ((according-to-&body
(let ((counter 0))
(cl-dolist (x orig-args)
(cond
((eq '&body x) (cl-return counter))
((not (memq x cl--lambda-list-keywords))
(cl-incf counter)))))))
;; Placing the declaration in the end
;; allows overriding the indentation setting
;; with an explicit (declare (indent ..)) statement
;; manually written in the form being expanded.
(setq header
(nconc header
(list
`(declare (indent ,according-to-&body))))))
#+end_example
See the attached patch for details. I hesitate to recommend using the
patch as is because my use of ~cl-dolist~ likely interrupts the flow of
cl-macs. In fact, the patch as is might actually break the build:
unfortunately, I cannot do a test build of Emacs right now. I thus did
not try to polish something I wouldn't actually be able to test. The
patch is provided for the sake of completeness.
Now to (possibly incomplete) summary of the 2005-07 thread and
comparison.
The feature was
- suggested to be applied to usual ~defmacro~ as well
- not implemented as there is no ~&body~ in ~defmacro~
- apparently shelved and then forgotten about
I only suggest to alter ~cl-defmacro~.
In addition, 2005-07 solution
- is implemented with ~(put .. 'lisp-indent-function ..)~
- does not check for preceding keywords
The link:
https://lists.gnu.org/archive/html/emacs-devel/2005-07/msg00457.html
I check for all ~cl--lambda-list-keywords~. This is excessive but it
also makes for a cleaner code, properly treats arglists with
~&optional~, ~&whole~ (if ever implmeneted) and whatever else happens to
be in the arglist; note that according to Common Lisp specification,
arglsits can actually have arbitrary keywords. ~&whole~ is only
relevant for macro definitions; arguably, it does make sense for
~cl--transform-lambda~ to take these types into account but I believe
the presented approach is good enough, and using &-keywords as regular
arguments in, say, ~cl-defun~ is certainly not a good idea.
As to whether the macro better inject ~(put ..)~ or ~(declare ..)~ form,
my preference is for the latter because
- I find it preferable to modify headers rather than the body
- I strongly prefer to generate code I myself would have written. This
is apparently not a conventional practice in Lisp; mistakenly, I
believe, but that's offtopic.
Just in case, I have signed the papers already.
- cl-macs: default indentation for all arglists with top-level &body,
akater <=