View the documentation and demo at https://docs.racket-lang.org/fmt/.
sorawee / fmt Goto Github PK
View Code? Open in Web Editor NEWA code formatter for Racket
License: Other
A code formatter for Racket
License: Other
View the documentation and demo at https://docs.racket-lang.org/fmt/.
I'm getting this error on running raco fmt <my_file>.rkt
. Any idea what the issue is?
/root/.local/share/racket/7.9/pkgs/pretty-expressive/core.rkt:5:11: #%declare: not an allowed declaration keyword
at: #:unsafe
in: (#%declare #:unsafe)
location...:
/root/.local/share/racket/7.9/pkgs/pretty-expressive/core.rkt:5:11
context...:
/usr/share/racket/collects/racket/require-transform.rkt:269:2: expand-import
/usr/share/racket/collects/racket/private/reqprov.rkt:505:5
/usr/share/racket/collects/racket/require-transform.rkt:269:2: expand-import
/usr/share/racket/collects/racket/private/reqprov.rkt:266:21: try-next
/usr/share/racket/collects/racket/private/reqprov.rkt:243:2: require
/usr/share/racket/collects/syntax/wrap-modbeg.rkt:46:4: do-wrapping-module-begin
/usr/share/racket/collects/racket/require-transform.rkt:269:2: expand-import
/usr/share/racket/collects/racket/private/reqprov.rkt:584:5
/usr/share/racket/collects/racket/require-transform.rkt:269:2: expand-import
/usr/share/racket/collects/racket/private/reqprov.rkt:266:21: try-next
/usr/share/racket/collects/racket/private/reqprov.rkt:243:2: require
/usr/share/racket/collects/syntax/wrap-modbeg.rkt:46:4: do-wrapping-module-begin
#lang racket/base
(provide the-formatter-map)
(require fmt/conventions)
(define (the-formatter-map s)
(case s
[("my-define") (format-define-like)]
[else #f]))
#lang racket
(require (for-syntax syntax/parse))
(define-syntax (my-define stx)
(syntax-parse stx
[(_ (name:id args ...) body ...) #'(define name
(λ (args ...)
body ...))]))
after raco fmt file.std
(notice the extra newline after stx)
#lang racket
(require (for-syntax syntax/parse))
(define-syntax (my-define stx
)
(syntax-parse stx
[(_ (name:id args ...) body ...) #'(define name
(λ (args ...)
body ...))]))
Assuming a very long comment line in a racket file, like:
; This is a very long line, is there some kind of automatic tool that would chop this to chunks of a reasonable length for me?
I would assume running raco fmt
on such a file would chop the comment to chunks of 80 characters (the default raco fmt
line width), but that does not seem to happen, although other formatting is taken care of. Any way to get such auto-formatting? I am running racket 8.8.
(struct s
(a ;; a
b ;; b
c ;; c
)
#:transparent
#:mutable)
is formatted to:
(struct s
(a ;; a
b ;; b
c ;; c
)
#:transparent
#:mutable)
The following command line currently works:
echo '#lang racket' | raco fmt /dev/stdin
Can you make either raco fmt
(with no filename) or raco fmt --stdin
format from stdin to stdout? This would avoid the Linux/BSD-specific /dev/stdin
.
Minimal example:
tmp.rkt:
#!/usr/bin/racket
raco fmt tmp.rkt
:
;#!/usr/bin/racket
Here's a slightly improved quickscript:
https://gist.github.com/Metaxal/f45ea1a893a1bdedaadbeafd11144e3d
It formats either the selection, or the whole program if the selection is empty.
It should probably call DrRacket's indenter afterwards, but I couldn't find the API for it, which means I would need to dig the keybinding function string name, get the keymap, etc.
given the following code, the trailing HERE
that closes the "here string" will not be left on a line by itself. Instead the paren after it will be moved up, which makes the HERE
not end the string, which makes a syntax error for the rest of the file.
The temporary workaround is to add a comment on a line AFTER the end of string indicator and before the next parentheses.
(string->jsexpr
#<<HERE
{
"foo": "bar"
}
HERE
)
that gets transformed to end with HERE)
which breaks things.
To workaround the problem:
(string->jsexpr
#<<HERE
{
"foo": "bar"
}
HERE
; formatter break
)
the expected/correct behavior is to leave the closing of the here string on the line by itself and then on the following line close/open any parentheses at the same level of indentation that the "here string" began at.
;; test.rkt
(lambda (#:key x #:word y) 1)
raco fmt --width 25 test.rkt
got
(lambda (#:key x
#:word y)
1)
expected
(lambda (#:key x
#:word y)
1)
;; test.rkt
(lambda (a b c #:key x #:word y) 1)
raco fmt --width 25 test.rkt
got
(lambda (a b
c
#:key x
#:word y)
1)
expected
(lambda (a
b
c
#:key x
#:word y)
1)
Right now there are a lot of raise-read-error
with a bunch of #f
as srclocs.
Is it possible to tell fmt
to format (indentation, line breaks, etc) but not modify the code? In particular, I’d like fmt
to stop changing ( )
into [ ]
(in some of my source codes).
From greghendershott/racket-mode#561:
When you think it's stable enough, and if you want to get into "no good deed goes unpunished" territory 😄:
You might want to submit this to one or more packages that aggregate code formatters for various langs.
For example there's the Emacs package format-all-the-code.
Although there seem to be other things like unibeautify
and prettier
, those two examples are node packages --- I'm not sure your good deed warrants cruel and unusual punishment. 😉
Is integration with the racket langserver a goal? I'd really like for the langserver to come with autoformatting support out of the box.
(struct S
([aaaaa #:mutable] [bbbbbbbbbbb #:mutable]
[ccccc #:mutable]
[ddddd #:mutable]
[eeeee #:mutable])
#:transparent)
(struct S
([aaaaa #:mutable] [bbbbbbbbbbb #:mutable]
[ccccc #:mutable]
[ddddd #:mutable]
[eeeee #:mutable])
#:transparent)
Shouldn't fmt
change it to something like:
(struct S
([aaaaa #:mutable]
[bbbbbbbbbbb #:mutable]
[ccccc #:mutable]
[ddddd #:mutable]
[eeeee #:mutable])
#:transparent)
Formatting this code:
#lang racket
(define (eval exp env)
(displayln exp)
(match exp
[(? symbol?) (unbox (hash-ref env exp))]
[`(λ ,params ,@body) `(Function (,params ,@body) ,env)]
[`(,fun ,@args) (apply (eval fun env) (map (lambda (arg) (eval arg env)) args))]))
(define (apply fun args)
(match fun
[`(Function (,params ,@body) ,env) (let loop ([params params] [args args] [env env])
(displayln fun)
(if (or (null? params) (null? args))
;(if (and (null? params) (null? args))
(eval body env)
;(display "Too much or too little arguments given"))
(loop (cdr params) (cdr args) (hash-set env (car params) (box (car args))))))]))
Produces this output:
#lang racket
(define (eval exp env)
(displayln exp)
(match exp
[(? symbol?) (unbox (hash-ref env exp))]
[`(λ ,params ,@body) `(Function (,params ,@body) ,env)]
[`(,fun ,@args) (apply (eval fun env)
(map (lambda (arg) (eval arg env)) args))]))
(define (apply fun args)
(match fun
[`(Function (,params ,@body) ,env)
(let loop ([params params] [args args] [env env])
(displayln fun)
(if (or (null? params) (null? args))
;(if (and (null? params) (null? args))
(eval body env)
;(display "Too much or too little arguments given"))
(loop (cdr params)
(cdr args)
(hash-set env (car params) (box (car args))))))]))
In that output, these two lines look off:
[`(,fun ,@args) (apply (eval fun env)
(map (lambda (arg) (eval arg env)) args))]))
I was expecting this:
[`(,fun ,@args)
(apply (eval fun env) (map (lambda (arg) (eval arg env)) args))]))
or this:
[`(,fun ,@args)
(apply (eval fun env)
(map (lambda (arg) (eval arg env)) args))]))
So that both v-concat/kw
and v-concat
can both be used.
I use fmt all the time, and it rocks -- perhaps the only thing that bugs me is that the diffs after formatting can be huge, even after I change just a single line. For example, if I change a line such that it becomes longer than the max line length, it will get wrapped, which can cause a change of indentation in the rest of the scope. Is there any way around this?
For testing resyntax, I wrote #lang resyntax/testing/refactoring-test
so I could easily write tests like this. Is that an approach that would benefit fmt
as well?
Hi, Just tried to get this working but ran into an error on HEAD.
$> raco make main.rkt
raco make main.rkt
core.rkt:94:1: define-syntax-parse-rule: unbound identifier
in: define-syntax-parse-rule
compilation context...:
/home/noah/programs/libraries/racket-fmt/core.rkt
/home/noah/programs/libraries/racket-fmt/main.rkt
location...:
core.rkt:94:1
context...:
do-raise-syntax-error
for-loop
[repeats 1 more time]
finish-bodys
lambda-clause-expander
for-loop
loop
[repeats 23 more times]
module-begin-k
expand-module16
expand-capturing-lifts
temp118_0
temp91_0
compile15
/usr/share/racket/collects/compiler/private/cm-minimal.rkt:414:0: compile-zo*58
/usr/share/racket/collects/compiler/private/cm-minimal.rkt:705:15
...
Was able go back a few commits. It appears the first commit where I see the issue is:
08c4958
The default for raco fmt --width
is 80, but the Racket Style Guide prescribes 102 as a column limit. I think these should be consistent.
Well, add option to make this possible
There are stuff that might be able to sort safely. See e.g. https://github.com/russellw/racket-format/blob/master/sort.rkt (though a lot of stuff in there are actually not safe to sort). Perhaps provide an option to sort?
'(; abc
def)
is formatted to
'; abc
(def)
Would be nice to make it:
; abc
'(def)
And perhaps provide a way to prefer user config but falls back to project config -- or vice versa.
There is an undocumented option --config
raco fmt --config /path/to/myconfig.rkt
I am not familiar with Racket. Instead of using CLI option --xxx
directly, could you please provide an example to use user-config file with formatting rules like this:
myconfig.rkt:
width 60
limit 80
max-blank-lines 0
indent 3
Thanks!
#lang racket
(define-syntax (reverse-list stx)
(syntax-case stx ()
[(_ x ...) #`'#,(reverse (syntax->list #'(x ...)))]))
(reverse-list 3 42 1)
is formatted to:
#lang racket
(define-syntax (reverse-list stx)
(syntax-case stx ()
[(_ x ...) #`#,'(reverse (syntax->list #'(x ...)))]))
(reverse-list 3 42 1)
Reported by Mason from the Racket Discord
Hi, the #reader
line for DrRacket's teachpacks gets cut of by the formatter. demo:
;; The first three lines of this file were inserted by DrRacket. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname my-file) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f)))
becomes
;; The first three lines of this file were inserted by DrRacket. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader
(lib "htdp-intermediate-lambda-reader.ss" "lang")
((modname my-file) (read-case-sensitive #t)
(teachpacks ())
(htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f)))
DrRacket needs that in all one line, or it refuses it to read it.
I could push a fix if people want this into the main branch.
Was discussed in #43, but I now create a specific issue, for the sake of clarity. @sorawee, please feel free to (re-)close #43 if you think nothing should be done about the comment "issue".
Minimal example for this issue:
$ raco fmt
4
4
Please note that after the first 4
, I press <return>
and <ctrl-d>
. raco fmt
then outputs my unchanged input, which is what I expect. On the other hand:
$ raco fmt
(define
1:1:0: expected a)
to close(
context...:
/usr/local/share/racket/collects/syntax/readerr.rkt:15:2: -raise-read-error
.../match/compiler.rkt:559:40: f123
/home/alain/.local/share/racket/8.8/pkgs/fmt/read.rkt:123:0: read-top
/home/alain/.local/share/racket/8.8/pkgs/fmt/main.rkt:27:0: program-format
/home/alain/.local/share/racket/8.8/pkgs/fmt/raco.rkt:115:0
body of "/home/alain/.local/share/racket/8.8/pkgs/fmt/raco.rkt"
/usr/local/share/racket/collects/raco/raco.rkt:41:0
body of "/usr/local/share/racket/collects/raco/raco.rkt"
body of "/usr/local/share/racket/collects/raco/main.rkt"
That is when pressing <return>
and <ctrl-d>
after (define
. There my input is gone, which might be intended, but makes the program unusable as a filter, as far as I know.
For the sake of completion, what raco fmt -i
does is as far as I know perfectly fine. This issue is only relevant when the output is sent to standard out (and standard error) in case of error. Getting the error message to standard error is then perfectly fine too, since it can easily be redirected. The issue in this case is that nothing comes to standard out. That prevents the program from being used as a true filter, which would be composable through pipelines (typical UNIX principle). In that case, just outputting the input to standard out would solve this issue.
Hello, Windows' way of inserting line breaks ("\n\r") creates a problem in the formatter.
Here is a link to a file formatted using this style: https://gist.github.com/d2db686a7ad030ecb7a0524bd890ed98
the input file contains:
;; blah
;; MyStruct : String [List-of String]
(define-struct MyStruct [key rest])
;; AnotherStruct : MyStruct [List-of String]
(define-struct World [mystruct tried completed])
and raco fmt
outputs
;; blah
;; MyStruct : String [List-of Strin
(define-struct MyStruct [key rest])
])
;; AnotherStruct : MyStruct [List-of St
(define-struct World [mystruct tried completed])
which is broken code.
(values
;; Key
(key-stuff)
;; Value
(value-stuff))
should not be formatted to
;; Key
(values (key-stuff)
;; Value
(value-stuff))
from @JacobVanGeffen
If I have a file with execute permissions, raco fmt -i
will remove its execute permissions.
Developers tend to mix two of them together. Perhaps fmt
can have an option to convert them all to either of the variant, improving the consistency.
E.g., we can add more core forms that asserts non-emptiness of layouts, and define-pretty
can insert this core form automatically.
Other #lang
might not be suitable for fmt
.
See also #34 (comment) by @jessealama
(define/contract x integer? 1)
should be formatted that way, not
(define/contract x
integer?
1)
Also, we probably should support
(define/contract (f x) (-> integer? integer?)
(+ x 1))
The problem is that with our current pretty printer, this style will almost always be preferred over
(define/contract (f x)
(-> integer? integer?)
(+ x 1))
even though the first line is really long. Our new pretty printer can fix this problem, but let's wait for now.
I am not a fan of the following formatting:
(define 2list (λ (a b) (list a b)))
(define (2list a b)
(list a b))
I would personally like to define functions this small on one line, but I also want to use the shorthand version of define
. I understand whether or not it should be one line is a matter of taste, but it doesn't make sense to me that the expression that is more noisy is the one that is formatted as one line. To me that feels like a less subjective inconsistency.
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
#lang racket
(define x (if #t 'foo 'bar))
(define y (if #f
'foo
'bar))
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
#lang racket
(define x (if #t 'foo 'bar))
(define y (if #f 'foo 'bar))
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 map if
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?"
Hey there! I noticed that you made this formatter for racket, right in time also since I'm taking a class that's using swindle.
I was wondering if you guys could write an example of how to use the formatter through the cli. I'd appreciate it! Thanks a lot for making this.
It's common to use .
and ...
in macro definition. These should not be indented as though they were the body.
Hi Sorawee!
I'd love it if fmt
saw test-case
from RackUnit as a begin
, and formatted it as such. Is that possible?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.