Externs

Calling external commands is a fundamental part of using Nushell as a shell (and often using Nushell as a language). There’s a problem, though, commands outside of Nushell means that Nushell can’t help with finding errors in the call, or completions, or syntax highlighting.

This is where extern comes in. The extern keyword allows you to write a full signature for the command that lives outside of Nushell so that you get all the benefits above. If you take a look at the default config, you’ll notice that there are a few extern calls in there. Here’s one of them:

  1. export extern "git push" [
  2. remote?: string@"nu-complete git remotes", # the name of the remote
  3. refspec?: string@"nu-complete git branches"# the branch / refspec
  4. --verbose(-v) # be more verbose
  5. --quiet(-q) # be more quiet
  6. --repo: string # repository
  7. --all # push all refs
  8. --mirror # mirror all refs
  9. --delete(-d) # delete refs
  10. --tags # push tags (can't be used with --all or --mirror)
  11. --dry-run(-n) # dry run
  12. --porcelain # machine-readable output
  13. --force(-f) # force updates
  14. --force-with-lease: string # require old value of ref to be at this value
  15. --recurse-submodules: string # control recursive pushing of submodules
  16. --thin # use thin pack
  17. --receive-pack: string # receive pack program
  18. --exec: string # receive pack program
  19. --set-upstream(-u) # set upstream for git pull/status
  20. --progress # force progress reporting
  21. --prune # prune locally removed refs
  22. --no-verify # bypass pre-push hook
  23. --follow-tags # push missing but relevant tags
  24. --signed: string # GPG sign the push
  25. --atomic # request atomic transaction on remote side
  26. --push-option(-o): string # option to transmit
  27. --ipv4(-4) # use IPv4 addresses only
  28. --ipv6(-6) # use IPv6 addresses only
  29. ]

You’ll notice this gives you all the same descriptive syntax that internal commands do, letting you describe flags, short flags, positional parameters, types, and more.

Types and custom completions

In the above example, you’ll notice some types are followed by @ followed by the name of a command. We talk more about custom completions in their own section.

Both the type (or shape) of the argument and the custom completion tell Nushell about how to complete values for that flag or position. For example, setting a shape to path allows Nushell to complete the value to a filepath for you. Using the @ with a custom completion overrides this default behavior, letting the custom completion give you full completion list.

Limitations

There are a few limitations to the current extern syntax. In Nushell, flags and positional arguments are very flexible: flags can precede positional arguments, flags can be mixed into positional arguments, and flags can follow positional arguments. Many external commands are not this flexible. There is not yet a way to require a particular ordering of flags and positional arguments to the style required by the external.

The second limitation is that some externals require flags to be passed using = to separate the flag and the value. In Nushell, the = is a convenient optional syntax and there’s currently no way to require its use.