Giter Site home page Giter Site logo

fmt's Introduction

fmt's People

Contributors

bogdanp avatar cassanof avatar jenntoo avatar sorawee avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fmt's Issues

Error: `#%declare`: not an allowed declaration keyword?

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

do not comment-out so-called "hash-bang"

On UNIX-like systems #! on top of the file tells the shell to run the specified interpreter when file is called without one.
Right now fmt comments-out hash-bang on top of the file making it impossible to run racket scripts in PATH.

image

Ugly format for custom define-like

.fmt.rkt

#lang racket/base

(provide the-formatter-map)
(require fmt/conventions)

(define (the-formatter-map s)
  (case s
    [("my-define") (format-define-like)]
    [else #f]))

file.rkt

#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 ...))]))

Any way to automatically limit comment line width in racket files to a certain value?

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.

Format stdin->stdout

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.

Quickscript

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.

formatting of here strings results in syntax error.

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.

Function argumets formatting

1.

;; 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)

2.

;; 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)

Format but do not modify

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

Submit to code formatting "aggregators"?

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

Weird format for structs with long field names / options

Original

(struct S
            ([aaaaa #:mutable] [bbbbbbbbbbb #:mutable]
                         [ccccc #:mutable]
                         [ddddd #:mutable]
                         [eeeee #:mutable])
  #:transparent)

After

(struct S
        ([aaaaa #:mutable] [bbbbbbbbbbb #:mutable]
                           [ccccc #:mutable]
                           [ddddd #:mutable]
                           [eeeee #:mutable])
  #:transparent)

Expected?

Shouldn't fmt change it to something like:

(struct S
        ([aaaaa #:mutable] 
         [bbbbbbbbbbb #:mutable]
         [ccccc #:mutable]
         [ddddd #:mutable]
         [eeeee #:mutable])
  #:transparent)

Inconvenient linebreak choice in match clause

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))]))

diff-friendly formatting?

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?

Testing

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?

Possible bug added in commit: 08c49588a28153c920b5dafba22721e5a1f158a8

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

How to use the CLI option --config

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!

fmt reorders tokens

#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

Bad formatting for #reader line in teachpacks

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.

No output to standard out in case of error

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.

Carriage return breaking formatting

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.

debug mode

E.g., we can add more core forms that asserts non-emptiness of layouts, and define-pretty can insert this core form automatically.

test #lang

Other #lang might not be suitable for fmt.

Better support for define/contract

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.

one-line define behavior

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.

Permit multiple formats for the same form

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

Documentation: Possible example of how to run on commandline

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.