unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Proposal: change indentation rules for one-dimensional lists in emacs-lisp-mode and lisp-mode
@ 2020-03-03  0:12 akater
  2020-03-03 18:14 ` Richard Stallman
  0 siblings, 1 reply; 4+ messages in thread
From: akater @ 2020-03-03  0:12 UTC (permalink / raw)
  To: emacs-devel


If you read this in recent Emacs, you can M-x org-mode for better
reading experience. It'll work fine even if you don't generally use
org-mode.

* Quick overview: Proposed indentation

My proposal is: when there's whitespace after the opening paren, always
indent list contents as data, as opposed to code:

#+begin_src emacs-lisp
;; proposed indentation
(blob '( a b c
         d e f))
(blob `( a b c
         d e f))
(blob ( a b c
        d e f))
#+end_src

#+begin_src lisp
;; proposed indentation
(blob '( a b c
         d e f))
(blob `( a b c
         d e f))
(blob ( a b c
        d e f))
#+end_src

This will be more aesthetically pleasing and will utilise whitespace
more efficiently when dealing with data lists. It will also bring more
consistency, as outlined below.

The proposal does apply to backquote, as backquote is not used solely
for code in practice. Sometimes data is backquoted, with parts of it
evaluated.

It won't affect code indentation as corresponding expressions never have
whitespace after the opening paren, according to my experience.

* Quick overview: Estabilished indentation

At the moment one-dimensional lists are indented disregarding the
post-open-paren whitespace:

#+begin_src emacs-lisp
;; estabilished indentation
(blob '( a b c
           d e f))
(blob `( a b c
           d e f))
(blob ( a b c
          d e f))
#+end_src

#+name: the-first-one-is-particularly-ugly
#+begin_src lisp
;; estabilished indentation
(blob '( a b c
        d e f))
(blob `( a b c
           d e f))
(blob ( a b c
          d e f))
#+end_src

* Motivation

When not at top-level, one-dimensional lists quoted with quote are
indented differently in lisp-mode and emacs-lisp-mode:

#+begin_src emacs-lisp
(blob '(a b c
          d e f))
#+end_src

#+begin_src lisp
(blob '(a b c
        d e f))
#+end_src

While lisp-mode employs data indentation here, emacs-lisp-mode uses code
indentation which I believe is a misfeature in emacs-lisp-mode.

One-dimensional lists quoted with backquote are indented as code in both
cases:

#+begin_src emacs-lisp
(blob `(a b c
          d e f))
#+end_src

#+begin_src lisp
(blob `(a b c
          d e f))
#+end_src

Sometimes the lists in question actually represent data. In those cases,
they should be indented unlike code and like, say, two-dimensional lists
are currently indented:

#+begin_src emacs-lisp
(blob '((a b c)
        (d e f)))
#+end_src

#+begin_src lisp
(blob '((a b c)
        (d e f)))
#+end_src

Note that unquoted lists

#+begin_src emacs-lisp
(blob (a b c
         d e f))
#+end_src

#+begin_src lisp
(blob (a b c
         d e f))
#+end_src

often enough represent data, too.

This case is treated satisfactorily now for two-dimensional lists across
the modes in question:

#+begin_src emacs-lisp
(blob ((a b c)
       (d e f)))
#+end_src

#+begin_src lisp
(blob ((a b c)
       (d e f)))
#+end_src

Currently, the only way to indent one-dimensional list as data in emacs-lisp-mode, is this:

#+begin_src emacs-lisp
(blob '(
        a b c
        d e f))
#+end_src

which works for backquote and unquoted sexp as well. This is how I
actually deal with this issue now. lisp-mode (as opposed to
emacs-lisp-mode) handles it better, unless there actually is post-quote
whitespace not containing a newline, in which case the indentation is
particularly ugly, as can be observed in
[[the-first-one-is-particularly-ugly]] block above.

* Further notes

Note how the estabilished indentation is inconsistent within lisp-mode:
lisp-mode indentation simply disregards post-quote whitespace but
respects post-backquote whitespace and “unquoted
whitespace”. Estabilished indentation rules are also inconsistent
between lisp-mode and emacs-lisp-mode for no good reason that I can see.

My proposal does not look like a significant step away from estabilished
indentation rules. It could be equivalently formulated as
“indent-as-data should be triggered by any whitespace after the opening
paren, not just by whitespace containing newline.” Proposal also makes
rules more consistent between the two modes.

Note that this would fit with the estabilished indentation style for
two-dimensional lists, as currently adopted by emacs-lisp-mode:

#+begin_src emacs-lisp
;; estabilished indentation
(blob '( (a b c)
         (d e f)))
(blob `( (a b c)
         (d e f)))
(blob ( (a b c)
        (d e f)))
#+end_src

