clojure-emacs / clojure-mode

Emacs support for the Clojure(Script) programming language
916 stars 246 forks source link

EDN lists indented function style #610

Open ryantate opened 2 years ago

ryantate commented 2 years ago

Expected behavior

When editing an EDN buffer (file ending .edn), clojure mode should treat all paren forms as lists rather than functions, since EDN is a data format.

Thus if you choose to format a list with, say, key-value style pairs, default indentation should Just Work, like for vectors:

(:key1 :value1
 :key2 :value2
 :key3 :value3)

Actual behavior

EDN buffers are treated like Clojure code. Though this is mostly correct, it indents list contents like function calls rather than lists when each line contains more than 1 item:

(:key1 :value1
       :key2 :value2
       :key3 :value3)

I don't see any configuration vars to change this behavior. There are options for functional indent style, but no buffer-local way to redefine what is classified as a function (that I can see). All the function indent styles will keep the keys from lining up as they would in a vector, map, etc.

Steps to reproduce the problem

Find new file, /tmp/foo.edn. Type one of the above forms.

Workaround

I work around this by redefining a function in my init.el. Only the string-match clause in the or is new:

(require 'clojure-mode)
(defun clojure--not-function-form-p ()
  "Non-nil if form at point doesn't represent a function call."
  (or (string-match "\\.edn$" (or (buffer-file-name) (buffer-name)))
      (member (char-after) '(?\[ ?\{))
      (save-excursion ;; Catch #?@ (:cljs ...)
        (skip-chars-backward "\r\n[:blank:]")
        (when (eq (char-before) ?@)
          (forward-char -1))
        (and (eq (char-before) ?\?)
             (eq (char-before (1- (point))) ?\#)))
      ;; Car of form is not a symbol.
      (not (looking-at ".\\(?:\\sw\\|\\s_\\)"))))

Environment & Version information

clojure-mode version

clojure-mode (version 5.13.0)

Emacs version

GNU Emacs 27.2 (build 1, x86_64-redhat-linux-gnu, GTK+ Version 3.24.30, cairo version 1.17.4) of 2021-08-07

bbatsov commented 2 years ago

Yeah, that's a good point. Right now clojure-mode doesn't make any distinction between EDN and Clojure code. Perhaps we can introduce a derived mode edn-mode which indents differently.