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

Commands that are both groups and have multi-mode cannot be listed #657

Closed
ret2libc opened this issue Feb 19, 2021 · 24 comments
Closed

Commands that are both groups and have multi-mode cannot be listed #657

ret2libc opened this issue Feb 19, 2021 · 24 comments
Assignees
Milestone

Comments

@ret2libc
Copy link
Member

ret2libc commented Feb 19, 2021

Work environment

Questions Answers
OS/arch/bits (mandatory) any
File format of the file you reverse (mandatory) any
Architecture/bits of the file (mandatory) any
rizin -v full output, not truncated (mandatory) rizin 0.2.0-git @ linux-x86-64 commit: b409ed1, build: 2021-02-19__12:14:03

Expected behavior

There should be a way to list the sub-modes of all commands, even the ones that are already the parent of a group, like z. Initially we were just appending ?, but that means that to get the longer help of a command you may have a lot of ? (e.g. z? gives the list of sub-commands of z, z?? gives the list of sub-modes of the command z, z??? gives the short description of the command z with standard output, z???? gives the longer description of the command z with standard output... It seems a bit too confusing).

Ideas?

Steps to reproduce the behavior

> z?
# it returns the list of sub-commands of `z`
Usage: z[?]   # Zignatures management
| z[j*qk]        # Show zignatures
| z.[*]          # Find matching zignatures
| zb[r]          # Search for best match
| z- <zigname|*> # Delete zignature
| za[fF]         # Add zignature
| zg             # Generate zignatures (alias for zaF)
| zo[sz]         # Manage zignature files
| zf<ds>         # Manage FLIRT signatures
| z/[*f]         # Search zignatures
| zc[n]          # Compare zignatures in current zignspace with another one
| zs[j*-+r]      # Manage zignspaces
| zi[j*qi]       # Show zignatures matching information
> z??
# it returns the longer description of `z`
Usage: z[j*qk]   # Show zignatures
> z.?
# z. is not the name of a group, so z.? shows the sub-modes
Usage: z.[*]   # Find matching zignatures
| z.     # Find matching zignatures
| z.*    # Find matching zignatures (rizin mode)

Additional context

By "sub-command" of z I mean commands like zi, zc, zg, zb, etc.
By "sub-mode" of z I mean all those things that behave exactly the same as z but provide an output in a different format, like zj, z*, zq, etc. These things actually are commands to the user, but they are handled by the same command handler and provide the same information just in different formats.

@ret2libc ret2libc added the shell label Feb 19, 2021
@ret2libc ret2libc self-assigned this Feb 19, 2021
@ret2libc ret2libc added this to the 0.2.0 milestone Feb 19, 2021
@caribpa
Copy link
Contributor

caribpa commented Feb 20, 2021

I've been thinking about this for a while and I am not so sure there's a non-confusing way of implementing this.

Actually, in my mind, the issue comes from the multi-purpose ? command, and the confusing ???.

How would I do it?

  • Appending ? to a command (ex: z?) shows just the "sub-modes" of the command (and hint about ?*)
  • Appending ?* to a command (ex: z?*) shows the "sub-commands" (like the current z? behavior) (and hint about ?**)
  • Appending ?** to a command (ex: z?**) shows recursively all sub-commands (like the current z?* behavior)

Now, the problematic ? command alone could be:

  • either a general help/tips for newbies (how to exit, how to find more help, etc)
  • or to perform what the ?? is currently doing

The issue of using ? to do what ?? is currently doing is that newbies won't know how to get help. But if ?? becomes ?, then ??? would become ??, which is consistent with how all the other commands list their help (so ??* and ??** would also work like in the rest of the commands).

For listing all the "base-commands" use ?* (like the current ? behavior), and use ?** to recursively list all commands (like the current ?* behavior).

Confusing, and still not so happy about the ? command, but what do you think?

@ret2libc
Copy link
Member Author

ret2libc commented Feb 22, 2021

