fish adds builtin argument parsing in the 2.7 beta
fish 2.7b1 gives functions a parser with the same option behavior as builtin commands. It also adds a directory-history menu, using existing session navigation state.
A small shell function can acquire a surprisingly large argument parser. Supporting long options and required values requires more than removing the first element of an argument list. An external parser can help, but GNU and BSD implementations of getopt differ. fish 2.7b1 adds a builtin parser so functions can use the same option behavior as fish's own commands.
The October 31 beta notes introduce argparse and its fish_opt helper. They also add cdh, a menu for recently visited directories. Both additions move common interactive-function work into maintained shell interfaces.
I value fish's scripting language when a short helper stays understandable as its interface grows. Argument parsing is a good place for a builtin because each function should not need a separate implementation of option grammar.
Specifications and arguments have separate positions
The beta's argparse reference defines two argument groups separated by a literal --. The first group describes recognized options and parser settings. After the separator comes the command line to parse.
The separator is required even when the second group is empty. It lets the builtin distinguish option specifications from the inputs those specifications describe. A parser invocation without that boundary is an error.
function greet
argparse --name=greet 'n/name=' -- $argv
or return
if set -q _flag_name
printf 'Hello %s\n' "$_flag_name"
end
end
The specification gives the option a short spelling -n and a long spelling --name. The equals suffix requires a value. After successful parsing, the function can inspect _flag_name instead of manually searching the original argument list.
The --name=greet parser option is separate from the function's --name option. It supplies the command name for diagnostics. Its position before the specifications and separator gives it a different role from arguments supplied by the caller.
Parsed flags become local variables
For recognized options, argparse sets local variables whose names begin with _flag_. A specification with both short and long forms supplies corresponding names. If an option is absent, its flag variables are not set.
The parser also updates local argv with the positional arguments left after option handling. A function can therefore validate options first and then process its remaining operands without stripping recognized flags again.
On invalid input, the reference says argparse emits a diagnostic and exits nonzero. The or return line in the example stops the helper before it uses incomplete parse results. That is control flow attached to the parser's actual status.
A required value is not the same as a required option. The equals modifier says a supplied option must have a value. It does not require the caller to supply that option on every invocation. Checking whether the flag variable exists remains meaningful.
The parser expresses more than spelling
The builtin supports minimum and maximum positional-argument counts. It also supports sets of mutually exclusive options. These express interface rules that otherwise need repeated conditional code after a manual scan.
By default, parsing reorders arguments so non-options follow options. The --stop-nonopt setting stops scanning at the first non-option instead. The reference identifies subcommand handling as a use for that behavior, because a subcommand can own the rest of the arguments.
Specifications distinguish optional values and repeated values as well. Those distinctions belong in the option contract, not in an assumption that every flag consumes exactly one following argument. The new interface makes the relevant policy visible beside each option name.
I prefer that explicit grammar because it lets the function's body concentrate on its operation. A reader can inspect the specifications to understand accepted syntax before following the implementation.
Specifications can also attach validation code to an option value. The reference supplies a supplied integer-validation helper with optional minimum and maximum bounds. A value can therefore satisfy the option's syntactic requirement and still fail its semantic check. That separates having an argument from having an argument suitable for the operation.
Directory history becomes a selection menu
The cdh implementation in the beta combines dirprev and dirnext, removes duplicate directories and presents numbered and lettered choices. A selection calls cd with the chosen path.
That is a menu over session navigation history, not a recursive filesystem search. The function reports when there are no previous directories to select. Its candidate list comes from places the session has already visited.
The implementation reverses the history to retain the most recent occurrence when removing duplicates. Repeated visits therefore do not create repeated menu choices for the same directory. Display order and duplicate handling are deliberate parts of making the menu usable.
These additions support different levels of interaction. cdh supplies a ready-made navigation command. argparse supplies a component for authors writing other commands. The beta gives those authors an option parser integrated with fish's own argument conventions, while keeping the function's remaining operands available through argv.