0
votes

I'm using Emacs 25.1, with the latest stable release of clojure-mode. When clojure-mode (not in other major modes like js2-mode) is turned on, everything is strictly aligned, no extra whitespace is allowed before any forms. For example,

(def
 last (fn ^:static last [x]
        (if (next x)
          (recur (next x))
          (first x))))

I can't insert a space (automatically removed after insertion) before the first non-whitespace character on each line. This kind of behavior is just not desirable to me. I tried changing the variables in the Clojure group, but nothing seemed to work. How can I turn this behavior off?

1
Are you saying you want a space before 'last' (in your line 2?) If so, that is vary odd formatting choice (odd for any flavour of lisp). You might be able to affect things with different values for clojure-indent-style, but it isn't really clear what your indent rules really are. I suspect your fighting against the mode. Other modes, like js2 tend to be more liberal because the syntax of the language is more complicated and it is harder to define consistent rules. Lisp languages have little syntax, so more rigid formatting rules. BTW why (def last (fn ...)) instead of (defn last ....)?Tim X
Are you using advanced editing capabilities like paredit or the like? I don't and for me Emacs never formats any code automatically, only when I ask it to.Stefan Kamphausen
@TimX given the snippet above, say if I try to insert a space before (def, can't happen, the space character just get deleted automatically right after the insertion. The snippet is taken from the source of clojure.core. defn hasn't been defined at that point :)damonh
@StefanKamphausen Tried disabling paredit-mode, still the same thing.damonh
Oh, I forgot the mention, my emacs.d was taken from Steve Purcell. I only changed some key bindings and the theme.damonh

1 Answers

1
votes

It isn't exactly clear what you mean, but I suspect you are referring to the way Clojure will align forms in things like let bindings so that all the symbols and values being bound are aligned i.e.

(let [a-val1      (something-1)
      another-val (something-2)
      final-col   12]
  (do-some-stuff))

rather than

(let [a-val1 (something-1)
      another val (something-2)
      final-col 12]
  (do-some-stuff))

If this is the case, then there are a few things you can try.

Look at the variable clojure-align-forms-automatically

clojure-align-forms-automatically is a variable defined in ‘clojure-mode.el’. Its value is t Original value was nil

This variable is safe as a file local variable if its value
satisfies the predicate ‘booleanp’.

Documentation: If non-nil, vertically align some forms automatically. Automatically means it is done as part of indenting code. This applies to binding forms (‘clojure-align-binding-forms’), to cond forms (‘clojure-align-cond-forms’) and to map literals. For instance, selecting a map a hitting ‘M-x indent-for-tab-command’ will align the values like this: {:some-key 10 :key2 20}

You can customize this variable.

This variable was introduced, or its default value was changed, in version 5.1 of the clojure-mode package.

The other variable which you might want to look at is clojure-indent-style

clojure-indent-style is a variable defined in ‘clojure-mode.el’. Its value is ‘:always-align’

This variable is safe as a file local variable if its value
satisfies the predicate ‘keywordp’.

Documentation: Indentation style to use for function forms and macro forms. There are two cases of interest configured by this variable.

  • Case (A) is when at least one function argument is on the same line as the function name.
  • Case (B) is the opposite (no arguments are on the same line as the function name). Note that the body of macros is not affected by this variable, it is always indented by ‘lisp-body-indent’ (default 2) spaces.

Note that this variable configures the indentation of function forms (and function-like macros), it does not affect macros that already use special indentation rules.

The possible values for this variable are keywords indicating how to indent function forms.

‘:always-align’ - Follow the same rules as ‘lisp-mode’.  All
args are vertically aligned with the first arg in case (A),
and vertically aligned with the function name in case (B).
For instance:
    (reduce merge
            some-coll)
    (reduce
     merge
     some-coll)

‘:always-indent’ - All args are indented like a macro body.
    (reduce merge
      some-coll)
    (reduce
      merge
      some-coll)

‘:align-arguments’ - Case (A) is indented like ‘lisp’, and
case (B) is indented like a macro body.
    (reduce merge
            some-coll)
    (reduce
      merge
      some-coll)

You can customize this variable.

This variable was introduced, or its default value was changed, in version 5.2.0 of the clojure-mode package.

There are some other alignment/indentation variables which you may also want to check out - try M-x customize-group clojure-mode and M-x customize-group cider to browse and see if anything is relevant. You might also find something relevant on the cider documentation site. In particular, look at the manual section on indentation

UPDATE EDIT: Based on additional information from the OP communicated in comments, I decided to edit and extend this answer. I've left the original response as I feel it may be useful to others who search and find the OPs question. However, with the additional info in the comments, I don't think the answer addresses the OPs actual issue, so have extended the answer below which I hope will help.

Some Emacs modes are more rigid or enforce code format more strictly than others. This is particularly the case with vary regular languages like Clojure (and most lisps generally) whee the syntax is minimal and the rules regarding code indentation are easier to define and tend to have wide consensus.

The situation for the OP is further complicated because they are using a pre-defined Emacs configuration - in this case Steve Purcell's emacs.d, which is one of my favourite pre-defined or canned Emacs configurations. The one drawback with these pre-defined configurations is that they will turn on and define many optional features of the Emacs editor which may or may not be in-line with user personal preferences. Emacs tends to have a vary conservative position when it comes to new features or enhancements. Often, they are disabled by default to avoid impacting new users. The cost for this conservative approach is that over time, Emacs can seem primitive or less feature rich compared to other editors to new users who expect some of this behaviour to be enabled by default. By using a canned configuration, you get one person's preferred setup without having to go through the often long and difficult process of doing it yourself. The downside is that when it does not match with the user's expectations, the user does not have the knowledge or understanding to make the changes and it is difficult to get help because others don't know/understand what their configuration is already.

As an example how using these pre-defined setups can complicated matters, when I last looked at the Purcell configuration, it used the ELPA package aggressive-indent, which enforces more rigid indentation rules and it could well be this package rather than clojure-mode which is enforcing the rigid indentation rule.

The OP mentions they are concerned regarding this auto-formatting as it could cause problems when contributing to other projects and issues with auto-formatting making the code look like there has been more changes than has actually occurred due to the version control picking up the whitespace adjustments. This issue mainly comes up over differences due to the use of tabs and spaces. to a large extent, such issues are less frequent these days as most version control systems can be configured to ignore whitespace changes.

In this case, my recommendation is to do nothing for now as there isn't a real issue yet. Continue to use the canned configuration and continue to ask questions, but also spend some time trying to learn and understand the configuration. At some point, once your comfortable with Emacs, you will likely want to re-configure the system to better meet your own personal taste. By this time, you will have a better understanding of Emacs, the various options it has and the way different modes work. When you run into specific real issues which you cannot solve, then post another question. It is likely at that point, you will have concrete information and someone will be able to provide specific help.