I'm kind of puzzled by the last couple of responses. Obviously very few forms (probably only macros) would have indentation specifications and editors can certainly disregard them, so I don't see the code being littered with indentation specs any time soon or some indentation being forced on everyone.
This idea is not something new - in Emacs Lisp there's a way to specify the indentation of a macro form which is pretty similar (via `declare`). Maybe there was something similar for CL as well, but right now I'm not 100% sure. As for things like the one-space indent, I'm not sure how related they are to Emacs's prominence in the Lisp world. It sounds more plausible that such conventions were established before the age of `lisp-mode`. On 17 September 2015 at 08:31, Colin Fleming <colin.mailingl...@gmail.com> wrote: > Unfortunately as tools developers we can't force our indentation > preferences on our users, although I'd be fine with it if you convinced > everyone to just use two spaces for everything, even though it's not my > preferred formatting. Cursive has supported this for ages (copied from > Emacs) but I don't know how many people actually use it. > > As above, I agree that this shouldn't be in the code. > > I also agree very strongly that this shouldn't just adopt whatever Emacs > does for formatting. The one-space indent for list forms, in particular, > drives me nuts and is purely an implementation detail, not because that > makes any sort of sense for code. > > You're right that the format spec is pretty obtuse, although we have far > worse out there (the pprint format, ahem). Separating the format spec out > into a separate doc would allow something more verbose to be used which > could be more expressive. > > On 16 September 2015 at 23:34, Chas Emerick <c...@cemerick.com> wrote: > >> Hi all; here to satisfy the quarterly quota to maintain my status as >> "that guy". >> >> This is a questionable proposal. It: >> >> * introduces completely orthogonal, transient concerns (presentation) >> into code, ideally a canonical, long-lived source-of-truth >> * sets up a bikeshed at the top of every def* form >> * adopts idiosyncratic implementation details of a particular editor's >> language support (the defrecord example's :indent is particularly obtuse >> IMO, even if you are aware of how clojure-mode is implemented) >> >> I *think* I coined the "always two spaces" shorthand for the (admittedly, >> minority) position that list forms should be formatted completely >> regularly, so as to: >> >> * make formatting a trivial operation, not requiring any "real" reading >> * eliminate this entire topic >> >> Here's the first time I talked about this IIRC: >> https://groups.google.com/forum/#!msg/clojuredev-users/NzKTeY722-I/3hmNvJulcksJ >> >> Best, >> >> - Chas >> >> >> On 09/13/2015 06:06 AM, Artur Malabarba wrote: >> >> Hi everyone, >> >> >> Over at CIDER we're adding a feature where the author of a macro (or >> function) can specify how that macro should be indented by adding an >> :indent metadata to its definition. This way the editor (and other >> tools, like cljfmt) will know what's the proper way of indenting any macro >> (even those custom-defined) without having to hardcode a bajillion names. >> >> Here's an example of how you specify the indent spec for your macros >> >> >> (defmacro with-out-str >> "[DOCSTRING]" >> {:indent 0} >> [& body] >> ...cut for brevity...) >> >> (defmacro defrecord >> "[DOCSTRING]" >> {:indent [2 nil nil [1]]} >> [name fields & opts+specs] >> ...cut for brevity) >> >> (defmacro with-in-str >> "[DOCSTRING]" >> {:indent 1} >> [s & body] >> ...cut for brevity...) >> >> >> We'd like to hear any opinions on the practicality of this (specially >> from authors of other editors). >> Below, I'll be saying “macros” all the time, but this applies just the >> same to functions. >> >> *Special arguments* >> >> >> Many macros have a number of “special” arguments, followed by an >> arbitrary number of “non-special” arguments (sometimes called the body). >> The “non-special” arguments have a small indentation (usually 2 spaces). >> These special arguments are usually on the same line as the macro name, >> but, when necessary, they are placed on a separate line with additional >> indentation. >> >> For instance, defrecord has two special arguments, and here's how it >> might be indented: >> >> >> (defrecord TheNameOfTheRecord >> [a pretty long argument list] >> SomeType >> (assoc [_ x] >> (.assoc pretty x 10))) >> >> >> Here's another way one could do it: >> >> >> (defrecord TheNameOfTheRecord >> [a pretty long argument list] >> SomeType >> (assoc [_ x] >> (.assoc pretty x 10))) >> >> >> *The point of the indent spec is not to specify how many spaces to use.* >> >> >> The point is just to say “a defrecord has *2* special arguments”, and >> then let the editor and the user come to an agreement on how many spaces >> they like to use for special and non-special arguments. >> >> *Internal indentation* >> >> >> The issue goes a bit deeper. Note the last argument in that defrecord. A >> regular function call would be internally indented as >> >> (assoc [_ x] >> (.assoc pretty x 10)) >> >> But this is not a regular function call, it's a definition. So we want to >> specify this form internally has 1 special argument (the arglist vector), >> so that it will be indented like this: >> >> (assoc [_ x] >> (.assoc pretty x 10)) >> >> The indent spec we're working on does this as well. It lets you specify >> that, for each argument beyond the 2nd, if it is a form, it should be >> internally indented as if it had 1 special argument. >> >> *The spec* >> >> >> An indent spec can be: >> >> - nil (or absent), meaning *“indent like a regular function call”*. >> - A vector (or list) meaning that this function/macro takes a number >> of special arguments, and then all other arguments are non-special. >> - The first element of this vector is an integer indicating how >> many special arguments this function/macro takes. >> - Each following element is an indent spec on its own, and it >> applies to the argument on the same position as this element. So, when >> that >> argument is a form, this element specifies how to indent that form >> internally (if it's not a form the spec is irrelevant). >> - If the function/macro has more aguments than the vector has >> elements, the last element of the vector applies to all remaining >> arguments. >> - If the whole spec is just an integer n, that is shorthand for [n]. >> >> >> *Examples* >> >> >> So, for instance, if I specify the defrecord spec as [2 nil nil [1]], >> this is saying: >> >> - defrecord has 2 special arguments >> - The first two arguments don't get special internal indentation >> - All remaining arguments have an internal indent spec of [1] (which >> means only the arglist is indented specially). >> >> Another example, reify is [1 nil [1]] (which should be easy to see now). >> >> >> (reify Object >> (toString [this] >> (something) >> else >> "here")) >> >> >> For something more complicated: letfn is [1 [[1]] nil]. This means >> >> - letfn has one special argument (the bindings list). >> - The first arg has an indent spec of [[1]], which means all forms >> *inside* the first arg have an indent spec of [1]. >> - The second argument, and all other arguments, are regular forms. >> >> (letfn [(twice [x] >> (* x 2)) >> (six-times [y] >> (* (twice y) 3))] >> (println "Twice 15 =" (twice 15)) >> (println "Six times 15 =" >> (six-times 15))) >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.