{"id":20081941,"url":"https://github.com/eval/bbangsearch","last_synced_at":"2025-05-06T00:31:26.637Z","repository":{"id":206046362,"uuid":"715695056","full_name":"eval/bbangsearch","owner":"eval","description":"DuckDuckGo's bang searches from the commandline","archived":false,"fork":false,"pushed_at":"2024-01-22T22:01:25.000Z","size":1625,"stargazers_count":12,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-09T06:12:43.279Z","etag":null,"topics":["babashka","cli","clojure","duckduckgo","search"],"latest_commit_sha":null,"homepage":"","language":"Clojure","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/eval.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-07T16:41:42.000Z","updated_at":"2024-11-01T08:24:35.000Z","dependencies_parsed_at":"2024-11-13T15:44:52.964Z","dependency_job_id":null,"html_url":"https://github.com/eval/bbangsearch","commit_stats":{"total_commits":36,"total_committers":1,"mean_commits":36.0,"dds":0.0,"last_synced_commit":"01db60957d7c14f53dff2c676d22a9aecb080cd3"},"previous_names":["eval/bbangsearch"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eval%2Fbbangsearch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eval%2Fbbangsearch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eval%2Fbbangsearch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eval%2Fbbangsearch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eval","download_url":"https://codeload.github.com/eval/bbangsearch/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252598319,"owners_count":21774236,"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":["babashka","cli","clojure","duckduckgo","search"],"created_at":"2024-11-13T15:41:01.604Z","updated_at":"2025-05-06T00:31:25.900Z","avatar_url":"https://github.com/eval.png","language":"Clojure","readme":"# bbangsearch❗\n\nA CLI for [DuckDuckGo's bang❗ searches](https://duckduckgo.com/bangs) written in [Babashka](https://babashka.org/).\n\n## Rationale\n\nI think bang searches are really great. Having DDG as my default search-engine, it's often easier to just type `!gh project` in the address bar than to cycle through open browser tabs to find the page of said GitHub project.\n\nI found there's also some shortcomings:\n- I miss a 'jump-to'-mode  \n  often there's no need to search, just to visit the thing you know is there.\n- some bangs are no longer working\n- no option to add custom bangs\n- they only work in the browser\n\nEnter `bbang`:\n* open (or get the url of) any of the ~14k bang search pages via the commandline\n* allow overriding/adding bangs\n* list all bangs (in an easily grep-able format)\n* allow for 'jump-to' functionality\n\n### Examples\n\n```shell\n# I. Use any of the regular DDG bangs (opens default browser),\n# e.g. gh (github), yt (youtube), dd (devdocs.io) etc.\n$ bbang gh some project\n$ bbang yt topic \"and exact phrase\"\n$ bbang dd git rebase\n\n# ...get the url\n$ bbang dd git rebase --url\n# =\u003e https://devdocs.io/#q=git+rebase\n\n\n# II. Additional built-in bangs\n# ghrepo: visit the GitHub project of the repository you're working on\n$ bbang ghrepo\n\n# ...search it\n$ bbang ghrepo _ some query\n\n# ...visit/search any one of your repositories\n$ bbang ghrepo deps-try\n$ bbang ghrepo deps-try some query\n\n# III. Add custom bangs\n# search all tickets\n$ bbang proj/tickets some query\n\n# visit specific ticket\n$ bbang proj/tickets PROJ-123\n```\n\n## Installation\n\n### Homebrew (Linux and macOS)\n\n#### Install\n\n``` bash\n$ brew install eval/brew/bbang\n# For future upgrades do:\n$ brew update \u0026\u0026 brew upgrade bbang\n```\n\nThere's also the unstable releases (tracking the mainline):\n``` bash\n$ brew install --head eval/brew/bbang\n# For future upgrades do:\n$ brew update \u0026\u0026 brew reinstall bbang\n```\n\n### bbin\n\n[bbin](https://github.com/babashka/bbin) allows for easy installation of Babashka scripts.\n\n#### Prerequisites\n\n[install bbin](https://github.com/babashka/bbin#installation) (make sure to adjust $PATH).\n\n```shell\n# latest version from mainline\n$ bbin install io.github.eval/bbangsearch\n$ bbang -h\n\n# as something else\n$ bbin install io.github.eval/bbangsearch --as b\n```\n\n### manual (Windows, Linux and macOS)\n\n#### Prerequisites\n\n* Install [babashka](https://github.com/babashka/babashka#installation)\n\nVerify that the following commands work:\n\n``` bash\n$ bb --version\nbabashka v1.3.186\n```\n\n#### Installation\n\n* Download [the latest stable bb-jar](https://github.com/eval/bbangsearch/releases/tag/stable).\n* Put an executable wrapper-script on $PATH. For example (for Linux and macOS):\n```bash\n#!/usr/bin/env sh\n\nexec bb /absolute/path/to/bbang-bb.jar \"$@\"\n```\n\n### standalone\n\nDownload, chmod +x and put somewhere on PATH:\n``` shell\n# Mac aarch64\n$ curl -sL https://github.com/eval/bbangsearch/releases/download/stable/bbang-mac-aarch64-standalone -o bbang\n\n# Linux amd64\n$ curl -sL https://github.com/eval/bbangsearch/releases/download/stable/bbang-linux-amd64-standalone -o bbang\n```\n\n## Usage\n\n```shell\n$ bbang -h\nbbang v0.7.0\n\nA CLI for DuckDuckGo's bang searches written in Babashka.\n\nUSAGE\n  $ bbang [bang [\u0026 terms] [--url]]\n  $ bbang [COMMAND]\n\nOPTIONS\n  --url  Print url instead of opening browser.\n\nCOMMANDS\n  bangs:ls  List all bangs (or via `bbang bangs [\u0026 terms]`)\n\n```\n\n### Show me the ❗s\n\nAll roughly 14k bang searches from DuckDuckGo are included.\n\n```shell\n# print table\n$ bbang bangs:ls\n\n# grep, e.g. bangs from specific domain\n$ bbang bangs:ls | grep -e '\\.dk'\n\n# Using DuckDuckGo's bang search\n$ bbang bangs github\n```\n\n### Additional ❗s\n\nAdditional built-in bangs:\n\n| Bang  | Description |\n| ------------- | ------------- |\n| `@gem` | Jump to gem on rubygems.org |\n| `@rdoc` | Jump to gem on rubydoc.info |\n| `cljd` | Alias for cljdoc |\n| `drdk` | Denmark Radio (fixes default) |\n| `drtv` | Denmark TV (fixes default) |\n| `gem` | rubygems.org (jump-to via @gem) |\n| `ghcclj` | Clojure code on GitHub (similar to `ghc`) |\n| `ghclj`  | Clojure projects on GitHub (similar to `gh`)  |\n| `ghdbf` | GitHub feed (no search) |\n| `ghrel` | Visit/search GitHub releases (see doc below) |\n| `ghrepo` | Visit/search repo on GitHub (see doc below) |\n| `grep` | Grep.app |\n| `grepclj` | Grep.app for Clojure code |\n| `java19` | Java v19 docs |\n| `java20` | Java v20 docs |\n| `java21` | Java v21 docs |\n| `java` | Alias of java21 |\n| `pgdoc14` | Postgresql docs v14 |\n| `pgdoc15` | Postgresql docs v15 |\n| `pgdoc16` | Postgresql docs v16 |\n| `pgdoc` | Postgresql docs current version |\n| `rails61` | Rails API latest v6.1.x (aliased as `rails6`) |\n| `rails70` | Rails API latest v7.0.x |\n| `rails71` | Rails API latest v7.1.x (aliased as `rails7`) |\n| `rdoc` | rubydoc.info, gems only (fixes default, jump-to via @gem) |\n\n#### ghrepo\n\nThis bang deserves it's own paragraph as it's quite powerful.  \n\nIn its simplest form it allows for visiting/searching a GitHub repository you pass it:\n```shell\n# visit\n$ bbang ghrepo eval/bbangsearch\n\n# search\n$ bbang ghrepo eval/bbangsearch some issue\n```\n\nIt also has some implied defaults.  \nE.g. with the right settings, you can leave out the GitHub organization and only provide a project-name:\n```shell\n# visit\n$ bbang ghrepo bbangsearch\n\n# search\n$ bbang ghrepo bbangsearch some issue\n```\n\nbbang derives the GitHub organization from the following settings (in order of precedence):\n* env-var `BBANG_GITHUB_ORG`\n* env-var `GITHUB_ORG`\n* git setting `github.org`  \n  `$ git config --global github.org mycom`  (leave out `--global` to set it for the current repos).\n* set env-var `BBANG_GITHUB_USER`\n* set env-var `GITHUB_USER`\n* git setting `github.user`  \n  `$ git config --global github.user eval` (leave out `--global` to set it for the current repos).\n\nFinally, when in a git working directory that has a remote pointing to GitHub[^1], you neither need to provide org or project:\n```\n# visit\n$ bbang ghrepo\n\n# search\n$ bbang ghrepo _ some issue\n```\n[^1]: in order of preference: the origin-url, any remote with an ssh-url\n\n#### ghrel\n\nThis bang works like `ghrepo`:\n- `bbang ghrel` jumps to the releases page on GitHub of the project derived from the git working directory.\n- `bbang ghrel _ some query` searches releases of said project.\n- `bbang ghrel my-other-repos [some query]` visits/searches releases of another project from the current organization.\n- `bbang ghrel org/project [some query]` visits/searches releases of specified GitHub project.\n\n### Customizations\n\nCustom/overriding bangs are defined in files named `bangs.edn` in the following places:\n- user-config  \n  `~/.config/bbang/bangs.edn` (or `$XDG_CONFIG_HOME/bbang/bangs.edn`)\n- current working directory and its direct ancestors\n\nSo when executing `bbang` from a project-folder (`~/projects/foo`), all bangs from the following places are (deep-)merged (last one wins):\n- built-in\n- user-config\n- `bangs.edn` in any folder starting at `/`, down to `~/projects/foo`\n\n#### Example\n\nHere's an example `bangs.edn` in some project-folder:\n```clojure\n;; ~/projects/foo/bangs.edn\n{\n  \"apidocs12\" {:desc \"API docs v1.2\"\n               :tpl  \"http://localhost:3333/v1.2?q={{s|urlescape}}\"\n               :aliases [\"apidocs\"]}\n}\n```\n\nIt's defined in the EDN-format (which is like JSON if you squint a bit).  \nA bang has a name (i.e. `apidocs12`) and a map (`{,,,}`) containing a description (`:desc`), a template (`:tpl`) and (optionally) aliases.  \n\nAs you have guessed, the template is what ultimately yields the url. The templating system used is [Selmer](https://github.com/yogthos/Selmer/) (more info below), but most templates are of the form `https://some-url?q={{s|urlsescape}}`. So `bbang apidocs12 some query` will open url `http://localhost:3333/v1.2?q=some+query` (quickly test bangs with the url-flag, e.g. `bbang mybang query --url`).\n\nAliases make a (new or existing) bang available under shorter (possibly existing) names. In this case we point a bang `apidocs` to `apidocs12`. You could imagine that in a big repository there might be a lot of apidoc variants: `apidocs11`, `apidocs13` etc. Combining these with an alias ensures users can always use `apidocs` and get the right version.\n\nUsers using `apidocs` a lot could even decide to have an alias for this alias in their user-config to make it even shorter:\n```clojure\n# ~/.config/bbang/bangs.edn\n{\n  \"apidocs\" {:aliases [\"ad\"]}\n}\n```\n\nUsing Selmer's tags you can do nifty things:\n```clojure\n{\n  \"mybang\"          {:desc \"Some bang\"\n                     :tpl \"{% if s|empty? %}https://example.org/all{% else %}https://example.org/search?q={{s|urlescape}}{% endif %}\"}\n  \"project/tickets\" {:desc \"Visit/search tickets\"\n                     :tpl \"{% ifmatches #\\\"^PROJ-\\\" s %}https://tickets.com/show/{{s}}{% else %}https://tickets.com/search?q={{s|urlescape}}{% endifmatches %}\"\n  \"java19\"          {:aliases [\"java\"]}}\n}\n```\nThe first example shows how to distinguish between merely visiting a resource (i.e. `bbang mybang`) and doing a search (e.g. `bbang mybang some query`) using Selmer's [if-tag](https://github.com/yogthos/Selmer/#if).  \nThe second example shows how to distinguish between jumping to a known ticket (e.g. `bbang project/tickets PROJ-123`) and doing a search. It uses the bbang-specific `ifmatches`-tag.  \nThe last example shows how to alias an existing bang. Both `java19` and `java` exist (resp. search java docs v19 and (currently) v21). This alias ensures that `java` is equivalent to `java19`.\n\n## License\n\nCopyright (c) 2023 Gert Goet, ThinkCreate. Distributed under the MIT license. See [LICENSE](./LICENSE).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feval%2Fbbangsearch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feval%2Fbbangsearch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feval%2Fbbangsearch/lists"}