diff --git a/vlib/cli/help.v b/vlib/cli/help.v index d1ec96e110..3e82fa8512 100644 --- a/vlib/cli/help.v +++ b/vlib/cli/help.v @@ -1,5 +1,10 @@ module cli +import ( + term + strings +) + const ( BASE_INDENT = 2 ABBREV_INDENT = 5 @@ -55,7 +60,8 @@ fn help_func(help_cmd Command) { base_indent := ' '.repeat(BASE_INDENT) description_indent := ' '.repeat(max(DESCRIPTION_INDENT-flag_name.len, 1)) - help += '${base_indent}${flag_name}${description_indent}${flag.description}${required}\n' + help += '${base_indent}${flag_name}${description_indent}' + + pretty_description(flag.description + required) + '\n' } help += '\n' } @@ -65,7 +71,8 @@ fn help_func(help_cmd Command) { base_indent := ' '.repeat(BASE_INDENT) description_indent := ' '.repeat(max(DESCRIPTION_INDENT-command.name.len, 1)) - help += '${base_indent}${command.name}${description_indent}${command.description}\n' + help += '${base_indent}${command.name}${description_indent}' + + pretty_description(command.description) + '\n' } help += '\n' } @@ -73,6 +80,36 @@ fn help_func(help_cmd Command) { print(help) } +// pretty_description resizes description text depending on terminal width. +// Essentially, smart wrap-around +fn pretty_description(s string) string { + width, _ := term.get_terminal_size() + // Don't prettify if the terminal is that small, it won't be pretty anyway. + if s.len + DESCRIPTION_INDENT < width || DESCRIPTION_INDENT > width { + return s + } + indent := ' '.repeat(DESCRIPTION_INDENT + 1) + chars_per_line := width - DESCRIPTION_INDENT + // Give us enough room, better a little bigger than smaller + mut acc := strings.new_builder(((s.len / chars_per_line) + 1) * (width + 1)) + + mut i := chars_per_line - 1 + mut j := 0 + for ; i < s.len ; i += chars_per_line - 1 { + for s.str[i] != ` ` { i-- } + // indent was already done the first iteration + if j != 0 { acc.write(indent) } + acc.writeln(s[j..i]) + j = i + } + // We need this even though it should never happen + if j != 0 { + acc.write(indent) + } + acc.write(s[j..]) + return acc.str() +} + fn max(a, b int) int { return if a > b {a} else {b} }