diff --git a/bin/commit b/bin/commit new file mode 100755 index 0000000..55aff07 --- /dev/null +++ b/bin/commit @@ -0,0 +1,13 @@ +#!/bin/sh +TYPE=$(gum choose "fix" "feat" "docs" "style" "refactor" "test" "chore" "revert") +SCOPE=$(gum input --placeholder "scope") + +# Since the scope is optional, wrap it in parentheses if it has a value. +test -n "$SCOPE" && SCOPE="($SCOPE)" + +# Pre-populate the input with the type(scope): so that the user may change it +SUMMARY=$(gum input --value "$TYPE$SCOPE: " --placeholder "Summary of this change") +DESCRIPTION=$(gum write --placeholder "Details of this change (CTRL+D to finish)") + +# Commit these changes +gum confirm "Commit changes?" && git add -A && git commit -m "$SUMMARY" -m "$DESCRIPTION" diff --git a/bin/nb b/bin/nb new file mode 100755 index 0000000..340e57b --- /dev/null +++ b/bin/nb @@ -0,0 +1,25477 @@ +#!/usr/bin/env bash +############################################################################### +# __ _ +# \ \ _ __ | |__ +# \ \ | '_ \| '_ \ +# / / | | | | |_) | +# /_/ |_| |_|_.__/ +# +# [nb] Command line and local web note-taking, bookmarking, and archiving with +# plain text data storage, encryption, filtering and search, pinning, #tagging, +# Git-backed versioning and syncing, Pandoc-backed conversion, global and local +# notebooks, customizable color themes, [[wiki-style linking]], plugins, and +# more in a single portable, user-friendly script. +# +# โฏ https://github.com/xwmx/nb +# โฏ https://xwmx.github.io/nb +# +# Based on Bash Boilerplate: https://github.com/xwmx/bash-boilerplate +# +# Copyright (c) 2015-present William Melody โ”ฏ hi@williammelody.com +# โ”• https://www.williammelody.com +# +# Overview +# ======== +# +# - Configuration and Setup +# - Helpers: Group 1 (alphabetical order) +# - Subcommands: Group 1 (alphabetical order) +# - Plugins +# - Option Parsing +# - _main() / Dispatch +# - Helpers: Group 2 (alphabetical order) +# - Subcommands: Group 2 (alphabetical order) +# - Subcommands: Group 3 (alphabetical order) +# +# Target Bash Version: 5 (target, recommended) +# Minimum Recommended Bash Version: 4 (fallback, recommended) +# Minimum Tested Bash Version: 3.2 (fallback, deprecated) +# +# AGPLv3 +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +############################################################################### + +############################################################################### +# Shell Options & Strict Mode +# +# More Information: +# https://github.com/xwmx/bash-boilerplate#bash-strict-mode +# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +# https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html +# https://tldp.org/LDP/abs/html/options.html +############################################################################### + +set -o errexit +set -o noglob +set -o nounset +set -o pipefail + +set +o noclobber + +shopt -s extglob + +IFS=$'\n\t' + +############################################################################### +# Environment +############################################################################### + +# $_VERSION +# +# The most recent program version. +_VERSION="7.1.1" + +# $_ME +# +# This program's basename. +_ME="$(basename "${0}")" + +# $_MY_DIR +# +# The directory containing $_ME. +_MY_DIR="$(cd "$(dirname "${0}")"; pwd)" + +# $_MY_PATH +# +# This program's full path. +_MY_PATH="${_MY_DIR}/${_ME}" + +# $_CURRENT_WORKING_DIR +# +# The current working directory in which the program was invoked. +_CURRENT_WORKING_DIR="${PWD}" + +# $_REPO +# +# The / identifier for this project's git repository. +_REPO="xwmx/nb" + +# $_REPO_MAIN_BRANCH +# +# The name of the main branch in this project's git repository. +_REPO_MAIN_BRANCH="master" + +# $_REPO_RAW_URL +# +# The base URL for raw files. +_REPO_RAW_URL="https://raw.githubusercontent.com/${_REPO}/${_REPO_MAIN_BRANCH}" + +############################################################################### +# Utilities +############################################################################### + +# _command_exists() +# +# Usage: +# _command_exists +# +# Exit / Error / Return Status: +# 0 (success, true) If a command is defined in the current environment. +# 1 (error, false) If not. +# +# More Information: +# http://stackoverflow.com/a/677212 +_command_exists() { + if [[ "${1:-}" == "w3m" ]] + then # Detect WSL 1 (https://stackoverflow.com/a/38859331), where w3m errors. + [[ -f /proc/version ]] && grep -q Micro /proc/version && return 1 + fi + + hash "${1}" 2>/dev/null +} + +# _contains() +# +# Usage: +# _contains ... +# +# Exit / Error / Return Status: +# 0 (success, true) If the item is included in the list. +# 1 (error, false) If not. +# +# Example: +# _contains "${_query}" "${_list[@]}" +_contains() { + local _query="${1:-}" + + shift + + if [[ -z "${_query}" ]] || + [[ -z "${*:-}" ]] + then + return 1 + fi + + local __element= + for __element in "${@}" + do + [[ "${__element}" == "${_query}" ]] && return 0 + done + + return 1 +} + +# _resolve_symlink() +# +# Usage: +# _resolve_symlink +# +# Description: +# Resolve the real path or target for a symbolic link. +_resolve_symlink() { + if hash "realpath" 2>/dev/null + then + realpath "${@:-}" + else + readlink "${@:-}" + fi +} + +# _sed_i() +# +# Usage: +# _sed_i ... +# +# Description: +# `sed -i` takes an extension on macOS, but that extension can cause errors +# in GNU `sed`. Detect which `sed` is available and call it with the +# appropriate arguments. +# +# More Information: +# https://stackoverflow.com/q/43171648 +# https://stackoverflow.com/a/16746032 +_sed_i() { + if sed --help >/dev/null 2>&1 + then # GNU + sed -i "${@}" + else # BSD + sed -i '' "${@}" + fi +} + +# _tput() +# +# Usage: +# _tput ... +# +# Description: +# Run `tput` commands, with fallbacks to termcap names for FreeBSD and +# `stty` and escape sequences when `tput` is not found. +_tput() { + if _command_exists "tput" + then + # More info: https://stackoverflow.com/a/64214019 + case "${1:-}" in + cols) + if tput cols &>/dev/null + then + tput cols + elif tput co &>/dev/null + then + tput co + else + printf "80\\n" + fi + + return 0 + ;; + lines) + if tput lines &>/dev/null + then + tput lines + elif tput li &>/dev/null + then + tput li + else + printf "20\\n" + fi + + return 0 + ;; + setaf|smul) + ((${_COLOR_ENABLED:-1})) || return 0 + ;; + esac + + tput "${@:-}" 2>/dev/null || { + case "${1:-}" in + sgr0) + tput me + ;; + smul) + tput us + ;; + setaf) + tput AF "${@:2}" + ;; + esac + } 2>/dev/null || printf "" + else + case "${1:-}" in + cols|lines) + { + stty size 2>/dev/null || printf "20 80\\n" + } | if [[ "${1:-}" == "cols" ]] + then + cut -d " " -f 2 + else + cut -d " " -f 1 + fi + ;; + setaf) + printf '\033[38;5;%sm' "${2:-}" + ;; + sgr0) + printf '\033[m' + ;; + smul) + printf '\033[4m' + ;; + esac + fi +} + +############################################################################### +# Debug +############################################################################### + +# _debug() +# +# Usage: +# _debug ... +# +# Description: +# Execute a command and print to standard error. The command is expected to +# print a message and should typically be either `echo`, `printf`, or `cat`. +# +# Example: +# _debug printf "Debug info. Variable: %s\\n" "$0" +__DEBUG_COUNTER=0 +__DEBUG_START_TIME= +_debug() { + # Usage: __debug_get_timestamp + __debug_get_timestamp() { + if hash "gdate" 2>/dev/null + then + gdate +%s%3N + elif date --version >/dev/null 2>&1 + then + date +%s%3N + else + return 1 + fi + } + + if ((${_USE_DEBUG:-0})) + then + __DEBUG_COUNTER=$((__DEBUG_COUNTER+1)) + printf "๐Ÿ› %s" "${__DEBUG_COUNTER} " + + "${@}" + + if [[ -n "${__DEBUG_START_TIME:-}" ]] + then + printf "โฑ %s\\n" "$(($(__debug_get_timestamp)-__DEBUG_START_TIME))" + elif __DEBUG_START_TIME="$(__debug_get_timestamp)" + then + printf "โฑ 0\\n" + fi + + printf "โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•โ€•\\n" + fi 1>&2 +} + +############################################################################### +# Error Messages +############################################################################### + +# _exit_1() +# +# Usage: +# _exit_1 +# +# Description: +# Exit with status 1 after executing the specified command with output +# redirected to standard error. The command is expected to print a message +# and should typically be either `echo`, `printf`, or `cat`. +_exit_1() { + { + [[ "${1:-}" == "_help" ]] || printf "%s " "$(_tput setaf 1)!$(_tput sgr0)" + + "${@}" + } 1>&2 + + exit 1 +} + +# _warn() +# +# Usage: +# _warn +# +# Description: +# Print the specified command with output redirected to standard error. +# The command is expected to print a message and should typically be either +# `echo`, `printf`, or `cat`. +_warn() { + { + printf "%s " "$(_tput setaf 1)!$(_tput sgr0)" + + "${@}" + } 1>&2 +} + +############################################################################### +# Option Helpers +############################################################################### + +# _option_get_value() +# +# Usage: +# _option_get_value