Skip to content
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

how do you deal with string interpolations? #488

Closed
BrianHicks opened this issue May 26, 2023 · 6 comments · Fixed by #493
Closed

how do you deal with string interpolations? #488

BrianHicks opened this issue May 26, 2023 · 6 comments · Fixed by #493

Comments

@BrianHicks
Copy link

As I mentioned in #481, I'm making a toy formatter for Ruby just to learn how this all works. I have a question about how you'd preserve spaces in interpolated strings.

The Ruby grammar has strings with string_content and interpolation nodes that can live inside them. The string_content frequently has whitespace at either end. How do I preserve that? For example, here's an input string:

"1 plus 1 is #{2}, 1+1=#{2}"

If I have these rules:

;; Strings
; Leave spaces alone, except for removing spaces around interpolation delimiters
(string_content) @do_nothing
(interpolation . "#{" @append_antispace)
(interpolation "}" @prepend_antispace .)

Then it's formatted like so, when I would want it to be left exactly as it was:

"1 plus 1 is#{2}, 1+1=#{2}"

(Doing (string_content) @leaf does the same thing, by the way.)

Is there a way to turn off formatting within some node, but only for its immediate children? Or to declare that some child gets a pass and that space within the text content of that node should be included? (Examining the nodes with tree-grepper shows that this is the case; I've attached it below.) Maybe something with a name like @append_preserve_whitespace/@prepend_preserve_whitespace?

$ tree-grepper -q ruby '(string_content)' -f pretty-json ./topiary/tests/samples/input/ruby.rb
[
  {
    "file": "./topiary/tests/samples/input/ruby.rb",
    "file_type": "ruby",
    "matches": [
      {
        "kind": "string_content",
        "name": "query",
        "text": "1 plus 1 is ",
        "start": {
          "row": 7,
          "column": 2
        },
        "end": {
          "row": 7,
          "column": 14
        }
      },
      {
        "kind": "string_content",
        "name": "query",
        "text": ", 1+1=",
        "start": {
          "row": 7,
          "column": 20
        },
        "end": {
          "row": 7,
          "column": 26
        }
      }
    ]
  }
]
@ErinvanderVeen
Copy link
Collaborator

Hej, thanks for this issue!

The team is currently on holiday, but I will discuss with them when they return tomorrow!

@nbacquey
Copy link
Member

Hi @BrianHicks, thanks for the issue indeed!
I'm haven't had a thorough look at your problem yet, but I'm not sure the problem lies with Topiary (it could be with the Ruby tree-sitter grammar instead).
Could you please share the output of:

echo '"1 plus 1 is #{2}, 1+1=#{2}"' | RUST_LOG=debug topiary --language rust -sf /dev/stdin

Also, as a side note about your query file, the rule (string_content) @do_nothing serves no purpose.
The do_nothing directive is used to "cancel" a matching pattern, usually if some condition is met. For instance:

(
  (string) @append_hardline
  .
  (comment)? @do_nothing
)

This query will match on any (string) node (the (comment) is optional), to which it will append a line break, except if the (string) node is followed by a (comment). In this case, the @do_nothing directive will trigger, and cancel all other directives of the pattern.

@BrianHicks
Copy link
Author

I get an error when I run that: "error: invalid value 'rust' for '--language '". Same if I try with --language ruby, which I think you might have meant? I was running it with cargo run instead of topiary directly, though, although I don't think that should make a difference?

As I've shown above with another tree-sitter tool, the whitespace is included in the string_content node in the Ruby grammar. Is that the kind of issue you're thinking about?

@nbacquey
Copy link
Member

@BrianHicks I did mean --language ruby indeed, thanks for noticing. The whitespace is indeed included in the string_content node up to the very end of the formatting process.

I managed to track down the source of your issue to #492, we'll work on that.

@BrianHicks
Copy link
Author

How do you get that --language thing to work, though? I see it in the README but it always complains that I'm using an invalid value?

Thanks for finding #492!

@nbacquey
Copy link
Member

How do you get that --language thing to work, though? I see it in the README but it always complains that I'm using an invalid value?

The --language flag is only active for "supported" languages (read "non-experimental"). To enable it, you have to edit the associated enum and function in supported.rs.

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

Successfully merging a pull request may close this issue.

3 participants