bangin is a primitive, portable shell script which enables DuckDuckGo-like bangs.

dea3ea5 Add !caniuse

~samhh pushed to ~samhh/dev.bangs git

9 months ago

#4 Crash on invalid char

~samhh filed ticket on bangin-server-node todo

9 months ago


bangin - It's positively bangin'!

builds.sr.ht status

bangin is a primitive, portable shell script which enables DuckDuckGo-like bangs. For example, an input of bangin!hn produces an output of https://hn.algolia.com/?q=bangin. The only dependency is GNU awk.

It aspires to be extensible and, hopefully, eventually, something of a pseudo-standard.

#What's wrong with DuckDuckGo?

Nothing at all! DuckDuckGo is an excellent service and bangs are an excellent idea. They are however limited due to their centralisation.

The first issue is that of performance. In order for a user to utilise DuckDuckGo's bangs, your requests must first make it to their servers and be redirected. This adds a perceptible delay to your requests before they reach their destination.

Secondly, DuckDuckGo has a few rules that bangs must adhere to that needn't exist in a decentralised solution. For example, if you've ever wanted to bang your way to a risque website, that's not been possible. Now you can!

Finally, you cannot override or remove bangs per your personal preference, and you cannot add bangs that "would [not] be useful to more than around 500 people". This means that you can't submit a bang for that niche website you like, and you likely occasionally find yourself somewhere you didn't intend to ever be by virtue of a typo. None of these limitations are technically necessary with a decentralised model.

#Why is bangin better?

bangin solves these problems with a simple solution which is maximally extensible, free in every sense of the word, and will work anywhere that can interpret POSIX shell scripts. Given some banglists, which are merely text files of newline-separated bangs, the shell script parses your input and outputs a URL which can then be forwarded onto a web browser or other utility.

The intention is that common bangs will be managed by the community in community lists, and that you as an individual user can also optionally maintain your own personal list. Think of it a little bit like adblocking with community-run lists of blocked domains.

#How do I get started?

There doesn't yet exist much of an ecosystem around bangin, however I hope this changes. In the meantime, you can pass input from something like dmenu or rofi into bangin and pipe the output to xdg-open or a specific browser. And, because it's a dead simple shell script, any other niche use case you have can almost certainly be accomodated with just a little bit of scripting.

With the use of bangin-server-node it is possible to use bangin as the search engine in your web browser. You can see an example integration in my dotfiles.

As for banglists, I maintain a few lists that you might be interested in.

At present, the easiest way to install a banglist is to clone the repo and run:

mkdir -p ~/.local/share/bangin/lists/
ln -s /path/to/repo/example.bangs ~/.local/share/bangin/lists/

Nota bene that bangin actually checks in $XDG_DATA_HOME and falls back to ~/.local/share/ as the default per the XDG specification, so adjust accordingly.

As for the shell script itself, you can either copy it onto your system manually, possibly placing it somewhere like /usr/local/bin so that it's in your path, or if you're on Arch you can install it from the AUR. The server is also available from the AUR.

#Technical details

The shell script is written with POSIX compliance in mind, so it should run almost anywhere. If that's not the case, please report a bug!

Banglists are plaintext files in which bangs are separated by newlines. On each line is at least one comma-separated !bang, and a URL with a {{{s}}} token, delimited by a space. All *.bangs files in $XDG_DATA_HOME/bangin/lists/ are loaded in alphabetical order, with priority being given to the first matching bang. If it exists, $XDG_CONFIG_HOME/bangin/bangin.bangs will be given priority and loaded first, allowing you to override bangs in community-sourced lists.

Search syntax is currently very strict; the bang must be placed at the end of the line, and you must have both a search term and a bang, each non-empty. An input of a!b!c is interpreted as a search term of a!b and a bang of !c. Failure to adhere to this schema will result in a failure exit code.


Unlike most of my projects, which utilise a copyleft license, bangin is MIT licensed to encourage its widespread adoption and pseudo-standardisation. We all benefit if the idea of bangs becomes decentralised and normalised.