racket / scribble

Other
197 stars 91 forks source link

`at-exp' changes indentation in whole document #54

Open leafac opened 8 years ago

leafac commented 8 years ago

CURRENT BEHAVIOR

In #lang racket, {braces} work the same as (parentheses) and expressions using either are indented the same:

#lang racket

(define foo
  `{(a)
    (b)})

(define foo-paren
  `((a)
    (b)))

In #lang at-exp, the @-expressions with {braces} are indented differently:

#lang at-exp racket

@foo{bar
 bar}

And that difference applies even to non-@-expressions with {braces}:

#lang at-exp racket

(define foo
  `{(a)
 (b)})

(define foo-paren
  `((a)
    (b)))

EXPECTED BEHAVIOR

Using #lang at-exp does not affect the indentation of non-@-expressions:

#lang at-exp racket

@foo{bar
 bar}

(define foo
  `{(a)
    (b)})

(define foo-paren
  `((a)
    (b)))

RELATED DISCUSSION

https://github.com/mbutterick/pollen/issues/124


Do you think this makes sense? If so, how can I help turning this idea into code?

rfindler commented 8 years ago

I think it makes sense to make this change. The code, perhaps confusingly, is in the https://github.com/racket/gui/ repo, tho. This is the code:

https://github.com/racket/gui/blob/master/gui-lib/scribble/private/indentation.rkt

leafac commented 8 years ago

@rfindler: Thank you for the reply. I'll look at the code and try to figure it out.

SuzanneSoy commented 8 years ago

I narrowed down the problem to the determine-spaces function, and I think it is needed to add a case for #\{ like for #\(, but only when the { is not preceeded by an @at-exp{.

I'm having trouble however writing this check, e.g. when I perform (send txt get-backward-sexp prev-posi) on a test which starts with #lang scribble/base it jumps to the a on @at-exp{, but performing get-backward-sexp on a test which deos not start with #lang scribble/base jumps all the way to the @ sign.

So far I got this:

…
[(equal? #\( (send txt get-character prev-posi)) #f]
[(and (equal? #\{ (send txt get-character prev-posi))
                (not (equal? 'text char-classify))
                (not (equal? 'text (send txt classify-position posi)))
                (let* ([prev-maybe-at-sexp
                        (send txt get-backward-sexp prev-posi)]
                       [preceeded-by-at-sexp
                        (or (and prev-maybe-at-sexp
                             (> prev-maybe-at-sexp 0)
                             (is-at-sign? txt (sub1 prev-maybe-at-sexp)))
                            (and prev-maybe-at-sexp
                             (is-at-sign? txt prev-maybe-at-sexp)))])
                  (not preceeded-by-at-sexp)))
           #f]
…

But it fails on a few tests (3) because my check "is this s-expression is preceeded by an @symbol" is unreliable, and I didn't manage to find a way to fix it.

leafac commented 8 years ago

@jsmaniac: Thank you for your progress. I get the general idea, but most of the implementation details are going over my head, for now. I'm going to further study and try to get the hang of things.