Externs
Calling external commands is a fundamental part of using rsh as a shell (and often using rsh as a language). There's a problem, though: rsh can't help with finding errors in the call, completions, or syntax highlighting with external commands.
This is where extern
comes in. The
extern
keyword allows you to write a full signature
for the command that lives outside of rsh 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:
export extern "git push" [
remote?: string@"rsh-complete git remotes", # the name of the remote
refspec?: string@"rsh-complete git branches" # the branch / refspec
--verbose(-v) # be more verbose
--quiet(-q) # be more quiet
--repo: string # repository
--all # push all refs
--mirror # mirror all refs
--delete(-d) # delete refs
--tags # push tags (can't be used with --all or --mirror)
--dry-run(-n) # dry run
--porcelain # machine-readable output
--force(-f) # force updates
--force-with-lease: string # require old value of ref to be at this value
--recurse-submodules: string # control recursive pushing of submodules
--thin # use thin pack
--receive-pack: string # receive pack program
--exec: string # receive pack program
--set-upstream(-u) # set upstream for git pull/status
--progress # force progress reporting
--prune # prune locally removed refs
--no-verify # bypass pre-push hook
--follow-tags # push missing but relevant tags
--signed: string # GPG sign the push
--atomic # request atomic transaction on remote side
--push-option(-o): string # option to transmit
--ipv4(-4) # use IPv4 addresses only
--ipv6(-6) # use IPv6 addresses only
]
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.
Note
A rsh comment that continues on the same line for argument
documentation purposes requires a space before the
#
pound sign.
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 rsh about how to complete values for that flag
or position. For example, setting a shape to
path
allows rsh 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.
Format specifiers
Positional parameters can be made optional with a
?
(as seen above) the remaining parameters can be
matched with ...
before the parameter name, which
will return a list of arguments.
export extern "git add" [
...pathspecs: glob
# …
]
Limitations
There are a few limitations to the current
extern
syntax. In rsh, 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 rsh, the =
is a convenient optional syntax and
there's currently no way to require its use.