tweag / topiary

https://topiary.tweag.io/
MIT License
575 stars 29 forks source link

Scope-dependent formatting outside the scope #639

Closed Xophmeister closed 1 month ago

Xophmeister commented 1 year ago

Is your feature request related to a problem? Please describe. In Issue #635, it's been shown that the following forms (in Nickel) cannot be distinguished:

{
  # Form 1
  symbol | annotation = {
    foo = 123
  },

  # Form 2
  symbol
    | annotation
    = {
      foo = 123
    }
}

The above code has been formatted by hand. With Topiary queries, the best you can do are the following, mutually exclusively:

Form 1 Formatted

{
  # Form 1
  symbol | annotation = {
    foo = 123
  },

  # Form 2 (not enough indent on the RHS)
  symbol
    | annotation
    = {
    foo = 123
  }
}

Form 2 Formatted

{
  # Form 1 (too much indent on the RHS)
  symbol | annotation = {
      foo = 123
    },

  # Form 2
  symbol
    | annotation
    = {
      foo = 123
    }
}

We have opted for form 2 to be formatted, as it is widely attested in (e.g.) the Nickel stdlib.

These forms, as far as Topiary is concerned, are indistinguishable from just their syntax tree and "multi-lined-ness" (modulo the current Nickel formatting queries). It doesn't appear possible to define a query to make the distinction. (See https://github.com/tweag/topiary/issues/635#issuecomment-1745161607 for discussion on attempts.)

Describe the solution you'd like

The #multi_line_scope_only! predicate seems to offer to closest solution, conceptually. However, the query doesn't match because (AIUI; see context, below) the matched nodes overspill the scope. For example:

node                \
  node     \         | matched
    node    | scope  | subtree
  node     /         |
  node              /

Perhaps a #non-strict-scope!, or similar, predicate would suffice to make the queries more permissive, in this case. (Again, see context for my presumptions!)

Additional context The hypothesized cause of the problem is just to the best of my understanding. I haven't examined the code to see if this is the actual reason when the queries don't match; there's a high chance I'm incorrect! (It may even be possible to distinguish these forms in Topiary already, but I've been unable to do so. In which case, this issue becomes a call for better documentation.)

If this is what's going on, then the only instance that would make sense is when the scope is a subtree of the match. Applying formatting on disjoint scopes and match subtrees doesn't make sense.

(Tagging @nbacquey for his opinion...)

nbacquey commented 1 month ago

Unless I'm mistaken, this issue has been closed by #755

simonzkl commented 1 month ago

@Xophmeister should #635 be reopened now that this has been fixed? Or are there no changes required here?

https://github.com/tweag/topiary/pull/755 doesn't touch Nickel queries.