lisp-mode, on the other hand, ignores the post-quote whitespace again,
like in the case of one-dimensional lists. I believe this is a
misfeature. The proposal otherwise fits with the lisp-mode indentation
rules.

#+begin_src lisp
;; estabilished indentation
(blob '( (a b c)
        (d e f)))
(blob `( (a b c)
         (d e f)))
(blob ( (a b c)
        (d e f)))
#+end_src

* Side note: top-level quoted indentation (or rather, lack thereof)

Note also that quoted lists are never auto-indented at top-level at all:

#+begin_src emacs-lisp
;; estabilished indentation
'(a b c
   d e f)
`(a b c
   d e f)
#+end_src

#+begin_src lisp
;; estabilished indentation
'(a b c
   d e f)
`(a b c
   d e f)
#+end_src

while unquoted lists (of course) are:

#+begin_src emacs-lisp
(a b c
   d e f)
#+end_src

#+begin_src lisp
(a b c
   d e f)
#+end_src

but I didn't give this any thought and meniton it just for the sake of
completeness.



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Proposal: change indentation rules for one-dimensional lists in emacs-lisp-mode and lisp-mode
  2020-03-03  0:12 Proposal: change indentation rules for one-dimensional lists in emacs-lisp-mode and lisp-mode akater
@ 2020-03-03 18:14 ` Richard Stallman
  2020-03-03 20:09   ` Stefan Monnier
  0 siblings, 1 reply; 4+ messages in thread
From: Richard Stallman @ 2020-03-03 18:14 UTC (permalink / raw)
  To: akater; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

THis is a very interesting idea.  It looks promising.

-- 
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Proposal: change indentation rules for one-dimensional lists in emacs-lisp-mode and lisp-mode
  2020-03-03 18:14 ` Richard Stallman
@ 2020-03-03 20:09   ` Stefan Monnier
  2020-05-01  6:26     ` akater
  0 siblings, 1 reply; 4+ messages in thread
From: Stefan Monnier @ 2020-03-03 20:09 UTC (permalink / raw)
  To: Richard Stallman; +Cc: akater, emacs-devel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/x-markdown; coding=UTF-8, Size: 252 bytes --]

> THis is a very interesting idea.  It looks promising.

It sounds like a good convention.  Much simpler than trying to make the
indentation smarter, and without the problems of having to try and guess
the intention of the code(r).


        Stefan




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Proposal: change indentation rules for one-dimensional lists in emacs-lisp-mode and lisp-mode
  2020-03-03 20:09   ` Stefan Monnier
@ 2020-05-01  6:26     ` akater
  0 siblings, 0 replies; 4+ messages in thread
From: akater @ 2020-05-01  6:26 UTC (permalink / raw)
  To: Stefan Monnier, Richard Stallman; +Cc: emacs-devel

FWIW, here's a patch that seems to work in emacs-lisp-mode but does not
work in lisp-mode.  It alters a single function, namely
calculate-lisp-indent.

I tested on various expressions; did try with paredit disabled.  For now
I'm baffled as to where the indentation procedures differ.  I'll keep
looking.


--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -947,6 +947,7 @@
           ;; setting this to a number inhibits calling hook
           (desired-indent nil)
           (retry t)
+          whitespace-after-open-paren
           calculate-lisp-indent-last-sexp containing-sexp)
       (cond ((or (markerp parse-start) (integerp parse-start))
              (goto-char parse-start))
@@ -976,6 +977,7 @@
           nil
         ;; Innermost containing sexp found
         (goto-char (1+ containing-sexp))
+        (setq whitespace-after-open-paren (looking-at (rx whitespace)))
         (if (not calculate-lisp-indent-last-sexp)
 	    ;; indent-point immediately follows open paren.
 	    ;; Don't call hook.
@@ -990,9 +992,11 @@
 		    calculate-lisp-indent-last-sexp)
 		 ;; This is the first line to start within the containing sexp.
 		 ;; It's almost certainly a function call.
-		 (if (= (point) calculate-lisp-indent-last-sexp)
+		 (if (or (= (point) calculate-lisp-indent-last-sexp)
+                         whitespace-after-open-paren)
 		     ;; Containing sexp has nothing before this line
-		     ;; except the first element.  Indent under that element.
+		     ;; except the first element, or the first element is
+                     ;; preceded by whitespace.  Indent under that element.
 		     nil
 		   ;; Skip the first element, find start of second (the first
 		   ;; argument of the function call) and indent under.



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-05-01  6:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-03  0:12 Proposal: change indentation rules for one-dimensional lists in emacs-lisp-mode and lisp-mode akater
2020-03-03 18:14 ` Richard Stallman
2020-03-03 20:09   ` Stefan Monnier
2020-05-01  6:26     ` akater

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).