docopt

Version, currently 0.3.03 versions

github.com/ralsina/docopt.cr

docopt for crystal-lang

1 stars
11 dependents
License: MIT

Nothing has been indexed for 0.3.0 yet. The tag is recorded, its shard.yml has not been read, so the manifest and dependency list below are empty because they are unknown rather than because they are absent.

Installation

# Add this to your shard.yml
dependencies:
  docopt:
    github: ralsina/docopt.cr
    version: ~> 0.3.0

Then run:

shards install

shard.yml

No shard.yml has been indexed for 0.3.0. You can read it on the repository.

Dependencies

Unknown: the shard.yml for this version has not been read yet.

README

This README is the one indexed from the repository at its latest ref, not from the tag for this version.

docopt.cr

docopt for crystal-lang

This is a fork of the original docopt.cr by chenkovsky with a few bugfixes.

It has a couple of bugfixes and I am now starting to add new features:

  • bash completion generation
  • fish completion generation
  • zsh completion generation
  • Custom hooks for smarter completion

Installation

Add this to your application's shard.yml:

dependencies:
  docopt:
    github: ralsina/docopt.cr

Usage

require "docopt"
describe "Docopt" do
  # TODO: Write tests

  it "works" do
    doc = <<-DOC
    Naval Fate.

    Usage:
      naval_fate ship new <name>...
      naval_fate ship <name> move <x> <y> [--speed=<kn>]
      naval_fate ship shoot <x> <y>
      naval_fate mine (set|remove) <x> <y> [--moored|--drifting]
      naval_fate -h | --help
      naval_fate --version

    Options:
      -h --help     Show this screen.
      --version     Show version.
      --speed=<kn>  Speed in knots [default: 10].
      --moored      Moored (anchored) mine.
      --drifting    Drifting mine.
    DOC
    std = {"ship" => true, "new" => false, "<name>" => ["A"], "move" => true, "<x>" => "a", "<y>" => "b", "--speed" => "3", "shoot" => false, "mine" => false, "set" => false, "remove" => false, "--moored" => nil, "--drifting" => nil, "-h" => nil, "--help" => false, "--version" => nil}
    ans = Docopt.docopt(doc, argv = ["ship", "A", "move", "a", "b", "--speed=3"])
    ans["<name>"].should eq(std["<name>"])
  end
  it "one or more" do
    doc = <<-DOC
    test
    Usage:
        naval [--files=files...]
    DOC
    ans = Docopt.docopt(doc, argv = ["--files=a.txt", "--files=b.txt"])
    farr = ans["--files"] as Array(String)
    "a.txt".should eq(farr[0])
    "b.txt".should eq(farr[1])
  end
end

Shell Completion Generation

docopt.cr can generate shell completion scripts for bash, fish, and zsh so that when you TAB while writing a command it will show you the possible options.

Bash Completion

The code to create a bash completion looks like this for the classic naval_fate example:

    bash_completion = Docopt.bash_completion("naval_fate", doc)

To make this available to the user you could have something like a naval_fate --completion-bash in your usage instructions and either tell the user to put this in their .bashrc:

    naval_fate --completion-bash >> ~/.bashrc

Or write it to a file and put it in /etc/bash_completion.d/:

    naval_fate --completion-bash > /etc/bash_completion.d/naval_fate

Fish Completion

For fish shell completion:

    fish_completion = Docopt.fish_completion("naval_fate", doc)

Users can install fish completions by adding to their config:

    naval_fate --completion-fish > ~/.config/fish/completions/naval_fate.fish

ZSH Completion

For zsh shell completion:

    zsh_completion = Docopt.zsh_completion("naval_fate", doc)

Users can install zsh completions by adding:

    naval_fate --completion-zsh > ~/.local/share/zsh/site-functions/_naval_fate

Or system-wide:

    naval_fate --completion-zsh > /usr/share/zsh/site-functions/_naval_fate

Custom Completions

Usually the suggestions provided by the completions are limited to flags options and files, which may not be the right thing.

Suppose you want the naval_fate ship new command to be completed with just the names from a list of famous ships. You can do that using the custom_completions argument:

    bash_completion = Docopt.bash_completion(
      "naval_fate", 
      doc, 
      {"naval_fate_ship_new" => %("Titanic 'Queen Mary' 'USS Enterprise')}
    )

The key is the name of the command and any subcommands, joined by _ (underscore). In this case, the command is naval_fate ship new.

The completion should be provided as a list of space-separated strings, and if any of them contain spaces, they should be single-quoted.

It can be made more dynamic by using instead the output of a command. For example, if the command naval_fate ship list existed, we could do this using bash ability to run commands inside other commands:

    bash_completion = Docopt.bash_completion(
      "naval_fate", 
      doc, 
      {"naval_fate_ship_new" => "$(naval_fate ship list)"}
    )

And the completion for naval_fate ship new would be the output of naval_fate ship list.

Custom Completions for All Shells

The custom completion system works consistently across all three shells:

    # Define custom completions once
    completions = {
      "naval_fate_ship_new" => "$(naval_fate ship list)",
      "naval_fate_mine_set" => %("anchored drifting")
    }

    # Use with any shell
    bash_completion = Docopt.bash_completion("naval_fate", doc, completions)
    fish_completion = Docopt.fish_completion("naval_fate", doc, completions)
    zsh_completion = Docopt.zsh_completion("naval_fate", doc, completions)

This ensures consistent completion behavior regardless of which shell the user prefers.

Examples

See the examples/ directory for a complete working example:

Naval Fate CLI

The naval_fate application demonstrates real-world usage:

# Build and run the example
cd examples
crystal build naval_fate.cr -o naval_fate
./naval_fate --help

# Generate completions
./naval_fate --completion-bash > ~/.bash_completion.d/naval_fate
./naval_fate --completion-fish > ~/.config/fish/completions/naval_fate.fish
./naval_fate --completion-zsh > ~/.local/share/zsh/site-functions/_naval_fate

Features demonstrated:

  • Multi-subcommand CLI structure
  • Custom completions with dynamic ship names
  • Real-time fleet management
  • Shell-appropriate completion behaviors

Run examples/test_completion.sh to see a complete demonstration of the completion functionality.

Development

Building

crystal build src/docopt.cr
crystal spec  # Run tests
ameba --fix  # Run linter

Contributing

  1. Fork it ( https://github.com/ralsina/docopt.cr/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

  • chenkovsky chenkovsky.chen - creator, maintainer
  • ralsina Roberto Alsina - fork maintainer