Your solution addresses indeed the problem of having ? meaning different things based on the command (e.g. z? means "list all subcommands of z, while wv4? means "show me the short description of wv4"). However, there should also be a way to show short/long help for each command.

Maybe to avoid changing "drastically" the syntax we could have:

  • <cmd>? show all subcommands of <cmd>, if any. sub-modes count as sub-commands, because for the user they are essentially just sub-commands, after all.
  • <cmd>?? show a short description of <cmd>
  • <cmd>??? show a long description of <cmd>
  • <cmd>?* recursively show all sub-commands of <cmd>

This has the advantage of remaining "in line" with the existing syntax at the cost of having to do ?? just to get a short description of a command. On the other hand, it allows us to be consistent no matter what. If you want a (short) description you use ??, no matter where in the commands-tree the command is.

@ret2libc
Copy link
Member Author

@caribpa BTW if you want we have a Mattermost server where we discuss this and other stuff. https://rizin.re/community/ There's a special channel for "newshell" development to discuss in real time some random ideas/issues.

@caribpa
Copy link
Contributor

caribpa commented Feb 22, 2021

Your solution addresses indeed the problem of having ? meaning different things based on the command (e.g. z? means "list all subcommands of z, while wv4? means "show me the short description of wv4"). However, there should also be a way to show short/long help for each command.

Yeah, I realized later, I thought of two solutions for this:

  • Add an e variable (e help.verbose=true or e cmd.help=long) to control whether to list short or long help/description, making it long as default (as I don't think the newbies will complain about having too much help when listing all commands)
  • or, show by default the short help and adding a trailing ? show the full help (so z??, z?*?, and z?**? following what I suggested in the previous comment)

By the way, I suggested ** because it is used as recursive globbing in bash (when globstar is enabled), and in zsh by default.

Maybe to avoid changing "drastically" the syntax we could have:
[...]
This has the advantage of remaining "in line" with the existing syntax at the cost of having to do ?? just to get a short description of a command. On the other hand, it allows us to be consistent no matter what. If you want a (short) description you use ??, no matter where in the commands-tree the command is.

I agree it is not fun to change the syntax, though Rizin is still not considered "stable" (until 1.0.0 release version), so I think that now is the time to "experiment" with breaking-changes (and revert them if the feedback/usability gets bad). IMO there could be a separate branch for these kind of experiments for the brave 😉

What you propose could also work, by the way, with the exception of the ? command. Also, if z?* is used to list all the subcommands of z, how do you list recursively all sub-commands of z with long help/description? With z???*? or maybe z?**? and what's then the meaning of z??*?

@ret2libc
Copy link
Member Author

What you propose could also work, by the way, with the exception of the ? command.

Ignore the ? command for now. That command is "wrong", it needs to be changed no matter what because it makes everything inconsistent. We will deal with it soon enough.

Also, if z?* is used to list all the subcommands of z, how do you list recursively all sub-commands of z with long help/description?

I think we don't want to list recursively sub-commands and show long descriptions at the same time. Consider that long descriptions might contain multi-paragraph descriptions, examples, use-cases and what not. It could easily become a mess to read. What we mean by "recursively list sub-commands" is exactly what you get now with z?*. We might introduce at some point a command to search inside the commands (e.g. a way to search commands that have a word in the description, or a word in the examples or a word in a summary, etc.)

@ret2libc
Copy link
Member Author

IMO there could be a separate branch for these kind of experiments for the brave wink

At this point, I think we don't have that many people testing the dev branch, adding another branch would just mean more headaches for everyone, probably for little benefit now.

@caribpa
Copy link
Contributor

caribpa commented Feb 22, 2021

I think we don't want to list recursively sub-commands and show long descriptions at the same time. Consider that long descriptions might contain multi-paragraph descriptions, examples, use-cases and what not. It could easily become a mess to read. What we mean by "recursively list sub-commands" is exactly what you get now with z?*. We might introduce at some point a command to search inside the commands (e.g. a way to search commands that have a word in the description, or a word in the examples or a word in a summary, etc.)

Well, I use the built-in grep (~) to filter the output of <cmd>?* (unless I don't even remember some keywords for the filtering), so I am not so sure if there will be such a big need for providing specialized search commands considering that adding regex capabilities to ~ is planned in #64.
Though it would be nice to have a context-smart search when filtering ?* with long description enabled to show the command where the filter matched (like grep -r shows the file and the line where the match happened), if this is what you are talking about.

@caribpa
Copy link
Contributor

caribpa commented Feb 22, 2021

At this point, I think we don't have that many people testing the dev branch, adding another branch would just mean more headaches for everyone, probably for little benefit now.

I use the dev branch 🙂, but I understand about the headaches.

@caribpa
Copy link
Contributor

caribpa commented Feb 22, 2021

@caribpa BTW if you want we have a Mattermost server where we discuss this and other stuff. https://rizin.re/community/ There's a special channel for "newshell" development to discuss in real time some random ideas/issues.

Thanks, I'll pass by later 👍

At the same time, have you considered moving (some of the conversations/ideas/FAQ requests) to the repo's discussions page? I'm suggesting this with the idea of increasing the visibility and possible engagement of the discussions as not everybody has a Mattermost account (and may not be interested in creating one just to check what the conversations there are about) 🙂

@ret2libc
Copy link
Member Author

@caribpa BTW if you want we have a Mattermost server where we discuss this and other stuff. https://rizin.re/community/ There's a special channel for "newshell" development to discuss in real time some random ideas/issues.

Thanks, I'll pass by later +1

Awesome! ;)

At the same time, have you considered moving (some of the conversations/ideas/FAQ requests) to the repo's discussions page? I'm suggesting this with the idea of increasing the visibility and possible engagement of the discussions as not everybody has a Mattermost account (and may not be interested in creating one just to check what the conversations there are about) slightly_smiling_face

Honestly, I haven't, but if you want to try using it, I'd be happy to move discussions there when it make sense.

@ret2libc
Copy link
Member Author

Maybe to avoid changing "drastically" the syntax we could have:

  • <cmd>? show all subcommands of <cmd>, if any. sub-modes count as sub-commands, because for the user they are essentially just sub-commands, after all.

I realized this is not alright, because z, for example, is:

  1. the name of the group z, which includes a lot of subcommands like zb, zc, etc.
  2. the name of the command that includes multiple sub-modes (z, zj, z*, zk)
  3. the name of the specific command that list zignatures in standard format (z)

So using <cmd>? to list sub-commands and sub-modes is not ok, because you could have no way to understand whether you are referencing 1) or 2) (essentially, if you do z?, what would you expect to see? The list of sub-commands like zb, zc, etc. or the list of sub-modes zj, zk, etc.??)

One solution could be to just consider sub-modes as some additional detail of a single command, so they would not be listed anymore as special sub-commands, but just as a single command. In particular, the sub-modes of z could be listed when you look at the short/long help of z. By doing this, z? has only one meaning: list the subcommands of z.

  • <cmd>?? show a short description of <cmd>

z?? would return a short help for the command z, which might show the possibility of having the output in different formats. For example:

Usage: z[j*qk]   # Show zignatures
  • <cmd>??? show a long description of <cmd>

z??? would return a long help for the command z. For example:

Usage: z[j*qk]   # Show zignatures

| z # Show zignatures
| zj # Show zignatures (in JSON mode)
| z* # Show zignatures (in Rizin mode)
| zq # Show zignatures (in quiet mode)

Prints the list of zignatures currently registered bla bla bla.
  • <cmd>?* recursively show all sub-commands of <cmd>

This has the advantage of remaining "in line" with the existing syntax at the cost of having to do ?? just to get a short description of a command. On the other hand, it allows us to be consistent no matter what. If you want a (short) description you use ??, no matter where in the commands-tree the command is.

@caribpa
Copy link
Contributor

caribpa commented Feb 26, 2021

So:

> z?
Usage: z[?]   # Zignatures management
| z[j*qk]        # Show zignatures
| z.[*]          # Find matching zignatures
| zb[r]          # Search for best match
| z- <zigname|*> # Delete zignature
| za[fF]         # Add zignature
| zg             # Generate zignatures (alias for zaF)
| zo[sz]         # Manage zignature files
| zf<ds>         # Manage FLIRT signatures
| z/[*f]         # Search zignatures
| zc[n]          # Compare zignatures in current zignspace with another one
| zs[j*-+r]      # Manage zignspaces
| zi[j*qi]       # Show zignatures matching information
> z??
Usage: z[j*qk]   # Show zignatures
> z???
Usage: z[j*qk]   # Show zignatures
| z # Show zignatures
| zj # Show zignatures (in JSON mode)
| z* # Show zignatures (in Rizin mode)
| zq # Show zignatures (in quiet mode)

Right?

So it is basically the same it is now but z??? shows the long help.

@caribpa
Copy link
Contributor

caribpa commented Feb 26, 2021

Why not making z?? behave like the proposed z??? because, after all, I don't think people will normally list the short help for a single command when it appears anyways when doing z?

@ret2libc
Copy link
Member Author

Right?

So it is basically the same it is now but z??? shows the long help.

That's right.

Why not making z?? behave like the proposed z??? because, after all, I don't think people will normally list the short help for a single command when it appears anyways when doing z?

This is a good point... One might say that sometimes you just want to know the arguments you have to pass to a command and you don't want your whole screen to be cleared by a lot of help text...

@caribpa
Copy link
Contributor

caribpa commented Feb 26, 2021

Well, you could still do: z? ~:1 😂

@caribpa
Copy link
Contributor

caribpa commented Feb 26, 2021

Honestly, I also get mildly annoyed by the pollution caused by the output of z?, etc, so why don't we show it in a "smart-pager" by default?

This "smart-pager" gets opened in another buffer, like the HUD input mode (_) in visual/panels mode, allowing searching with /, etc like the ~.. pager, then, when pressing q (or other exit key), it returns to your previous, unpolluted, prompt.

Example:

> xc 32 @r:SP
# Other commands and outputs
> z?
# Opens a new buffer with only the following content:
Usage: z[?]   # Zignatures management
| z[j*qk]        # Show zignatures
| z.[*]          # Find matching zignatures
| zb[r]          # Search for best match
| z- <zigname|*> # Delete zignature
| za[fF]         # Add zignature
| zg             # Generate zignatures (alias for zaF)
| zo[sz]         # Manage zignature files
| zf<ds>         # Manage FLIRT signatures
| z/[*f]         # Search zignatures
| zc[n]          # Compare zignatures in current zignspace with another one
| zs[j*-+r]      # Manage zignspaces
| zi[j*qi]       # Show zignatures matching information

*Presses q*

# Goes back to your beautiful prompt now showing:
> xc 32 @r:SP
# Other commands and outputs
> z?
> *cursor here*

And I said "smart-pager" because it behaves like in of these two when filtering it:

  • either z? ~Search opens the result of the filter in another buffer pager-style
  • or z? ~Search shows the result in the current buffer (where the output of all the other commands is)

@caribpa
Copy link
Contributor

caribpa commented Feb 26, 2021

Sure thing, this change comes with an e variable to disable this behavior for old-schoolers/scholars.

@ret2libc
Copy link
Member Author

ret2libc commented Mar 1, 2021

Honestly, I also get mildly annoyed by the pollution caused by the output of z?, etc, so why don't we show it in a "smart-pager" by default?

This could have the disadvantage of not being able to see the command syntax while typing it. Sometimes you do z? to see the arguments accepted by a command and then you can still reference it while typing the command, but if the help just disappears, it might be annoying.

However I do see value in both cases.

@ret2libc ret2libc modified the milestones: 0.2.0, 0.3.0 Mar 1, 2021
@caribpa
Copy link
Contributor

caribpa commented Mar 1, 2021

What could be done (in a really far future) is to make an interactive help-buffer with a cursor that pastes in the prompt the selected command, and allows traversing in the sub-command/group in tree-like fashion. For example:

$ rizin --
> z?
*a help-buffer opens only showing the following*

  Usage: z[?]   # Zignatures management
> | z[j*qk]        # Show zignatures
  | z.[*]          # Find matching zignatures
  | zb[r]          # Search for best match
  | z- <zigname|*> # Delete zignature
  | za[fF]         # Add zignature
  | zg             # Generate zignatures (alias for zaF)
  | zo[sz]         # Manage zignature files
  | zf<ds>         # Manage FLIRT signatures
  | z/[*f]         # Search zignatures
  | zc[n]          # Compare zignatures in current zignspace with another one
  | zs[j*-+r]      # Manage zignspaces
  | zi[j*qi]       # Show zignatures matching information

*Note that the > denotes the cursor position*

  Usage: z[?]   # Zignatures management
  | z[j*qk]        # Show zignatures
  | z.[*]          # Find matching zignatures
  | zb[r]          # Search for best match
  | z- <zigname|*> # Delete zignature
> | za[fF]         # Add zignature
  | zg             # Generate zignatures (alias for zaF)
  | zo[sz]         # Manage zignature files
  | zf<ds>         # Manage FLIRT signatures
  | z/[*f]         # Search zignatures
  | zc[n]          # Compare zignatures in current zignspace with another one
  | zs[j*-+r]      # Manage zignspaces
  | zi[j*qi]       # Show zignatures matching info

*Presses TAB to show the sub-commands*

  Usage: z[?]   # Zignatures management
  | z[j*qk]        # Show zignatures
  | z.[*]          # Find matching zignatures
  | zb[r]          # Search for best match
  | z- <zigname|*> # Delete zignature
> \ za[fF]         # Add zignature
    | za <zigname> <type> <param0> [<param1> ...] # Add zignature
    | zaf [<fcnname> [<zigname>]] # Create zignature for function
    - zaF                     # Generate zignatures for all functions
  | zg             # Generate zignatures (alias for zaF)
  | zo[sz]         # Manage zignature files
  | zf<ds>         # Manage FLIRT signatures
  | z/[*f]         # Search zignatures
  | zc[n]          # Compare zignatures in current zignspace with another one
  | zs[j*-+r]      # Manage zignspaces
  | zi[j*qi]       # Show zignatures matching info

*Also allowing to move the cursor to the sub-commands*

  Usage: z[?]   # Zignatures management
  | z[j*qk]        # Show zignatures
  | z.[*]          # Find matching zignatures
  | zb[r]          # Search for best match
  | z- <zigname|*> # Delete zignature
  \ za[fF]         # Add zignature
    | za <zigname> <type> <param0> [<param1> ...] # Add zignature
>   | zaf [<fcnname> [<zigname>]] # Create zignature for function
    - zaF                     # Generate zignatures for all functions
  | zg             # Generate zignatures (alias for zaF)
  | zo[sz]         # Manage zignature files
  | zf<ds>         # Manage FLIRT signatures
  | z/[*f]         # Search zignatures
  | zc[n]          # Compare zignatures in current zignspace with another one
  | zs[j*-+r]      # Manage zignspaces
  | zi[j*qi]       # Show zignatures matching info

*Pressing Enter closes the help-buffer and pastes the selected command into the prompt*

$ rizin --
> z?
> zaf

@caribpa
Copy link
Contributor

caribpa commented Mar 1, 2021

Well, or it could end overriding the current z? call for cleanliness:

$ rizin --
> zaf

instead of:

$ rizin --
> z?
> zaf

@wargio
Copy link
Member

wargio commented Mar 2, 2021

that feature is cool, but i do not think is needed right now. i think is better to just use <combo>?*~<keyword>

@wargio
Copy link
Member

wargio commented Mar 2, 2021

Why not making z?? behave like the proposed z??? because, after all, I don't think people will normally list the short help for a single command when it appears anyways when doing z?

I'm more than ok with this. makes more sense.

@ret2libc
Copy link
Member Author

ret2libc commented Jul 5, 2021

I don't think I will be able to do this for 0.3.0. Going to move it to 0.4.0.

@ret2libc ret2libc modified the milestones: 0.3.0, 0.4.0 Jul 5, 2021
@wargio
Copy link
Member

wargio commented Jul 5, 2021

it is fine. so many things to be done and not much time to work on them

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

No branches or pull requests

4 participants