From 1d6065d3087db8badd041dc9c83e5ed710cfa093 Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Fri, 3 Sep 2021 16:36:12 +0800 Subject: [PATCH] Refactor the bangs script Even at a couple hundred lines, it is slightly not good to navigate the codebase. I'll just make it into `main` ala-Rust/C/whatever-C-inspired-language. --- bangs/config.json | 10 +-- bin/bangs | 177 +++++++++++++++++++++++++++------------------- 2 files changed, 110 insertions(+), 77 deletions(-) diff --git a/bangs/config.json b/bangs/config.json index 657dde0..de8226c 100644 --- a/bangs/config.json +++ b/bangs/config.json @@ -18363,6 +18363,10 @@ "name": "GitHub", "url": "https://github.com/search?utf8=%E2%9C%93&q={{{s}}}" }, + "gh.nix": { + "name": "NixOS Packages", + "url": "https://github.com/NixOS/nixpkgs/search?q={{{s}}}" + }, "gha": { "name": "GitHub Actions", "url": "https://github.com/marketplace?type=actions&query={{{s}}}" @@ -32941,11 +32945,7 @@ }, "nixpkg": { "name": "NixOS Packages", - "url": "https://nixos.org/nixos/packages.html?query={{{s}}}" - }, - "nixpkgs": { - "name": "NixOS Packages", - "url": "https://nixos.org/nixos/packages.html?query={{{s}}}" + "url": "https://search.nixos.org/packages?query={{{s}}}" }, "nixtodon": { "name": "Nixtodon", diff --git a/bin/bangs b/bin/bangs index 053256b..1ec8023 100755 --- a/bin/bangs +++ b/bin/bangs @@ -36,48 +36,13 @@ Examples: HELP } -# These are the default bangs available. -# Bangs are any keys that shouldn't have whitespace characters. -const config_dir = "${XDG_CONFIG_HOME:-"$HOME/.config"}/bangs" -const config_file = "${config_dir}/config.json" -const default_config = { - 'aw': { - 'name': 'Arch Wiki', - 'url': 'https://wiki.archlinux.org/index.php?title=Special%3ASearch&search={{{s}}}' - }, - 'gh': { - 'name': 'GitHub', - 'url': 'https://github.com/search?utf8=%E2%9C%93&q={{{s}}}' - }, - 'g': { - 'name': 'Google', - 'url': 'https://www.google.com/search?q={{{s}}}' - }, - 'so': { - 'name': 'Stack Overflow', - 'url': 'http://stackoverflow.com/search?q={{{s}}}' - }, - 'w': { - 'name': 'Wikipedia', - 'url': 'https://en.wikipedia.org/wiki/Special:Search?search={{{s}}}' - } -} - -const bangs_prefix = "${BANGS_PREFIX:-~}" -const bangs_placeholder = "${BANGS_PLACEHOLDER:-{{{s}}}}" -const bangs_format = / %start $bangs_prefix !space+ %end / -const valid_bangs = %() -const search_query = %() - -# Config file detection. -# Otherwise, we'll just use the default config. -if test -f $config_file { - json read :bangs < $config_file -} else { - var bangs = default_config -} - -# Stolen from https://gist.github.com/cdown/1163649 and https://gist.github.com/cdown/1163649#gistcomment-1256298 +# Simply prints the given string into percent-encoded equivalent. +# +# > urlencode "Hello world" +# Hello%20world +# +# Stolen from https://gist.github.com/cdown/1163649 and https://gist.github.com/cdown/1163649#gistcomment-1256298. +# Just ported it in Oil script. proc urlencode(msg) { for (i in 0:len(msg)) { var char = msg[i] @@ -93,39 +58,107 @@ proc urlencode(msg) { } } +# `printf` except it prints in the stderr stream. proc warnf(format, @msg) { >&2 printf "$format\\n" @msg } -if (len(ARGV) == 0) { - usage - exit 0 +# The entry point of this program. +proc main { + # Config-related variables. + # For now, there is no system-related config. + # This is primarily a user script, after all. :) + const config_dir = "${XDG_CONFIG_HOME:-"$HOME/.config"}/bangs" + const config_file = "${config_dir}/config.json" + + # Note you can configure these variables through the respective environment variables. + const bangs_prefix = "${BANGS_PREFIX:-~}" + const bangs_placeholder = "${BANGS_PLACEHOLDER:-{{{s}}}}" + + # These are the default bangs available. + # Bangs are any keys that shouldn't have whitespace characters. + # We'll use this in case there is no user configuration. + # + # We also made the default config to be more flexible with the placeholder. + const default_config = { + 'aw': { + 'name': 'Arch Wiki', + 'url': 'https://wiki.archlinux.org/index.php?title=Special%3ASearch&search=' + bangs_placeholder + }, + 'gh': { + 'name': 'GitHub', + 'url': 'https://github.com/search?utf8=%E2%9C%93&q=' + bangs_placeholder + }, + 'g': { + 'name': 'Google', + 'url': 'https://www.google.com/search?q=' + bangs_placeholder + }, + 'so': { + 'name': 'Stack Overflow', + 'url': 'http://stackoverflow.com/search?q=' + bangs_placeholder + }, + 'w': { + 'name': 'Wikipedia', + 'url': 'https://en.wikipedia.org/wiki/Special:Search?search=' + bangs_placeholder + } + } + + # Setting up some variables. + const bangs_format = / %start $bangs_prefix !space+ %end / + const valid_bangs = %() + const search_query = %() + + # Config file detection. + # Otherwise, we'll just use the default config. + if test -f $config_file { + json read :bangs < $config_file + } else { + var bangs = default_config + } + + # Show the usage when no arguments was given like any sane program. + if (len(ARGV) == 0) { + usage + exit 0 + } + + # Filter out the bangs from the search query. + # The bangs are just words prefixed with a certain sequence of characters. + # We put both bangs and the search query in separate arrays for easier processing. + # E.g., in the search query `hello ~ddg world ~g`, `~ddg~ and `~g` are the bangs. + for i in @ARGV { + # If the argument is not a bang, append in the search query queue. + write -- $i | rg --quiet $bangs_format || { + append :search_query $i + continue + } + + # Otherwise, put it in the bangs array. + # Keep in mind, we do throw out bangs that are not in the bangs database. + var bang = $(write -- $i | sed --regexp-extended --expression "s/^${bangs_prefix}//") + if (bang in bangs) { + append :valid_bangs $bang + warnf "%s will be used to search." $bang + } else { + warnf "%s is not found in the database." $bang + } + } + + # Encode the query for a consistent formatting. + # Even though this script is in Oil where it has less problems with splitting strings, we still might want to encode the query for a good measure. + var query = join(search_query, " ") + var encoded_query = $(urlencode $query) + + warnf "Search query is '%s'" $query + warnf "Encoded form is '%s'" $encoded_query + + # Search the query with the given bangs. + for bang in @valid_bangs { + var metadata = bangs[bang] + var url = $(write -- ${metadata['url']} | sed --expression "s/${bangs_placeholder}/${encoded_query}/") + + handlr open $url + } } -for i in @ARGV { - write -- $i | rg --quiet $bangs_format || { - append :search_query $i - continue - } - - var bang = $(write -- $i | sed --regexp-extended --expression "s/^${bangs_prefix}//") - if (bang in bangs) { - append :valid_bangs $bang - warnf "%s will be used to search." $bang - } else { - warnf "%s is not found in the database." $bang - } -} - -var query = join(search_query, " ") -var encoded_query = $(urlencode $query) - -warnf "Search query is '%s'" $query -warnf "Encoded form is '%s'" $encoded_query - -for bang in @valid_bangs { - var metadata = bangs[bang] - var url = $(write -- ${metadata['url']} | sed --expression "s/${bangs_placeholder}/${encoded_query}/") - - handlr open $url -} +main @ARGV