@pez, to start off with the issue that started this thread – yes, zprint is almost totally opinionated about where to place newlines. You couldn’t find any way to configure it to just indent code because they don’t exist. There is a very limited capability to respect new-lines in vectors, but that isn’t at all what you are looking for. To briefly recap what I said in the “community formatter” thread, there are indenters and there are formatters, and the difference is how much respect they have for newlines in the code (with indenters having a lot, and formatters having little to none). Obviously there is a spectrum of behavior from one to the other, and zprint was written explicitly to be on the formatter end of the spectrum. I am currently exploring how and whether it is possible for zprint to be enhanced to move some distance toward the indenter end of the spectrum (due in part to a current issue, and in part because this is important to you). I honestly don’t know how this will work out. Prior to your interest I had about decided that respecting blank lines was what I was going to try for, and ignore all other newlines. But that’s not going to meet your needs. So, we’ll have to see about this.
Also, you indicate that Calva has two modes – “as you type”, and “on command or save”. Zprint is a great option for a “command or save” formatter, and would hopefully be easy to integrate for that mode. That is how it is used today in the existing editor integrations and by anyone using it as a unix “filter” with their editor or IDE. If there is something that it needs to do to be a “command and save” formatter, please let me know, as nothing I’ve noticed in these posts suggests that it isn’t ready for that role in Calva. I’ll be glad to help with any issue or questions you have there.
Certainly zprint was never designed to be a formatter that would do “while you type” indentation. That doesn’t mean that it can’t be stretched to do so. I’d like to gather the list of things you need a “while you type” indenter to do here, so we can both assess how close zprint already is and what needs to be done to get there.
“More respect for new-lines.” Does this mean that you need a pure indenter, that is, something that respects all existing new-lines? Or is there some intermediate ground? This is by far the most challenging of the five requirements I’ve listed here, just FYI.
“Consider cursor position and selection before and after reformatting the text.” This makes sense, but I’m not clear on the meaning of “consider”. zprint has an intermediate output format that contains a lot more data than shows up in the string output. I have some escapes to output this information for testing, but it would be simple to make it a defined output format. This is essentially a vector of 3-tuples, where each tuple has
[<string> <color-keyword> <element-keyword>]. It has
:right elements in it, and currently accepts “paths” to specific elements. This is because zprint supports a “focus” highlighting mode, where on input you tell it what expression to highlight. The way you tell it what expression to highlight is to give it a path in a vector, where each element is how far you go to the right at this level before you go down. It works for the uses to which it has been put, it only gets you to an expression, not a character. As it happens, this path doesn’t change regardless of what zprint does to the formatting. This is a bit of a long shot, but if it would help, you could give zprint a path before you called it, and you could accept the intermediate format on output, and zprint could easily tag the element that your path pointed to in that intermediate format. To recover the output string, you just
(apply str (map first <intermediate-format-vector>). Which is what zprint does on output. Just a thought.
“Format a given range of code.” zprint will format any “top-level” form now. That is what it does best – to do a whole file is actually a bit more work. It doesn’t know how to do less than a top-level form, since to do that it doesn’t know the where to indent it. I can imagine that if you were to give zprint the current place on the line, and the current indent, then I might be able to enhance it to operate within those boundaries. It is always going to have to be for full expressions, that is a given. The parser it uses does not parse things that are not expresions. Which may be a blocking issue right there, I don’t know.
“Format a given range from the cursor.” There are two ways to think about this. This could just be a situation where you would do #3, and you would find an expression “up” from where you are, and tell zprint to format that. Alternatively, zprint will take a full top-level expression/form, and will format it, and then only output a configurable number of lines before and a configuration number of lines after the “focus” point. Which might (or might not) be more what you are looking for here.
“Access to the internal AST/zipper format.” zprint is called zprint because it does zippers. I haven’t documented a zipper as an input because nobody seemed to care, but that would be easy to do. zprint doesn’t modify the zipper it creates from parsing the source, it builds its own output (as mentioned above). But if your editor kept a zipper updated with changes, you could keep giving that zipper to zprint and save the parsing time. That would work great! Overall, I think using a zipper as the input would make most of the requirements easier. Not #1 though, unfortunately.
These are the 5 requirements that I’ve gleaned from this thread and your comments in the other thread, but I may well have missed some. Please add any additional requirements, and let me know your comments on these. It would be useful if you could prioritize these as “must have” and “nice to have”. Also, I believe these 5 requirements are all for the “as you type” formatting. If there are any requirements for the “command or save” more complete formatting, please let me know. If any of the things I’ve mentioned as possible solutions to the 5 requirements above would be useful for the “command or save” formatting, that would be good to know.
We can keep using this thread to discuss things for a while. When and if we think we have a plan, I’ll want to turn these into specific issues in the zprint repo for tracking.
Again, my apologies for missing this thread.