antonmedv / fx

Terminal JSON viewer & processor
https://fx.wtf
MIT License
19.07k stars 438 forks source link

Any interest in implementing .[] in interactive mode? #305

Open mtHuberty opened 7 months ago

mtHuberty commented 7 months ago

When viewing JSON in interactive mode, I'd love to be able to dig into arrays of objects by doing .[]. For example, in regular processing mode, I can pass a filter to fx on a top level array of objects like the example below, and get back a list of emails. So using this command curl "https://jsonplaceholder.typicode.com/comments" | fx '.[].email' will process JSON like this

[
  {
    "postId": 1,
    "id": 1,
    "name": "id labore ex et quam laborum",
    "email": "Eliseo@gardner.biz",
    "body": "laudantium enim quasi est quidem magnam voluptate ipsam eos\ntempora quo necessitatibus\ndolor quam autem quasi\nreiciendis et nam sapiente accusantium"
  },
  {
    "postId": 1,
    "id": 2,
    "name": "quo vero reiciendis velit similique earum",
    "email": "Jayne_Kuhic@sydney.com",
    "body": "est natus enim nihil est dolore omnis voluptatem numquam\net omnis occaecati quod ullam at\nvoluptatem error expedita pariatur\nnihil sint nostrum voluptatem reiciendis et"
  }
]

into a result like this

[
  "Eliseo@gardner.biz",
  "Jayne_Kuhic@sydney.com"
]

But I can't achieve the same thing in interactive mode. If I try typing .[].email, as soon as I type the second dot, it clears my prompt and refuses to dig into the array. Doing .[0].email works but only gives the first email.

Would this be a PR that you would support? I'm not familiar enough with the codebase to make this change myself yet, but if this is a change you would allow, I could try to start familiarizing myself to work through opening a PR.

Also if so, are there contribution docs anywhere? I couldn't find them. Thanks!

antonmedv commented 6 months ago

Yes, this is due to the fact what path is not a freeform JavaScript expression. It's a path of a cursor in JSON.

I have an idea to add full support arbitrary JS expressions in future as well.

One think I need to figure out, how to do argument splitting. Now fx relays on shell args splitting:

fx '.[].foo' func 'x => x.length'

How this string will be represented in a single string? Same with quotes? But this is ugly solution. With |?

.[].foo | func | x => x.length
CouscousPie commented 2 months ago

This should definitely be implemented. On a related note, it should be possible to just increment, wherever you are like when being in .[3].foo.bar to jump with Ctrl+PgDown to .[4].foo.bar, which would enhance navigation and overview substantially. Should I open a seperate issue for that? Seems like it would be easier to implement.