[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Codifying some aspects of Elisp code style and improving pretty printer

From: akater
Subject: Codifying some aspects of Elisp code style and improving pretty printer
Date: Wed, 29 Sep 2021 18:01:47 +0000

Rgrepping lisp/emacs-lisp alone for “(let” and “(if” demonstrates that
there is a reasonable practice at least

- of keeping “then” on the same line as “if” sometimes

- of having several let bindings in “let” on the same line, especially
  if they are all symbols except maybe some first ones.

There is an informal consensus that it's worth it to use whitespace
wisely to keep Lisp forms concise vertically as well as horizontally.  I
think if the idea is recognised as useful it better be explicitly stated
as such rather than remain folklore. I don't see this practice codified
neither in elisp nor eintr Info nodes nor anywhere in Lisp literature
for that matter.  I asked in commonlisp channel on libera.chat and
nobody seems to know of any text like that; pointers are welcome if I
missed something.

True, this is largerly a matter of personal style.  However, there is
also some accumulated experience which I think is worth aggregating.
And no style is actually 100% personal when we collaborate.

I paid some attention to the issue for some time while writing (E)Lisp
code.  There are still some practices I'm not sure about.
E.g. apparently there's no practice to start the first subform of
unwind-protect on the same line as unwind-protect when line width
allows it; I find this surprising as I think this significantly
decreases readablity of unwind-protect forms.

What follows is a draft of relevant style guidelines as I see it.  At
the very least, it can serve as a basis for improving the currently
used pretty printer that prints Elisp forms (which still inexplicably
insists that let forms' bindings should start on a new line, for
example).  Automatic indentation should not attempt to be smart about
line splits but pretty printer should.

I'd welcome relevant bits of github.com/bbatsov/emacs-lisp-style-guide
as well but the guide mentions issues Emacs seems to deal on its own
automatically so I'm not sure.  Also, there may be copyright issues.

When it comes to accessing such information from within Emacs, I could
only find something in (recent) compiler warnings, about long
docstrings, and some other notes about docstrings in CONTRIBUTE file.
Since it has sporadic notes on docstring style, CONTRIBUTE likely
should also reference the style guide as well as Emacs Lisp Coding
Conventions Info node.

So here's the draft.

Emacs Lisp source code layout guidelines

- Rule of thumb: General form should look like

  (f x

  However, if sequences f x1 ... xn, y1 ... ym, ..., z1 ... zk are
  short as a whole, it is preferred to

  (f x1 ... xn
     y1 ... ym
     z1 ... zk)

  especially if expressions on the same line are close conceptually,
  e.g. (a) key-value pairs, including those with keyword arguments, or
  (b) pairs of arguments in setq, setf and similar forms.

- “Short as a whole” necessarily means “fits into a single line of
  recommended line width, together with all opening parens” but this
  condition is not sufficient.

- In let, let* and similar forms, a single line can hold as many
  bindings represented by symbols rather than lists, as long as they
  are short as a whole.

- In let* and similar forms, a binding with initial value that depends
  solely on a previous (but not necessarily immediately previous)
  value, can be kept on the same line as its dependency as long as
  they are short as a whole.

- In let, let* and similar forms, if it is posible to arrange
  variables so that conceptually close ones share the same line, it is
  preferred to do so.

- In most (indent n) forms, it is preferred to start (n-1)th
  subexpression on the same line as the head symbol if the
  subexpressions in question are short as a whole and if it allows to
  keep the overall form concise both horizontally and vertically; note
  that it applies to forms ignore-errors and unwind-protect.

- The former applies to cl-loop, cond, let, if forms which do not have
  (indent ..) in their specs but which can nevertheless be considered
  for our purposes as (indent 0), (indent 0), (indent 1), (indent 2)
  forms correspondingly.

- Aside from the very first one, cl-loop keywords should start the lines.

- Two or more forms, short as a whole, that perform what's essentially
  a single step of a loop can be kept on the same line.

- “Short”, “most forms”, “similar forms” in the above paragraphs are
  subjective so the final decision on whether keeping sexps on the
  same line hampers readability or not is up to a maintainer of the
  Elisp codebase in question.  Arguing about such things with
  maintainers is likely a waste of time.  Thus, the maintainer's
  decision on line splits should be considered final.  Refactoring /
  cleanup edits that deal with line splits better be left to
  maintainers, or outsourced by them to someone whose personal style
  they explicitly trust enough to avoid any arguments about this

Attachment: signature.asc
Description: PGP signature

reply via email to

[Prev in Thread] Current Thread [Next in Thread]