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"
}
# Show help on commands.
export def commands [
def scope-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
] {
@ -699,20 +698,35 @@ export def commands [
let found_command = ($commands | where name == $target_command)
if ($found_command | is-empty) {
try {
print $"(ansi default_italic)Help pages from external command ($target_command | pretty-cmd):(ansi reset)"
^($env.NU_HELPER? | default "man") $target_command
} catch {
command-not-found-error (metadata $command | get span)
}
command-not-found-error (metadata $command | get span)
} else {
build-command-page ($found_command | get 0)
}
build-command-page ($found_command | get 0)
} else {
$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 [] {
let cmd = $in
$"(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 commands = (try { commands $target_item --find $find })
let commands = (try { scope-commands $target_item --find $find })
if not ($commands | is-empty) { return $commands }
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)"
return []
}
let span = (metadata $item | get span)
error make {
msg: ("std::help::item_not_found" | error-fmt)
label: {
text: "item not found"
span: $span
}
}
# use external tool (e.g: `man`) to search help for $target_item
# the stdout and stderr of external tool will follow `main` call.
external-commands $target_item
}