emacs

Kimo 2025-05-16T11:35:36.963179Z

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

hkjels 2025-05-19T10:50:54.060559Z

Yeah. The code isn't very well thought out. But you can build on it to get what you want I think

Kimo 2025-05-16T11:36:26.930769Z

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.

respatialized 2025-05-16T11:54:15.012979Z

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

πŸ‘€ 1
hkjels 2025-05-16T12:55:36.624429Z

Does this work for you?

dpsutton 2025-05-16T13:30:51.267169Z

emacs has an align-regex or something like that. that might work out for you?

hkjels 2025-05-16T14:10:46.470729Z

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.

practicalli-johnny 2025-05-16T14:52:11.325319Z

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.

Kimo 2025-05-16T21:57:56.956999Z

@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 "    }
]

clyfe 2025-05-16T15:08:33.791349Z

Why does elisp format IFs like this? Why are the "then" and "else" not aligned like in clojure?

(if true
    (message "true")
  (message "false"))

Roma 2025-05-16T15:13:03.149659Z

Probably because you can write more than 1 expression in the else branch and you will be able to distinct branches by indentation level.

πŸ‘ 2
Roma 2025-05-16T15:13:19.177349Z

That's my guess

dpsutton 2025-05-16T15:25:26.170739Z

i actually kinda like this style

clyfe 2025-05-16T15:26:52.333029Z

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."

clyfe 2025-05-16T15:28:15.079329Z

It does not say what's "special" about it. Probably what @rrudakov said.

ag 2025-05-16T18:53:14.383399Z

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.