{"id":13690968,"url":"https://github.com/f/completion","last_synced_at":"2025-03-21T07:30:45.856Z","repository":{"id":140370448,"uuid":"48688683","full_name":"f/completion","owner":"f","description":"Easy Command Line Completion for Crystal","archived":false,"fork":false,"pushed_at":"2017-03-03T21:01:29.000Z","size":12,"stargazers_count":70,"open_issues_count":3,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-17T22:26:12.052Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Crystal","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/f.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2015-12-28T11:07:40.000Z","updated_at":"2023-04-13T14:58:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"53ee31a1-05cd-4d29-a546-dd36814ae9f4","html_url":"https://github.com/f/completion","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f%2Fcompletion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f%2Fcompletion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f%2Fcompletion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f%2Fcompletion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/f","download_url":"https://codeload.github.com/f/completion/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244757258,"owners_count":20505362,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T17:00:37.785Z","updated_at":"2025-03-21T07:30:45.550Z","avatar_url":"https://github.com/f.png","language":"Crystal","funding_links":[],"categories":["Cli Builders"],"sub_categories":[],"readme":"# Easy Command Line Autocompletion Helper\n\nCompletion is a Shell Completion Helper built on Crystal. It allows you to have completion muscle for your CLI apps.\n\n## Installation\n\nAdd this to your application's `shard.yml`:\n\n```yaml\ndependencies:\n  completion:\n    github: f/completion\n```\n\n![Completion](http://i.imgur.com/UVh97ZO.gif)\n\n## Usage\n\n### 1 Minute Start\n\nFirst, create a file with simple autocompletion logic.\n```crystal\n# hello.cr\nrequire \"completion\"\n\ncompletion :where do |comp|\n  comp.on(:where) do\n    comp.reply [\"world\", \"mars\", \"pluton\"]\n  end\nend\n```\n\nBuild and try:\n\n```bash\ncrystal build hello.cr\neval \"$(./hello --completion --development)\"\n\n./hello\u003ctab\u003e\u003ctab\u003e\nworld   mars   pluton\n```\n\n\u003e **Note:** `--development` flag enables autocompletion for relative (`./hello`) completion.\n\u003e While developing your application and testing your autocompletion feature, please\n\u003e use `--development` flag beside `--completion` flag.\n\u003e\n\u003e When you are available to use your app globally (e.g. via Homebrew) you should\n\u003e make your users to run `eval \"$(yourapp --completion)\"` command.\n\n### Overview\n```crystal\nrequire \"completion\"\n\n# [detected program] \u003caction\u003e \u003cuser\u003e \u003cremote\u003e\n\ncompletion :action, :user, :remote do |comp|\n\n  # When Program requested :action, reply the availables.\n  comp.on(:action) do\n    comp.reply [\"pull\", \"push\"]\n  end\n\n  # When Program requested :user, reply the availables.\n  comp.on(:user) do\n    comp.reply [\"f\", \"sdogruyol\", \"askn\"]\n  end\n\n  # When Program requested :remote, reply the availables with defined variables.\n  comp.on(:remote) do\n    comp.reply [\"github/#{comp.values[:user]}\", \"bitbucket/#{comp.values[:user]}\"]\n  end\n\n  # When all parameters finished, reply always...\n  # It is `Dir.entries Dir.current` by default.\n  comp.end do\n    comp.reply [\"--force\"]\n  end\nend\n```\n\n### Changing Program Name\n\nIt detects program name automatically. If you want to change it or you have problems with\ndetection, you should set the first argument to program name.\n\n```crystal\nrequire \"completion\"\n\n# myprogram \u003caction\u003e \u003cremote\u003e \u003csuboption\u003e\ncompletion \"myprogram\", :action, :remote, :suboption do |comp|\n  # ...\nend\n```\n\n### Defined Values, Last Word and Whole Line\n\nThe first parameter of the block you give has `last_word`, `line` and `fragment` parameters. So you can make\nyour parameters more dynamic.\n\n```crystal\ncompletion :searchengine, :url do |comp|\n\n  comp.on(:searchengine) do\n    comp.reply [\"google\", \"bing\"]\n  end\n\n  comp.on(:url) do\n    comp.reply [\"#{comp.values[:searchengine]}.com/search\", \"#{comp.values[:searchengine]}.com/images\"]\n  end\nend\n```\n\nThis will run as:\n\n```\n$ myapp\u003ctab\u003e\ngoogle bing\n\n$ myapp goog\u003ctab\u003e\ngoogle\n\n$ myapp google \u003ctab\u003e\ngoogle.com/search google.com/images\n```\n\n### End of Arguments\n\nYou can define what to show when arguments are finished:\n\n```crystal\ncompletion :first do |comp|\n  comp.on(:first) do\n    comp.reply [\"any\", \"option\"]\n  end\n  comp.end do\n    comp.reply [\"--force\", \"--prune\"]\n  end\nend\n```\n\n### Concatting Replies\n\nYou can reply more than one time. It will concat all of these.\n\n```crystal\ncompletion :first do |comp|\n  comp.on(:first) do\n    comp.reply [\"any\", \"option\"]\n    comp.reply [\"other\", \"awesome\"]\n    comp.reply [\"options\", \"to\", \"select\"]\n  end\nend\n```\n\n## Integrating into `OptionParser`\n\nCompletion can parse `OptionParser` arguments and it's very easy to integrate with.\n\nSimply use `complete_with` macro with the instance of `OptionParser`. It will automatically\nparse all the flags and add them to the suggestion list.\n\n```crystal\nOptionParser.parse! do |parser|\n  parser.banner = \"Usage: salute [arguments]\"\n  parser.on(\"-u\", \"--upcase\", \"Upcases the sallute\") { }\n  parser.on(\"-t NAME\", \"--to=NAME\", \"Specifies the name to salute\") { }\n  parser.on(\"-h\", \"--help\", \"Show this help\") { puts parser }\n\n  # Just add this macro to the OptionParser block.\n  complete_with parser\nend\n```\n\nIt will run as:\n\n```\n$ myapp\u003ctab\u003e\n--help    --to      --upcase  -h        -t        -u\n\n$ myapp --\u003ctab\u003e\n--help --to --upcase\n\n$ myapp --help --\u003ctab\u003e\n--help --to --upcase\n```\n\n## Installation\n\n*(You should add these instructions to your project's README)*\n\n```bash\n# Add this line to your .bashrc file.\neval \"$(yourapp --completion)\"\n```\n\n# Examples\n\nExamples are here to show you how to make it more functional.\n\n## Real World Examples\n\n| Project Name | Talk is cheap, show me the code |\n| ------------ | ------------------------------- |\n| [tlcr](https://github.com/porras/tlcr) | [src/tlcr/completion.cr](https://github.com/porras/tlcr/blob/master/src/tlcr/completion.cr#L28-L39) |\n| [cryload](https://github.com/sdogruyol/cryload) | [src/cryload/cli.cr](https://github.com/sdogruyol/cryload/blob/master/src/cryload/cli.cr#L36) |\n\n## Branched Autocompletion\n\nThis is how you can branch options and suboptions by using `values` parameter.\n\n```crystal\ncompletion :action, :subaction, :subsubaction do |comp|\n  comp.on(:action) do\n    comp.reply [\"pull\", \"log\", \"commit\", \"remote\"]\n  end\n\n  comp.on(:subaction) do\n    case comp.values[:action]\n      when \"pull\"\n        comp.reply [\"origin\", \"upstream\"]\n\n      when \"log\"\n        comp.reply [\"HEAD\", \"master\", \"develop\"]\n\n      when \"commit\"\n        comp.reply [\"--amend\", \"-m\", \"-am\"]\n    end\n  end\n\n  comp.on(:subsubaction) do\n    case comp.values[:subaction]\n      when \"origin\"\n        comp.reply [\"origin/master\", \"origin/upstream\", \"origin/patch\"]\n\n      when \"HEAD\"\n        comp.reply [\"~1\", \"~2\", \"~3\"]\n    end\n  end\nend\n```\n\n## Remote Autocompletion\n\nYou can make a remote autocompletion using `HTTP::Client`.\n\n```crystal\nrequire \"json\"\nrequire \"http/client\"\n\ncompletion :repos do |comp|\n  comp.on(:repos) do\n    request = HTTP::Client.get \"https://api.github.com/users/f/repos\"\n    repos = JSON.parse(request.body)\n    repo_names = [] of JSON::Any\n    repos.each {|repo| repo_names \u003c\u003c repo[\"name\"] }\n\n    comp.reply repo_names\n  end\nend\n```\n\nThis will run as:\n\n```\n$ mygit c\u003ctab\u003e\ncards     coffeepad     completion    cryload     crystal-kemal-todo-list     crystal-weekly\n```\n\n## TODO\n\n - [ ] Add ZSH Support\n\n## Contributing\n\n1. Fork it ( https://github.com/f/completion/fork )\n2. Create your feature branch (git checkout -b my-new-feature)\n3. Commit your changes (git commit -am 'Add some feature')\n4. Push to the branch (git push origin my-new-feature)\n5. Create a new Pull Request\n\n## Contributors\n\n- [f](https://github.com/f) Fatih Kadir Akın - creator, maintainer\n\n\u003e It's acutally a port of [`omelette`](http://github.com/f/omelette) package of Node.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff%2Fcompletion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ff%2Fcompletion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff%2Fcompletion/lists"}