Closed default-kramer closed 2 years ago
Yes, the indenter and formatter are different. An indenter will never insert or remove a newline. A formatter on the other hand aims to produce code with minimal height, subjected to the constraint that the code fit the page width limit. So it could insert a newline if your original code is too wide, or remove a newline if doing so will reduce the number of lines.
If you want a customizable indenter, both DrRacket and Racket Mode are customizable in different aspect. DrRacket allows you to use regexp to match forms to indent "begin-like keyword", "define-like keyword", "lambda-like keyword", and "for/fold-like keyword" (Preferences > Editing > Indenting). On the other hand, Racket Mode allows you to create a new keyword "category".
Currently it's not possible for fmt
to do what you want, and you intuited correctly that it's somewhat not compatible with the project goal.
But theoretically, fmt
is also flexible enough to do what you want (at least for this specific case). As you mentioned, you can create your own if
-formatter. The code fragment that is the input to formatters ideally should contain the source locations (right now I haven't implemented this feature -- see #14). With the source locations, you can check if the "conditional" and the "branches" are on the same line. Depending on the answer, you would format differently.
Also note that while one newline is insignificant in fmt
, two or more newlines are not (this is the what most code formatters for most languages do). fmt
will try to preserve these significant newlines. For example, currently fmt
formats
#lang racket
(
if test
hello
world
)
to:
#lang racket
(if test
hello
world)
Thank you for the detailed explanation. It seems what I currently want is an indenter with maybe some very light formatting capabilities. Still, the idea of a standard formatter is intriguing (the Go community seems to universally love gofmt).
First of all, thanks for doing this project. For me, DrRacket's formatting is what I want 99% of the time, but every now and then I wish I could customize it. I think this project might be able to grow into my preferred solution.
=========
Consider the following example file
When I run DrRacket's indenter on this, nothing changes. This is the behavior I want. The rationale is that I added those newlines deliberately and unless I am breaking some rule I would like to keep them where they are. (Where "breaking some rule" means exceeding the width, incorrect indentation, or something like that.) But when I run fmt, the output is
I read the docs about formatters and I'm not sure if it is possible/easy to customize fmt to work like DrRacket for this example. Would this be implemented as a single formatter for the
if
form? Or maybe the formatter map should mapif
to a list of formatters. (But then how would it decide which one to use when the input doesn't match any of them?)Is what I want to do even philosophically compatible with your project goals? Perhaps an "indenter" and a "formatter" are two different things, and I want an indenter.
PS - I'm sure I can find a non-contrived example from real code if you're wondering "why do you want to do this?"