Skip to content

Add @prepend_antiline/@append_antiline #989

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
rpost opened this issue May 13, 2025 · 1 comment
Open

Add @prepend_antiline/@append_antiline #989

rpost opened this issue May 13, 2025 · 1 comment

Comments

@rpost
Copy link

rpost commented May 13, 2025

Hi all,

First of all: Topiary is great!

I'm currently experimenting with formatting java with topiary and I miss something similar to https://topiary.tweag.io/book/reference/capture-names/horizontal-spacing.html?highlight=anti#append_antispace--prepend_antispace but for vertical spacing.

My use case: I want all block-s to be formatted like this:

if (myCondition) {
}

void myMethod() {
}

Like we used to format blocks in java: with newline after closing brace. As usual when there is general rule there is also exception:

try {
} catch(Exception e) {
} finally {
}

It would be very handy to express general rule as:

  (block
      .
      "{" @prepend_space @append_hardline @append_indent_start
      (_)*
      "}" @prepend_hardline @prepend_indent_end @append_hardline
      .
    )

and then enumerate exceptions which doesn't have trailing newline:

(try_statement
  (block
      "}" @append_antiline
      .
    )
)

Without this I have to enumerate every possible combination of parent<->block and apply rules individually.

@Xophmeister
Copy link
Member

Thanks for your suggestion 👍

I think the way we'd normally do this is by specifying a rule that applies formatting within the block, like this:

(block
  .
  "{" @append_spaced_softline @append_indent_start
  "}" @prepend_spaced_softline @prepend_indent_end
  . 
)

Here I'm using spaced softlines for the case where you have a one-liner that gets formatted like { foo }, which is a common pattern.

Then, for vertical spacing between nodes, one could use an alternation:

(
  [
    (conditional)
    (for_loop)
    (try_catch_block)
    (etc_etc)
  ] @append_hardline
  .
  (_)
)

Or, depending on how uniform these node types are, separate rules for each...which is probably more likely, as those node types will presumably need fine-tuning formatting of their own. For example, adding the space between the keyword, etc. and the block.

I think the case for an "antiline" makes sense when the grammar is very regular, with a handful of exceptions. Your Java example might fit that pattern, so it's worth thinking about, but how I describe above may make for more tractable queries...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants