{"id":15044999,"url":"https://github.com/denosaurs/tabtab","last_synced_at":"2025-10-24T19:30:17.158Z","repository":{"id":62421674,"uuid":"295135257","full_name":"denosaurs/tabtab","owner":"denosaurs","description":"📎 Generate CLI completions for zsh, bash, and fish","archived":false,"fork":false,"pushed_at":"2020-11-21T01:36:29.000Z","size":51,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-04-13T23:13:36.767Z","etag":null,"topics":["bash","cli","completions","deno","fish","zsh"],"latest_commit_sha":null,"homepage":"https://deno.land/x/tabtab","language":"TypeScript","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/denosaurs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"open_collective":"denosaurs","github":"denosaurs"}},"created_at":"2020-09-13T11:17:01.000Z","updated_at":"2024-01-24T13:52:33.000Z","dependencies_parsed_at":"2022-11-01T17:31:54.202Z","dependency_job_id":null,"html_url":"https://github.com/denosaurs/tabtab","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denosaurs%2Ftabtab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denosaurs%2Ftabtab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denosaurs%2Ftabtab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denosaurs%2Ftabtab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/denosaurs","download_url":"https://codeload.github.com/denosaurs/tabtab/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219868059,"owners_count":16555878,"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":["bash","cli","completions","deno","fish","zsh"],"created_at":"2024-09-24T20:51:19.957Z","updated_at":"2025-10-24T19:30:16.524Z","avatar_url":"https://github.com/denosaurs.png","language":"TypeScript","funding_links":["https://opencollective.com/denosaurs","https://github.com/sponsors/denosaurs"],"categories":[],"sub_categories":[],"readme":"# tabtab\n\n[![Tags](https://img.shields.io/github/release/denosaurs/tabtab)](https://github.com/denosaurs/tabtab/releases)\n[![CI Status](https://img.shields.io/github/workflow/status/denosaurs/tabtab/check)](https://github.com/denosaurs/tabtab/actions)\n[![Dependencies](https://img.shields.io/github/workflow/status/denosaurs/tabtab/depsbot?label=dependencies)](https://github.com/denosaurs/depsbot)\n[![License](https://img.shields.io/github/license/denosaurs/tabtab)](https://github.com/denosaurs/tabtab/blob/master/LICENSE)\n\n\u003cp align=\"center\"\u003e\n  \u003cbr\u003e\n  \u003cimg src=\"assets/example.svg\" width=\"650\"\u003e\n  \u003cbr\u003e\n\u003c/p\u003e\n\n## Usage\n\nWriting completion is a two-step process: Installation and Logging. Tabtab\nprovides just that.\n\nHere is a basic example using\n[std parse](https://deno.land/std@0.78.0/flags) to parse arguments.\n\n```js\nimport { tabtab, ParsedEnv } from \"../mod.ts\";\nimport { parse } from \"https://deno.land/std@0.78.0/flags/mod.ts\";\n\nconst opts = parse(Deno.args, {\n  string: [\"foo\", \"bar\"],\n  boolean: [\"help\", \"version\", \"loglevel\"],\n});\n\nconst args = opts._;\nconst completion = (env: ParsedEnv) =\u003e {\n  if (!env.complete) return;\n\n  // Write your completions there\n\n  if (env.prev === \"foo\") {\n    return tabtab.log([\"is\", \"this\", \"the\", \"real\", \"life\"]);\n  }\n\n  if (env.prev === \"bar\") {\n    return tabtab.log([\"is\", \"this\", \"just\", \"fantasy\"]);\n  }\n\n  if (env.prev === \"--loglevel\") {\n    return tabtab.log([\"error\", \"warn\", \"info\", \"notice\", \"verbose\"]);\n  }\n\n  return tabtab.log([\n    \"--help\",\n    \"--version\",\n    \"--loglevel\",\n    \"foo\",\n    \"bar\",\n    \"someCommand:a comprehensive description of the command\",\n    {\n      name: \"someOtherCommand\",\n      description: \"comprehensive description of the other command\",\n    },\n    \"anotherOne\",\n  ]);\n};\n\nconst run = async () =\u003e {\n  const cmd = args[0];\n\n  // Write your CLI there\n\n  // Here we install for the program `tabtab-test` (this file), with\n  // completer being the same program. Sometimes, you want to complete\n  // another program that's where the `completer` option might come handy.\n  if (cmd === \"install-completion\") {\n    await tabtab.install({\n      name: \"tabtab-test\",\n      completer: \"tabtab-test\",\n      location: tabtab.defaultLocation(),\n    });\n\n    return;\n  }\n\n  if (cmd === \"uninstall-completion\") {\n    // Here we uninstall for the program `tabtab-test` (this file).\n    await tabtab.uninstall({\n      name: \"tabtab-test\",\n    });\n\n    return;\n  }\n\n  // The completion command is added automatically by tabtab when the program\n  // is completed. Can be configured with the `cmd` option in install.\n  if (cmd === \"completion\") {\n    const env = tabtab.parseEnv();\n    return completion(env);\n  }\n};\n\nrun();\n```\n\nPlease refer to the\n[examples/hello.ts](examples/hello.ts) module for a\nworking example. The following usage documentation is based on it.\n\n### 1. Install completion\n\nTo enable completion for a given program or module, you must enable the\ncompletion on your or user's system. This is done by calling `tabtab.install()`\nusually behind a `program install-completion` command or something similar.\n\n```js\n// Here we install for the program `tabtab-test`, with completer being the same\n// program. Sometimes, you want to complete another program that's where the\n// `completer` option might come handy.\ntabtab\n  .install({\n    name: \"tabtab-test\",\n    completer: \"tabtab-test\",\n    location: \"~/.profile\", // optional\n    cmd: \"completions\", // optional\n  })\n  .then(() =\u003e console.log(\"Completion installed\"))\n  .catch((err) =\u003e console.error(err));\n```\n\nThe method returns a promise, so `await / async` usage is possible. It takes an\n`options` parameter, with:\n\n- `name`: The program to complete\n- `completer`: The program that does the completion (can be the same program).\n- `location`: Location of shell configuration.\n- `cmd`: Command to call your script with when asking for completions.\n\n`tabtab.install()` will ask the user which SHELL to use, and optionally a path\nto write to. This will add a new line to either `~/.bashrc`, `~/.zshrc` or\n`~/.config/fish/config.fish` file to source tabtab completion script.\n\nOnly one line will be added, even if it is called multiple times.\n\n### 2. Log completion\n\nOnce the completion is enabled and active, you can write completions for the\nprogram (here, in this example `tabtab-test`). Briefly, adding completions is\nas simple as logging output to `stdout`, with a few particularities (namely on\nBash, and for descriptions), but this is taken care of by `tabtab.log()`.\n\n```js\ntabtab.log([\n  '--help',\n  '--version',\n  'command'\n  'command-two'\n]);\n```\n\nThis is the simplest way of adding completions. You can also use an object,\ninstead of a simple string, with `{ name, description }` property if you want\nto add descriptions for each completion item, for the shells that support them\n(like Zsh or Fish). Or use the simpler `name:description` form.\n\n```js\ntabtab.log([\n  { name: \"command\", description: \"Description for command\" },\n  \"command-two:Description for command-two\",\n]);\n```\n\nThe `{ name, description }` approach is preferable in case you have completion\nitems with `:` in them.\n\nNote that you can call `tabtab.log()` multiple times if you prefer to do so, it\nsimply logs to the console in sequence.\n\n### 3. Parsing env\n\nIf you ever want to add more intelligent completion, you'll need to check and\nsee what is the last or previous word in the completed line, so that you can\nadd options for a specific command or flag (such as loglevels for `--loglevel`\nfor instance).\n\nTabtab adds a few environment variables for you to inspect and use, this is\ndone by calling `tabtab.parseEnv()` method.\n\n```js\nconst env = tabtab.parseEnv();\n// env:\n//\n// - complete    A Boolean indicating whether we act in \"plumbing mode\" or not\n// - words       The Number of words in the completed line\n// - point       A Number indicating cursor position\n// - line        The String input line\n// - partial     The String part of line preceding cursor position\n// - last        The last String word of the line\n// - lastPartial The last word String of partial\n// - prev        The String word preceding last\n```\n\nUsually, you'll want to check against `env.last` or `env.prev`.\n\n```js\nif (env.prev === \"--loglevel\") {\n  tabtab.log([\"error\", \"warn\", \"info\", \"notice\", \"verbose\"]);\n}\n```\n\n## Completion mechanism\n\nFeel free to browse the [scripts](./scripts) directory to inspect the various\ntemplate files used when creating a completion with `tabtab.install()`.\n\nHere is a Bash completion snippet created by tabtab.\n\n```bash\n###-begin-tabtab-test-completion-###\nif type complete \u0026\u003e/dev/null; then\n  _tabtab-test_completion () {\n    local words cword\n    if type _get_comp_words_by_ref \u0026\u003e/dev/null; then\n      _get_comp_words_by_ref -n = -n @ -n : -w words -i cword\n    else\n      cword=\"$COMP_CWORD\"\n      words=(\"${COMP_WORDS[@]}\")\n    fi\n\n    local si=\"$IFS\"\n    IFS=$'\\n' COMPREPLY=($(COMP_CWORD=\"$cword\" \\\n                           COMP_LINE=\"$COMP_LINE\" \\\n                           COMP_POINT=\"$COMP_POINT\" \\\n                           tabtab-test completion -- \"${words[@]}\" \\\n                           2\u003e/dev/null)) || return $?\n    IFS=\"$si\"\n    if type __ltrim_colon_completions \u0026\u003e/dev/null; then\n      __ltrim_colon_completions \"${words[cword]}\"\n    fi\n  }\n  complete -o default -F _tabtab-test_completion tabtab-test\nfi\n###-end-tabtab-test-completion-###\n```\n\nThe system is quite simple (though hard to nail it down, thank you npm). A new\nBash function is created, which is invoked whenever `tabtab-test` is tab\ncompleted. This function then invokes the completer `tabtab-test completion`\nwith `COMP_CWORD`, `COMP_LINE` and `COMP_POINT` environment variables (which is\nparsed by `tabtab.parseEnv()`).\n\nThe same mechanism can be applied to Zsh and Fish.\n\n### Completion install\n\nAs described in the [`Usage \u003e Install Completion`](#1-install-completion)\nsection, installing a completion involves adding a new line to source in either\n`~/.bashrc`, `~/.zshrc` or `~/.config/fish/config.fish` file.\n\nIn the `3.0.0` version, it has been improved to only add a single line instead\nof multiple ones, one for each completion module installed on the system.\n\nThis way, a single line is added to enable the completion of for various\nprograms without cluttering the Shell configuration file.\n\nExample for `~/.bashrc`\n\n```bash\n# deno tabtab source for modules\n# uninstall by removing these lines\n[ -f ~/.config/tabtab/__tabtab.bash ] \u0026\u0026 . ~/.config/tabtab/__tabtab.bash || true\n```\n\nIt'll load a file `__tabtab.bash`, created in the `~/.config/tabtab` directory,\nwhich will hold all the source lines for each tabtab modules defining a\ncompletion.\n\n```bash\n# deno tabtab source for foo module\n# uninstall by removing these lines\n[ -f ~/.config/tabtab/foo.bash ] \u0026\u0026 . ~/.config/tabtab/foo.bash || true\n\n# deno tabtab source for tabtab-test module\n# uninstall by removing these lines\n[ -f ~/.config/tabtab/tabtab-test.bash ] \u0026\u0026 . ~/.config/tabtab/tabtab-test.bash || true\n```\n\n### Completion uninstall\n\nYou can follow the file added in your SHELL configuration file and disable a\ncompletion by removing the above lines.\n\nOr simply disable tabtab by removing the line in your SHELL configuration file.\n\nOr, you can use `tabtab.uninstall()` to do this for you.\n\n```js\nif (cmd === \"uninstall-completion\") {\n  // Here we uninstall for the program `tabtab-test`\n  await tabtab\n    .uninstall({\n      name: \"tabtab-test\",\n    })\n    .catch((err) =\u003e console.error(\"UNINSTALL ERROR\", err));\n\n  return;\n}\n```\n\n## Debugging\n\ntabtab internally logs a lot of things, using the\n[debug](https://deno.land/x/debug) module.\n\nWhen testing a completion, it can be useful to see those logs, but writing to\n`stdout` or `stderr` while completing something can be troublesome.\n\n## Maintainers\n\n- Filippo Rossi ([@qu4k](https://github.com/qu4k))\n\n## Permission Table\n\n| Permission Needed | Required | Reason                                       |\n| ----------------- | -------- | -------------------------------------------- |\n| `--allow-env`     | yes      | Detecting current shell and completion vars. |\n\n## Other\n\n### Related\n\n- [tabtab](https://github.com/mklabs/tabtab) - tab completion helpers, for node cli programs \u0026 others.\n\n### Contribution\n\nPull request, issues and feedback are very welcome. Code style is formatted with `deno fmt` and commit messages are done following Conventional Commits spec.\n\n### Licence\n\nCopyright 2020-present, the denosaurs team. All rights reserved. MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenosaurs%2Ftabtab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdenosaurs%2Ftabtab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenosaurs%2Ftabtab/lists"}