Does anyone know a way to align multiple maps as if they're rows in a spreadsheet? For example: https://github.com/day8/re-com/blob/master/src/re_com/alert.cljs#L31-L45
Yeah. The code isn't very well thought out. But you can build on it to get what you want I think
More detailed question:
A vector of maps is a common structure.
β’ Some devs like to format this as a "table", putting each map on a single line, and aligning the matching keys in each map. For instance:
https://github.com/day8/re-com/blob/master/src/re_com/alert.cljs#L31-L45
β’ Other devs like to run clojure-align on the entire buffer.
I want to be both kinds of devs.
β’ I can "tabularize" the structure somewhat, by pressing M-x align-regexp <return> <space> : <return>. But that just aligns all the keywords, whether or not they "match" across lines or not. It would easily align something like this:
[{:a 1 :b 2 :c 3}
{:a 1 :c 3}]
When actually, I want:
[{:a 1 :b 2 :c 3}
{:a 1 :c 3}]
I wonder if I could use regex capture groups to achieve this.
β’ clojure-align works great, but it destroys all the nice tabular alignment. I wonder if I could configure it to ignore these structures, or start using a different tool to auto-align the whole buffer.
https://cljdoc.org/d/zprint/zprint/1.3.0/doc/i-want-to-change-/the-options-map-by-defining-functions-to-format-based-on-content
zprint (which is great) supports UDFs, but I haven't used them, so I can't speak to whether they can do exactly what you're describing
https://gist.github.com/hkjels/202483d446b552ff96b2c3137665aed1
Does this work for you?
emacs has an align-regex or something like that. that might work out for you?
Nah. ialign and align-regexp can align on : as klimo mentioned, but you can't have proper columns that work if you omit a key in one of the maps.
I used to use https://github.com/Malabarba/aggressive-indent-mode that aligned maps and other pairs. It worked well when editing the maps, not sure about fixing maps once they are created. zprint can do some magical things with existing code structure.
@hkjels - cool, i'll examine this. My first attempt to use it highlights an edge case - I assume it's because of some colons which aren't part of a keyword:
[{:a 1 :b ":hello"}
{:a 2 :b ":world"}]
[
{:a 1 :b " :hello " :world }
{:a 2 :b " :hello :world " }
]Why does elisp format IFs like this? Why are the "then" and "else" not aligned like in clojure?
(if true
(message "true")
(message "false"))Probably because you can write more than 1 expression in the else branch and you will be able to distinct branches by indentation level.
That's my guess
i actually kinda like this style
I just found https://github.com/bbatsov/emacs-lisp-style-guide it says "Note that the βthenβ clause of an if form is a special argument, indent it by 4 spaces."
It does not say what's "special" about it. Probably what @rrudakov said.
I can't offer you the logical explanation behind this convention, but I have yet another technical bit: in elisp, the indent is controlled via lisp-indent-function, if you eval (get 'if 'lisp-indent-function) you get 2, in clojure-modes the indent is controlled by clojure-indent-function, so evaling (get 'if 'clojure-indent-function) gets you 1. But what were the reasons for a different indentation convention, I'm now curious myself.