-
Notifications
You must be signed in to change notification settings - Fork 7
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
Usage text suggestions #19
Comments
Thanks for the great input! Working on these changes now. |
One problem regarding having All flags have defaults, so no What about having Note that eventually I want to see if I can do something about how parsed flags are returned. I'd love to be able to return a proper struct containing the values rather than using a hash/map. By that time I could also potentially tackle the issue of allowing a value to be marked as required. Haven't yet figured out how to deal with using structs, though. Might have to resort to the use of macros. |
Perhaps unnecessary to render |
Well, Using In all command line applications that I see, the usage text clearly shows if the flag has an argument or not - since it helps to clarify the purpose. imagine this flag:
and compare it to how Commander displays it:
In the first case, the user does not need to read the description to understand how it works. In the second case, they must. Perhaps this can be solved easily, like how the
Will that be easier / acceptable? |
There's no way to infer that you want a directory ( Perhaps it'd be better to allow you to specify cmd.flags.add do |flag|
flag.name = "cache"
flag.short = "-c DIR"
flag.long = "--cache DIR"
flag.default = ".cache"
flag.description = "Directory to place cache files."
end |
Note that |
Alternatively, and much easier to implement and perhaps more understandable would be to allow you to specify a flag arg: cmd.flags.add do |flag|
flag.name = "cache"
flag.short = "-c"
flag.long = "--cache"
flag.arg = "DIR"
flag.default = ".cache"
flag.description = "Directory to place cache files."
end This way you don't repeat the same |
Yes. Both options are nice. In fact, the first option ( |
I opted for what you intuitively tried. It's more consistent with how you define a command, so to avoid inconsistencies we'll use the same notation style with flags. I ended up getting a simple implementation done for this regardless. I haven't taken care of text wrapping because there doesn't appear to be a good way to determine the terminal width in Crystal at this time from what I can see. Though we might want to still wrap using at least a fixed width. Thoughts on this? The individual commits: These commits address points 1, 2, 3 and 4. You can try it in your application by referring to the help branch. Like so iirc: dependencies:
commander:
github: mrrooijen/commander
branch: help You can specify the descriptive argument like so: flag.short = "-c DIR"
flag.long = "--cache" Or flag.short = "-c"
flag.long = "--cache DIR" Or flag.short = "-c DIR"
flag.long = "--cache DIR" All of the above are equivalent. |
Very nice. Just tested, and looks nice. As for text wrapping, there are a couple of points to consider: Newline between flag description and flagIn the command line frameworks I have built in Ruby (for example mister_bin) - I opted to always show the description of the subcommand or flag, indented and in a separate line than the flag. This alone makes most lines not wrap, since there is more space (here is an example) For example:
This particular change becomes particularly crucial, when you have long flag names, imagine this:
it does not leave you a lot of space for the description. Width detectionAs for determining the width of the terminal - in Ruby, I have developed a gem that I am using successfully in all my CLI apps. One of its functions is to determine terminal width. Wouldn't this code work almost as is in Crystal? def detect_terminal_size(default=[80,30])
if (ENV['COLUMNS'] =~ /^\d+$/) && (ENV['LINES'] =~ /^\d+$/)
result = [ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
elsif (RUBY_PLATFORM =~ /java/ || (!STDIN.tty? && ENV['TERM'])) && command_exist?('tput')
result = [`tput cols 2>&1`.to_i, `tput lines 2>&1`.to_i]
elsif STDIN.tty? && command_exist?('stty')
result = `stty size 2>&1`.scan(/\d+/).map { |s| s.to_i }.reverse
else
result = default
end
result = default unless result[0].is_a? Integer and result[1].is_a? Integer and result[0] > 0 and result[1] > 0
result
end Word wrappingThe same Colsole gem also has a word wrapping function I am using - perhaps it can be ported to Crystal as well? def word_wrap(text, length=nil)
length ||= terminal_width
lead = text[/^\s*/]
text.strip!
length -= lead.length
text.split("\n").collect! do |line|
if line.length > length
line.gsub!(/([^\s]{#{length}})([^\s$])/, "\\1 \\2")
line.gsub(/(.{1,#{length}})(\s+|$)/, "#{lead}\\1\n").rstrip
else
"#{lead}#{line}"
end
end * "\n"
end Is any of this helpful? |
Nice. I wasn't aware of Putting descriptions on the next line also seems like a viable approach. Would that apply to both (sub)commands and flags, or just flags? |
In regards to width - yes, best effort is definitely the way to go. As you can see in my code, if everything fails, I am considering 80 to be the width. As for new line in subcommands - dealers choice. In some of my implementations I did it like this, and in others, in the same line. I guess the important thing is that the usage looks as friendly as possible - usage for humans. |
Looking at |
By the way, another couple of things I am missing in all of Crystal's CLI frameworks that I have tested, and another reason I prefer to have all descriptions in a new line are these:
The below is an example output of a subcommand in one of my gems (which uses my mister_bin gem). Points of interest:
The DSL for the below output looks like this
|
I've opened 3 new issues where these additions can be discussed. If you have any specific DSL/Output ideas for Commander for these specific features, submit them there. |
Good idea. This topic has become long :) |
Hi,
I am playing with this nice
gemshard, and noticed some things that I think could benefit from a slight change.Consider this output:
Suggestions:
#
symbol that separates the flag/command and its description. Having 2 or 3 spaces between the flag and the description will be cleaner and still clear.default: 8080.
instead ofdefault: '8080'.
-p, --port <port>
would look like this
The text was updated successfully, but these errors were encountered: