Skip to content
ridiculousfish edited this page Jun 13, 2014 · 2 revisions

https://github.com/fish-shell/fish-shell/issues/478 discusses "command signatures," which would be a way to unify option parsing, syntax highlighting, completions, and autosuggestions into a single piece of metadata that could be provided for a function or external command. docopt was proposed as a syntax. This page gives samples of what it might look like to write a docopt signature for common commands.

The samples here pre-suppose that option parsing is a separate syntax, i.e. that the "signature" command kicks fish into a special parsing mode until the end of the signature. This is definitely not a settled matter.

signature cd

  # Code is divided into usage patterns. Each line represents a separate way you might invoke the command.
  # Values in brackets <> are positional arguments. These automatically show up as variables in the function.
  # For example, here the function 'cd' would see a variable $DIR (but only in the first use case)
  Usage:
    cd <DIR>
    cd —-help | -h
    cd

  Options:
    —-help, -h: Display help and exit

  # "Arguments" section would be a fish extension to docopt that allow dynamically
  # determining valid arguments, akin to the —-arguments parameter to `complete`. The
  # key DIR matches the variable DIR in the usage pattern above, and can also match
  # variables specified in Options.
  # Unclear what the quoting rules are, but it's unlikely you'd want literals here.
  Arguments:
    DIR: __fish_valid_directories

end

signature ls

  Usage: 
    # '[options]' is a docopt 'builtin' shorthand for all of the options
    # specified below. PATH is in brackets to show it is a variable (not
    # a literal), and the ellipsis shows that the argument may be repeated.
    # If the argument is repeated, $PATH will be a list of all of the path
    # values, assuming ls is a function and not an external command.
    ls [options] <PATH>...

  Options:
    -a:  Show all files
    -R, --recursive:  Recursively list subdirectories
    -C:  List by columns
    -S:  Sort by size
    -c:  Show and sort by ctime
    -f:  Don't sort
    -g:  Long format without owner
    -k:  Set blocksize to 1kB
    -l:  Long format
    -m:  Comma separated format
    -t:  Sort by modification time
    -u:  Show access time
    -x:  List entries by lines
    -1:  List one file per line

  Arguments:
     PATH:  __fish_valid_paths

end

# Signatures may be defined dynamically
# Here we define a signature for each grep variant
for some_grep in grep egrep fgrep rgrep
  signature $some_grep

    Usage:
      # Sort of silly that we have to specify the command name for each usage pattern
      $some_grep [options] <PATTERN> <FILE>...
      $some_grep --help | -h

    Options:
      -A <NUM>, --after-context=<NUM>:  Print NUM lines of trailing context
      -a, --text:  Process binary file as text
      -B, --before-context:  Print NUM lines of leading context
      -C, --context:  Print NUM lines of context
      -b, --byte-offset:  Print byte offset of matches
      --binary-files:  Assume data type for binary files -x -a binary text
      --colour <COLOR_TYPE>, --color <COLOR_TYPE>: Mark up output with GREP_COLOR
      -c, --count:  Only print number of matches
      -D, --devices -x -a read skip:  Action for devices
      -d, --directories -x -a read skip recurse:  Action for directories
      -E, --extended-regexp:  Pattern is extended regexp
      -e <PATTERN>, --regexp=<PATTERN>:  Pattern used during the search of the input
      --exclude-from <EXCLUDE_FILE>:  Read pattern list from file. Skip files whose base name matches list.
      --exclude-dir <EXCLUDE_DIR>:  Exclude matching directories from recursive searches
      -F, --fixed-strings:  Pattern is a fixed string
      -f <PATTERN_FILE>, --file <PATTERN_FILE>:  Use patterns from a file
      -G, --basic-regexp:  Pattern is basic regex
      -H, --with-filename:  Print filename
      -h, --no-filename:  Suppress printing filename
      --help:  Display help and exit
      -I:  Skip binary files
      -i, --ignore-case:  Ignore case
      -L, --files-without-match:  Print first non-matching file
      -l, --files-with-match:  Print first matching file
      -m, --max-count:  Stop reading after NUM matches
      --mmap:  Use the mmap system call to read input
      -n, --line-number:  Print line number
      -o, --only-matching:  Show only matching part
      --label:  Rename stdin
      --line-buffered:  Use line buffering
      -P, --perl-regexp:  Pattern is a Perl regexp (PCRE) string
      -q, --quiet:  Do not write anything
      --silent:  Do not write anything
      -R, --recursive:  Read files under each directory, recursively
      -r:  Read files under each directory, recursively
      --include=<PATTERN>:  Search only files matching PATTERN
      --exclude=<PATTERN>:  Skip files matching PATTERN
      -s, --no-messages:  Suppress error messages
      -T, --initial-tab :  Ensure first character of actual line content lies on a tab stop
      -U, --binary:  Treat files as binary
      -u, --unix-byte-offsets:  Report Unix-style byte offsets
      -V, --version:  Display version and exit
      -v, --invert-match:  Invert the sense of matching
      -w, --word-regexp:  Only whole matching words
      -x, --line-regexp:  Only whole matching lines
      -y:  Obsolete synonym for -i
      -z, --null-data --description 'treat input as a set of lines each terminated by a zero byte'
      -Z, --null:  Output a zero byte after filename

    Arguments:
      # fish will provide special functions for common cases (file paths, etc).
      # We need a way to indicate that an argument is NOT a valid path
      # Leaving it blank will prevent fish from suggesting any arguments
      PATTERN: 
      COLOR_TYPE: echo never always auto
      PATTERN_FILE: __fish_valid_files
      EXCLUDE_DIR: __fish_default_args
      NUM: __fish_valid_numbers
  
  end 
end