make std help more user friendly (#14347)

# Description
Fixes:  #13159

After the change, `std help` will no-longer print out "double error"
messages.

Actually I think it's tricky to make it right. To make `help <cmd>`
keeps paging feature from fallback `man` command. I have to split
`commands` into `scope-commands` and `external-commands`.

If we don't split it, simply call `let commands = (try { commands
$target_item --find $find })` in `help main` will cause us to lost
paging feature, which is not we want.

A comment from original issue:

> If there are no objections, I'd like to remove the man page fallback
code from std help for the moment. While it's probably fixable, it's
also platform specific and requires testing on all platforms. It also
seems like a low-value add here.

Actually I think it's a beautiful feature of `std help`, so I want to
keep it here.

# User-Facing Changes
### Before
```nushell
> help commands asdfadsf
Help pages from external command asdfadsf:
No manual entry for asdfadsf
Error:   × std::help::command_not_found
   ╭─[entry #11:1:15]
 1 │ help commands asdfadsf
   ·               ────┬───
   ·                   ╰── command not found
   ╰────
```

### After
```nushell
> help commands asdfasdf
Help pages from external command asdfasdf:
No manual entry for asdfasdf
```

# Tests + Formatting
Actually it's a little hard to add test because it required user input
(especially for fallback `man` command)
This commit is contained in:
Wind 2024-11-27 09:29:25 +08:00 committed by GitHub
parent 367fb9b504
commit 186c08467f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -684,8 +684,7 @@ def build-command-page [command: record] {
] | flatten | str join "\n" ] | flatten | str join "\n"
} }
# Show help on commands. def scope-commands [
export def commands [
...command: string@"nu-complete list-commands" # the name of command to get help on ...command: string@"nu-complete list-commands" # the name of command to get help on
--find (-f): string # string to find in command names and description --find (-f): string # string to find in command names and description
] { ] {
@ -699,20 +698,35 @@ export def commands [
let found_command = ($commands | where name == $target_command) let found_command = ($commands | where name == $target_command)
if ($found_command | is-empty) { if ($found_command | is-empty) {
try { command-not-found-error (metadata $command | get span)
print $"(ansi default_italic)Help pages from external command ($target_command | pretty-cmd):(ansi reset)" } else {
^($env.NU_HELPER? | default "man") $target_command build-command-page ($found_command | get 0)
} catch {
command-not-found-error (metadata $command | get span)
}
} }
build-command-page ($found_command | get 0)
} else { } else {
$commands | select name category description signatures search_terms $commands | select name category description signatures search_terms
} }
} }
def external-commands [
...command: string@"nu-complete list-commands",
] {
let target_command = $command | str join " "
print $"(ansi default_italic)Help pages from external command ($target_command | pretty-cmd):(ansi reset)"
^($env.NU_HELPER? | default "man") $target_command
}
# Show help on commands.
export def commands [
...command: string@"nu-complete list-commands" # the name of command to get help on
--find (-f): string # string to find in command names and description
] {
try {
scope-commands ...$command --find=$find
} catch {
external-commands ...$command
}
}
def pretty-cmd [] { def pretty-cmd [] {
let cmd = $in let cmd = $in
$"(ansi default_dimmed)(ansi default_italic)($cmd)(ansi reset)" $"(ansi default_dimmed)(ansi default_italic)($cmd)(ansi reset)"
@ -763,7 +777,7 @@ You can also learn more at (ansi default_italic)(ansi light_cyan_underline)https
let target_item = ($item | str join " ") let target_item = ($item | str join " ")
let commands = (try { commands $target_item --find $find }) let commands = (try { scope-commands $target_item --find $find })
if not ($commands | is-empty) { return $commands } if not ($commands | is-empty) { return $commands }
let aliases = (try { aliases $target_item --find $find }) let aliases = (try { aliases $target_item --find $find })
@ -776,13 +790,7 @@ You can also learn more at (ansi default_italic)(ansi light_cyan_underline)https
print -e $"No help results found mentioning: ($find)" print -e $"No help results found mentioning: ($find)"
return [] return []
} }
# use external tool (e.g: `man`) to search help for $target_item
let span = (metadata $item | get span) # the stdout and stderr of external tool will follow `main` call.
error make { external-commands $target_item
msg: ("std::help::item_not_found" | error-fmt)
label: {
text: "item not found"
span: $span
}
}
} }