From 3eeb4e2d7fd256cbc5b44131c1a44dab754f40a4 Mon Sep 17 00:00:00 2001 From: Sam Hardeman Date: Fri, 21 Nov 2025 00:40:31 +0100 Subject: [PATCH] Refactor of README.md. Change daisy_help to source directly from READEME.md to prevent data duplication. Made daisy_help granular (e.g. runnig "daisy_help bak" returns solely the description of the "bak" utility. Added the following utils/functions: - daisy_list: Provides a list of utilities similar to daisy_help but without the descriptions. - daisy_(un)alias: Adds/removes user-bound aliases inside of the lackadaisical config files. - grab: Alias of "awk '{primt $num}". --- LICENSE | 0 README.md | 222 ++++++----- daisy | 1068 -------------------------------------------------- daisy.source | 283 +++++++------ 4 files changed, 274 insertions(+), 1299 deletions(-) mode change 100644 => 100755 LICENSE mode change 100644 => 100755 README.md delete mode 100755 daisy diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 5604aea..06dd03e --- a/README.md +++ b/README.md @@ -1,94 +1,140 @@ -# LACKADAISICAL -*This project is still under heavy development!* +---*This project is still under heavy development!*--- +# L A C K A D A I S I C A L +A collection of easy-to-understand, easy-to-use scripts, functions and aliases. Designed to be beginner-friendly but also useful! -A collection of easy-to-understand, easy-to-use scripts and functions. Designed to be beginner-friendly but also useful! +## Disclaimer +Some aspects of this project were generated by Google Gemini (in particular, daisy_help and daisy_liist). While we are generally against using LLMs for code, the added functionality of being able to get information for individual tools is useful and not considered to be vital functionality. -# How to use -Simply open your shell's RC-file (.bashrc, .zshrc, etc) and include `source /daisy.source` preferably at the bottom of the file. We recommend setting your editor before sourcing `lackadaisical`. For instance, putting `export EDITOR=/usr/bin/nano` near thec\ top of your RC-file. It may later be overridden by `lackadaisical` itself if you use (or have used) `ched`. +## How to use +Simply open your shell's RC-file (.bashrc, .zshrc, etc) and include `source /daisy.source`, preferably at the bottom of the file. We recommend setting your editor before sourcing `lackadaisical`. For instance, putting `export EDITOR=/usr/bin/nano` near the top of your RC-file. It may later be overridden by `lackadaisical` itself if you use (or have used) `ched`. -You can also try out the utilities by simply sourcing the file while running your shell. It will automatically include itself into your `PATH` variable. +You can also try out the utilities by simply sourcing the file while running your shell of choice. It will automatically include itself into your `PATH` variable. -# Contents -*(taken from `daisy_help`)* +At first use, `lackadaisical` will provide you with information via `daisy_help`. This information is identical to what can be read in the `Getting Started` section below. +## Getting started +``` +--- BEGIN OF DAISY HELP --- +=============================================================================== +Thanks for installing LACKADAISICAL! +This project aims to provide useful utilities as well as learning material. + +It is still under heavy development, not all of the things on this +list are present/implemented. Utils marked with * are incomplete. + +This suite provides a number of functions, aliases and scripts. +They are all aimed at enhancing your efficiency. + +To uninstall LACKADAISICAL, simply remove the source line from your +shell RC, and reload it. This does not remove the files! +You will also need to manually clear the configuration data in '/.config/ +lackadaisical` if you so desire. + +To read this notice again, call the function 'daisy_help'. +=============================================================================== +These are the included binaries and utilities: + - calm: + Reduce a process 'niceness' to 0. + - cdz: + This utility extracts an archive to /tmp and changes + directory to it in a new shell instance. Upon exit, + the files are wiped. If `archivemount` is present, + it will be used to mount the archive instead! You can + bypass this behavior by specifying an env value of; + NO_ARCHIVEMOUNT=1. The standard script supports zip, + tarballs, and rar archives. We recommend relying on + archivemount` if you have it installed. + - editx: + Uses your standard CLI editor to create/modify a + file and make it executable. + - filewait: + This tool is given a filename of a file that does + not exist yet. When the file appears on disk, the + tool quits and simply returns the filename. This + can be used in personal workflows to stall a longer + command that relies on the existence of said file. + - newday: + A basic but powerful journaling system. Recommended + to be set up via crontab. Can be used for everything + from diaries to general file storage to even BTRFS + snapshots. + - own: + A simple utility. It's effectively an alias for + "sudo chown -R user:user" on the target dir/file. + Root permissions required! + - shrc: + This tool allows you to edit the RC file for your + shell in your preferred editor. After saving, the + file is sourced by your shell if modified. + - sw: + A basic function that swaps two files by content. + Useful for restoring backups. + - what: + This is a tool similar to which and others, the key + difference is that it returns partial matches. It can + be used to search for binaries. + - binbox: + This tool can be used to pack bash scripts into one + big megascript, much like how `busybox` works. + You can also make symlinks to it to invoke a specific + script (as of writing, 11/25, symlinks do not work well). + - bak/unbak: + These small utilities make backups of files by making + a copy with a .bak suffix. Unbak reverses the process + by using sw and removes the backup. + - lsa: + A simple alias for ls -lah. + - lsn: + A simple alias for ls -lah --sort=time --reverse. + - lss: + A simple alias for ls -lah --sort=size --reverse. + - editbin: + An alias for editx $\(which \). Saves on typing. + - editpeco: + This function uses peco+tree like 'cdp', but opens + your editor on the selected file(s). After you exit + your editor(s), you are returned to peco where you left + off. + - ched: + Like chsh but for your editor (EDITOR env). A list + from which you can choose an installed editor + (CLI or GUI) is shown. This list is by no means complete. + - cdf: + Use fzf to find a file and then cd to its location. + - cdp: + Similar to 'cdf' but uses tree+peco for the query. + - ldrc: + Edits daisy.source and re-sources it, similarly to shrc. + - daisy_init: + Alias for directly sourcing this file from any + LACKADAISICAL binary. You may use this yourself. + - grab: + Alias for awk "'{print $x}'", where x is a number. + E.g. "echo 'a b c' | grab 2" returns 'b'. + - daisy_cbin: + Contains the name of the current LACKADAISICAL + binary being run. + - daisy_enc: + Converts a file/stdin to a base64 block that can be + decoded by passing the output(s) to daisy_dec. + - daisy_enc_multi: + A version of daisy_enc that encodes multiple + files and outputs daisy_base64_data blocks to a file + or stdout. + - daisy_dec: + Converts daisy_base64_data blocks back to the form + it was in originally. + - daisy_dec_multi: + A version of daisy_dec that runs on multiple input + blocks that are either stored in a file or stdin. + - daisy_alias/daisy_unalias: + This utility sets persistent user aliases stored in + .daisy_aliases in the lackadaisical config folder. + They will remain persistent until unaliased. + Call 'daisy_alias' without parameters to get a list. + Use 'daisy_unalias' to remove an alias. + - daisy_list: + List all available commands without description. +--- END OF DAISY HELP --- ``` - =================================================================== - - Thanks for installing LACKADAISICAL! - This project aims to provide useful utilities as well as learning - material. - It is still under heavy development, not all of the things on this - list are present/implemented. - - =================================================================== - - This suite provides a number of functions, aliases and scripts. - They are all aimed at enhancing your efficiency. - - =================================================================== - - These are the included binaries: - - calm: Reduce a process niceness to 0. - - cdz: This utility extracts an archive to /tmp and changes - directory to it in a new shell instance. Upon exit, - the files are wiped. - - editx: Uses your standard CLI editor to create/modify a - file and make it executable. - - filewait: This tool is given a filename of a file that does - not exist yet. When the file appears on disk, the - program quits and simply returns the filename. This - can be used in personal workflows. - - newday: A basic but powerful journaling system. Recommended - to set up via crontab. Can be used for everything - from diaries to BTRFS snapshots. - - own: A simple utility. It effectively uses chown -R - user:user on its target. Root permissions required! - - short: This tool allows you to set up directory shortcuts. - It enhances cd t to integrate itsef using its own - syntax. It is similar to wd. - - shrc: This tool allows you to edit the RC file for your - shell in your preferred editor. After saving, the - file is sourced by your shell. - - sw: A basic function that swaps two files by content. - Useful for restoring backups. - - what: This is a tool similar to which and others, the key - difference is that it returns partial matches. It can - be used to search for binaries. - - =================================================================== - - There are aliases and functions included within this file as well: - - bak/unbak: These small utilities make backups of files by making - a copy with a .bak suffix. Unbak reverses the process - using sw and removes the backup. - - lsa: A simple alias for ls -lah. - - lsn: A simple alias for ls -lah --sort=time --reverse. - - editbin: An alias for editx $(which ). Saves on typing. - - ched: Like chsh but for your editor (EDITOR env). A list - from which you can choose an installed editor - (CLI or GUI) is shown. - - cdf: Use fzf to find a file and then cd to its location. - - ldrc: Edits this file and source it, similarly to shrc. - - daisy_init: Alias for directly sourcing this file from any - LACKADAISICAL binary. You may use this yourself. - - daisy_cbin: Contains the name of the current LACKADAISICAL - binary being run. - - daisy_enc: Converts a file/stdin to a base64 block that can be - decoded by passing the output(s) to daisy_dec. - - *_multi: A version of daisy_enc that runs encodes multiple - files and outputs daisy_base64_data blocks to a file - or stdout. - - daisy_dec: Converts daisy_base64_data blocks back to the form - it was in originally. - - *_multi: A version of daisy_dec that runs on multiple input - blocks that are either stored in a file or stdin. - - =================================================================== - - To uninstall LACKADAISICAL, simply remove the source line from your - shell RC, and reload it. This does not remove the files! - - To read this notice again, call the function 'daisy_help'. - - =================================================================== - ``` diff --git a/daisy b/daisy deleted file mode 100755 index a7d0afc..0000000 --- a/daisy +++ /dev/null @@ -1,1068 +0,0 @@ -#!/bin/bash -# Multi-call binary generated by LACKADAISICAL binbox -# daisy information: -# Contained modules: binbox calm cdz editx filewait newday own short shrc sw what -# Files included verbatim: daisy.source -# Files sourced: -# Symlink to this binary with the module name to invoke it, or -# use 'daisy ' to do the same. - -# Included file daisy.source -#!/bin/echo "This file can only be sourced, not run stand-alone." -- #!/bin/bash -# LACKADAISICAL SOURCE-ABLE FILE - -# Source this in your RC file or manually to receive some of the simpler -# utilities, as well as aliases for `shrc` and `cdf`. Set env variable -# FROM_RC to 1 when sourcing this file to get RC-related functionality: -# FROM_RC=1 source /daisy.source - -# This file is also sourced in some of the scripts included within -# lackadaisical for common functionality. Some of the shared functionality is -# only included if sourced from one of the included scripts, though you are -# free to bypass this by setting env variable DAISY_INTERNAL to 1. - -if [[ $DAISY_INTERNAL -eq 1 ]]; -then - export DAISY_BIN=$(basename $0) -fi - -# Intro function -function daisy_help() -{ - OLD_IFS="$IFS" - IFS= - echo -e "===================================================================" - echo -e "" - echo -e "Thanks for installing LACKADAISICAL!" - echo -e "This project aims to provide useful utilities as well as learning" - echo -e "material." - echo -e "" - echo -e "It is still under heavy development, not all of the things on this" - echo -e "list are present/implemented. Utils marked with * are incomplete." - echo -e "" - echo -e "===================================================================" - echo -e "" - echo -e "This suite provides a number of functions, aliases and scripts." - echo -e "They are all aimed at enhancing your efficiency." - echo -e "" - echo -e "===================================================================" - echo -e "" - echo -e "These are the included binaries:" - echo -e " - calm: Reduce a process niceness to 0." - echo -e " - cdz: This utility extracts an archive to /tmp and changes" - echo -e " directory to it in a new shell instance. Upon exit," - echo -e " the files are wiped. If \`archivemount\` is present," - echo -e " it will be used to mount the archive instead! You can" - echo -e " bypass this behavior by specifying an env value of;" - echo -e " NO_ARCHIVEMOUNT=1. The standard script supports zip," - echo -e " tarballs, and rar archives. We recommend relying on" - echo -e " \`archivemount\` if you have it installed." - echo -e " - editx: Uses your standard CLI editor to create/modify a" - echo -e " file and make it executable." - echo -e " - filewait: This tool is given a filename of a file that does" - echo -e " not exist yet. When the file appears on disk, the" - echo -e " program quits and simply returns the filename. This" - echo -e " can be used in personal workflows." - echo -e " - newday: A basic but powerful journaling system. Recommended" - echo -e " to set up via crontab. Can be used for everything" - echo -e " from diaries to BTRFS snapshots." - echo -e " - own: A simple utility. It effectively uses chown -R" - echo -e " user:user on its target. Root permissions required!" - echo -e " - short: This tool allows you to set up directory shortcuts." - echo -e " It enhances cd t to integrate itsef using its own" - echo -e " syntax. It is similar to wd." - echo -e " - shrc: This tool allows you to edit the RC file for your" - echo -e " shell in your preferred editor. After saving, the" - echo -e " file is sourced by your shell." - echo -e " - sw: A basic function that swaps two files by content." - echo -e " Useful for restoring backups." - echo -e " - what: This is a tool similar to which and others, the key" - echo -e " difference is that it returns partial matches. It can" - echo -e " be used to search for binaries." - echo -e " -*binbox: This tool can be used to pack bash scripts into one" - echo -e " big megascript, much like how \`busybox\` works." - echo -e " You can also make symlinks to it to invoke a specific" - echo -e " script (current symlinks do not work well)." - echo -e "" - echo -e "===================================================================" - echo -e "" - echo -e "There are aliases and functions included within this file as well:" - echo -e " - bak/unbak: These small utilities make backups of files by making" - echo -e " a copy with a .bak suffix. Unbak reverses the process" - echo -e " using sw and removes the backup." - echo -e " - lsa: A simple alias for ls -lah." - echo -e " - lsn: A simple alias for ls -lah --sort=time --reverse." - echo -e " - lss: A simple alias for ls -lah --sort=size --reverse." - echo -e " - editbin: An alias for editx $\(which \). Saves on typing." - echo -e " - ched: Like chsh but for your editor (EDITOR env). A list" - echo -e " from which you can choose an installed editor" - echo -e " (CLI or GUI) is shown." - echo -e " - cdf: Use fzf to find a file and then cd to its location." - echo -e " - ldrc: Edits this file and sources it, similarly to shrc." - echo -e " - daisy_init: Alias for directly sourcing this file from any" - echo -e " LACKADAISICAL binary. You may use this yourself." - echo -e " - daisy_cbin: Contains the name of the current LACKADAISICAL" - echo -e " binary being run." - echo -e " -*daisy_enc: Converts a file/stdin to a base64 block that can be" - echo -e " decoded by passing the output(s) to daisy_dec." - echo -e " - *_multi: A version of daisy_enc that runs encodes multiple" - echo -e " files and outputs daisy_base64_data blocks to a file" - echo -e " or stdout." - echo -e " -*daisy_dec: Converts daisy_base64_data blocks back to the form" - echo -e " it was in originally." - echo -e " - *_multi: A version of daisy_dec that runs on multiple input" - echo -e " blocks that are either stored in a file or stdin." - echo -e "" - echo -e "===================================================================" - echo -e "" - echo -e "To uninstall LACKADAISICAL, simply remove the source line from your" - echo -e "shell RC, and reload it. This does not remove the files!" - echo -e "" - echo -e "To read this notice again, call the function 'daisy_help'." - echo -e "" - echo -e "===================================================================" - - IFS="$OLD_IFS" -} - -# Variables for use in other utilities -# Find the right argument for our folder -ARG=$0 -if [[ ! $ARG == *daisy.source* ]]; -then - ARG="${BASH_SOURCE[0]}" -fi - -export DAISY_FOLDER=$(dirname $(realpath $ARG)) -export DAISY_SOURCE_FILE=$(realpath $ARG) -export DAISY_AVAILABLE=0 - -# Config folder setup -export DAISY_CONFIG_FOLDER="$HOME/.config/lackadaisical" -NEW_INSTALL=0 - -if [[ ! -d "$DAISY_CONFIG_FOLDER" ]]; -then - # Create the folder with its basics - mkdir -p "$DAISY_CONFIG_FOLDER" - echo "export EDITOR=$EDITOR" > "$DAISY_CONFIG_FOLDER/editor.src" - daisy_help - NEW_INSTALL=1 -fi - -# Installation into PATH -if [[ ! $PATH == *"$DAISY_FOLDER"* ]]; -then - export PATH="$PATH:$DAISY_FOLDER" - [[ NEW_INSTALL -eq 1 ]] && echo -e "Lackadaisical binaries have been added to your PATH variable." -fi - -# Load override from config (default is $EDITOR - so no change is made) -_EDITOR=$(cat "$DAISY_CONFIG_FOLDER"/editor.src | grep "EDITOR=" | sed 's/export EDITOR=//g') - -NEED_CHED=0 -if [[ -z $EDITOR ]]; -then - NEED_CHED=1 -fi - -# Never call if we're in internal mode -if [[ $DAISY_INTERNAL -eq 1 ]]; -then - NEED_CHED=0 -fi - -# Set up the basic alias for `shrc` -# Do not set these up if DAISY_INTERNAL=1 is set, or infinite recursion could -# occur! -if [[ ! -v DAISY_INTERNAL ]]; -then - alias shrc=". shrc" -fi - -############################################################################### -# FUNCTIONS and ALIASES ####################################################### -############################################################################### - -# bak and unbak -function bak() -{ - # Input: - target=$1 - - # Check if file exists - if ! test -f "$target"; - then - echo "Path not found: \"$target\"" - return 2 - fi - - # Handle both cases - if [[ UNBAK_MODE -eq 1 ]]; - then - cp -R "$target.bak" "$target" - rm -rf "$target.bak" - echo "Restored backup: $target <-- $target.bak" - else - cp -R "$target" "$target.bak" - echo "Backup made: $target --> $target.bak" - fi -} - -alias unbak="UNBAK_MODE=1 bak" -alias lsa="ls -a -l -h" -alias lsn="ls -a -l -tu -r -h" -alias lss="ls -a -l -S -r -h" - -# Simple version of `cdf` -function cdf() -{ - cd $(dirname $(fzf)) -} - -# for convenience purposes -function editbin() -{ - editx $(which $1) -} - -# sets a new editor based on commony available ones, and some visual ones -function ched() -{ - editors=("nano" "vim" "nvim" "vi" "emacs" "gedit" "kate" "mousepad" "micro" \ - "code" "subl" "joe" "kwrite" "gnome-text-editor") - - # Find which editors are installed - available_editors=() - for editor in "${editors[@]}"; - do - EDITOR_REAL=$(which $editor) - if command -v "$EDITOR_REAL" >/dev/null 2>&1; - then - if [[ $(realpath "$EDITOR") == "$EDITOR_REAL" ]]; - then - available_editors+=("$EDITOR_REAL" "$editor (current choice)") - else - available_editors+=("$EDITOR_REAL", "$editor") - fi - fi - done - - if [[ ! -z $@ ]]; - then - TEXT="$@" - dialog --msgbox "$TEXT" 0 0 - fi - - # Present all choices - CHOICE=$(dialog --clear --title "Select Text Editor (Recommendation: nano)" \ - --menu "Choose one of the installed text editors:" 15 50 6 \ - "${available_editors[@]}" 3>&1 1>&2 2>&3) - DIALOG_RET=$? - - if [ $DIALOG_RET -ne 0 ]; - then - echo "No editor selected." - return - fi - - CHOICE=$(which $CHOICE) - echo export EDITOR=$CHOICE > "$DAISY_CONFIG_FOLDER/editor.src" - echo export DAISY_OLD_EDITOR=$EDITOR >> "$DAISY_CONFIG_FOLDER/editor.src" - - # Seems silly but this is also where we should export these - source "$DAISY_CONFIG_FOLDER/editor.src" -} - -function wait_for_editor() -{ - pname="$1" - fname="$2" - - # Give some time for a process to launch - sleep 1 - - while true; - do - ALIVE=$(ps aux | grep $fname | grep $pname) - if [[ $ALIVE == "" ]] - then - break - fi - sleep 1 - done -} - -function ldrc() -{ - FROM_RC=0 $EDITOR "$DAISY_SOURCE_FILE" - wait_for_editor $EDITOR "$DAISY_SOURCE_FILE" - source "$DAISY_SOURCE_FILE" -} - -function daisy_enc() -{ - has_file=$([[ ! -z $1 ]] && file $1 1>/dev/null; echo $?) - has_file=$([[ has_file -eq 0 ]] && echo 1) - file_info="no data" - file_name="null" - if [[ has_file -eq 1 ]]; - then - file_info=$(file $1) - file_name=$(basename $1) - fi - - base64_inner=$(cat ${1:-/dev/stdin} | base64 | tr -d '\n') - - # Print out our block - echo -e "# File info: $file_info" - echo -e "daisy_data_base64_$file_name=\"$base64_inner\"" -} - -# Will only take input files, always outputs to stdout -function daisy_enc_multi() -{ - [[ ! -d $1 ]] && echo "daisy_dec_multi: No input files specified" && return - for file in "$@"; do - if [[ -f "$file" ]]; then - daisy_enc "$file" - echo # separate blocks with a newline - else - echo "daisy_enc_multi: Skipping non-file: $file" - fi - done -} - -function daisy_dec() -{ - data=$(cat ${1:-/dev/stdin} | grep -v "#" ) - echo -e "$data" | cut -d "=" -f 2- | cut -b 2- | head -c -2 | base64 -d -} - -# Will only take a file and directory, sources it to find all encoded data -# Extracts to the directory -function daisy_dec_multi() -{ - [[ ! -f $1 ]] && echo "daisy_dec_multi: No input file specified" && return - [[ ! -d $2 ]] && echo "daisy_dec_multi: No output directory specified" && return - declare -a vars=( $(cat $1 | grep -v "# File") ) - for enc in "${vars[@]}"; - do - file=$(echo -e "$enc" | cut -d "_" -f 4- | cut -d "=" -f 1) - - if [[ ! "$file" == '' ]] - then - daisy_dec <(echo "$enc") | tee "$2"/"$file" - fi - done -} - -alias daisy_init='source "$DAISY_SOURCE_FILE"' - -############################################################################### -# end of FUNCTIONS and ALIASES ################################################ -############################################################################### -if [[ $NEED_CHED -eq 1 ]]; -then - # Editor is unset, pick one, set `vi` as backup - TXT1="There is no standard EDITOR environment variable defined. Choose one of the installed text editors." - TXT2="You can always change it later wih `ched`, part of the Lackadaisical suite." - ched $TXT1 $TXT2 -fi - -# End of user section! -export DAISY_AVAILABLE=1 - -# Start of internal section - -# Check for dependencies -function daisy_dependency_check() -{ - command -v $1 1>/dev/null 2>/dev/null; - res=$? - echo $(($res ^ 1)) -} - -DAISY_HAS_fzf=$(daisy_dependency_check fzf) -DAISY_HAS_md5sum=$(daisy_dependency_check md5sum) - -function daisy_quit_if_no() -{ - has_dep=$DAISY_HAS_$1 - - # Check first if we have checked for this dependency, if not, print a fixme! - # TODO: Remove upon release, or convert into self-modifying code. - if [[ ! -v DAISY_HAS_$1 ]]; - then - echo "FIXME: Dependency `$1` should have an env variable, checking ad-hoc" - has_dep=$(daisy_dependency_check $1) - fi - - if [[ $has_dep -eq 0 ]]; - then - echo "$DAISY_BIN: The dependency $1 was not found! Please install it" \ - "to be able to use this utility!" - exit 1 - fi -} - -[ -d "$DAISY_FOLDER" ] && export DAISY_AVAILABLE=1 - -# Source everything in the config folder -# We do this at the end so that we do not run into isues -for file in "$DAISY_CONFIG_FOLDER"/*; do - [ -f "$file" ] && source "$file" -done -# Module 'binbox': -function binbox() -{ -# binbox: Creates a multi-binary script that self-contains the input scripts. -# Symlinking to the resulting binary with the name of one of the original scripts will trigger -# said script. The idea is similar to `busybox`. - -DAISY_INTERNAL=1 -. $(dirname $(realpath $0))/daisy.source - -ARGS=$@ - -function help() -{ - echo "$DAISY_BIN is a utility that allows you to generate busybox-style combined binaries." - echo "To access the original functionality of an input binary, you can either use a symlink or" - echo "call the function like so: 'combi-bin input-bin ." - echo "" - echo "> Usage:" - echo "Creating boxed binary: $DAISY_BIN -o <-s source files> <-p include files verbatim> -i INPUT_BINS ..." - echo " Unpacking a boxed binary: $DAISY_BIN -e " - echo "View this screen: $DAISY_BIN " - exit 0 -} - -if [[ $@ == '' ]]; then - help -fi - -# Define some building blocks -CASE_P1="case $BINARY in" -CASE_PM1=" $OPTION)" -CASE_PM2=" exec $OTPION_fn" -CASE_PM3=" ;;" -CASE_CM1=" *)" -CASE_CM2=" exec help_fn" -CASE_CM3=" ;;" -CASE_P2="esac" - -FUNC_P1="function $OPTION_fn() {" -FUNC_P2=" exit($?)" -FUNC_P3="}" - -BASIC_P1="BINARY=$0" - -# Start parsing args -inputs=() -output="" - -inputs=() -output="" -includes=() -sources=() - -args=("$@") -i=0 -b=0 -s=0 -p=0 -while [ $i -lt $# ]; do - case "${args[$i]}" in - -i) - ((i++)) - while [ $i -lt $# ] && [[ ! "${args[$i]}" =~ ^- ]]; do - inputs+=("${args[$i]}") - ((i++)) - ((b++)) - done - continue - ;; - -s) - ((i++)) - while [ $i -lt $# ] && [[ ! "${args[$i]}" =~ ^- ]]; do - sources+=("${args[$i]}") - ((i++)) - ((s++)) - done - continue - ;; - -p) - ((i++)) - while [ $i -lt $# ] && [[ ! "${args[$i]}" =~ ^- ]]; do - includes+=("${args[$i]}") - ((i++)) - ((p++)) - done - continue - ;; - -o) - ((i++)) - output="${args[$i]}" - ;; - esac - ((i++)) -done - -echo "Input binaries: ${inputs[*]}" -echo "Include files: ${includes[*]}" -echo "Source files: ${sources[*]}" -echo "Output binary: $output" - -if [ "$b" -eq 0 ]; then - echo "Missing input binaries!" - exit 1 -fi - -if [[ "$output" == "" ]]; then - echo "Missing output file!" - exit 1 -fi - -function add() -{ - echo "$@" >> "$output" -} - -rm -rf "$output" - -# Now to construct the binary -# >>> Section 1, includes -add "# Multi-call binary generated by LACKADAISICAL binbox" -add "# $output information:" -add "# Contained modules: ${inputs[*]}" -add "# Files included verbatim: ${includes[*]}" -add "# Files sourced: ${sources[*]}" -add "# Symlink to this binary with the module name to invoke it, or" -add "# use '$output ' to do the same." - -for f in "${sources[@]}"; do - add ". $f" -done - -for f in "${includes[@]}"; do - add "" - add "# Included file $f" - add "$(cat "$f")" -done - - -# >>> Section 2: Modules -for f in "${inputs[@]}"; do - add "# Module '$f':" - add "function $f()" - add "{" - add "}" -done - -# >>> Section 3: Module selection -add "SYMED=1" -add "BINSELF=\$(basename \$0)" -add "BOXFILE=\"$output\"" -add "if [[ \$BINSELF == \$BOXFILE ]]; then" -add " SYMED=0" -add " if [[ \$# -eq 0 ]]; then" -add " echo 'Available modules:'" - for f in "${inputs[@]}"; do - add " echo '$f'" - done -add " exit 0" -add " fi" -add "fi" - -add "if [[ \$SYMED -eq 0 ]]; then" -add " eval \$@" -add " exit \$?" -add "fi" - -add "if [[ \$SYMED -eq 1 ]]; then" -add " eval \$(basename \$0) \$@" -add "fi" - - -chmod +x "$output" -} -# Module 'calm': -function calm() -{ -# Calm a process down -# NEEDS_WORK: cleanup -# calm == only one process -# calm == all processes that match query -# calm * == if used in proc or a folder with just PID files, if not you will get an error -# calm .... OK -# set's NICE value to 0 -# need sudo - -DAISY_INTERNAL=1 -. $(dirname $(realpath $0))/daisy.source - -PIDS=$@ - -errorFn() -{ - echo calm: Invalid operation or no such PID/process \(\"$(echo "$PIDS" | tr '\n' ' ' | cut -c -20)...\"\) - exit -} - -for pid in $PIDS -do - # Process to PID in elegant way - NEWPIDS=$(pidof "$pid") - if [ "$NEWPIDS" ] - then - BINNY=$pid - pid=$NEWPIDS - else - NEWBINS=$pid - BINNY=$(ps -p "$pid" -o comm= 2>/dev/null ) - if [ $? != 0 ] - then - errorFn - fi - fi - - echo Calming down $pid \("$BINNY"\)... - sudo renice -n 0 -p $pid; -done -} -# Module 'cdz': -function cdz() -{ - -if [[ $DAISY_INTERNAL -ne 1 ]]; -then - export DAISY_INTERNAL=1 - . $(dirname $(realpath $0))/daisy.source -fi - -target=$1 - -# Check if file exists -if [[ -z "$target" ]]; -then - echo "No target specified." - exit 1 -fi - -if ! test -f "$target"; -then - echo "File not found: \"$target\"" - exit 2 -fi - -# Check if archivemount is present -which archivemount 1>/dev/null 2>/dev/null -hasmounter=$? - -file "$target" 1>/dev/null -exitcode=$? -report=$(file "$target") - -# Check for archive type, supported types are zip/tar/rar -comm1=(:) -comm2=(echo "Unsupported archive type$add: \"$target\"") -comm3=(:) -comm4=(:) -comm5=(:) - -echo $report | grep "tar archive" 1>/dev/null -istar=$? -echo $report | grep "Zip archive" 1>/dev/null -iszip=$? -echo $report | grep "Android" 1>/dev/null -iszip=$? -echo $report | grep "RAR archive" 1>/dev/null -israr=$? - -# TAR archives come in many forms, if none of our tests say it's tar -# ...but it looks like tar and barks like tar, let's take the shot. -# Seems to work fairly well for the record. -RES=$(echo "$target" | grep ".tar") -if [[ $RES != "" ]]; -then - istar=0 -fi - -if [[ $NO_ARCHIVEMOUNT -eq 1 ]]; then - hasmounter=1 -fi - -if (( $hasmounter == 0 )); then - echo "We have \`archivemount\`, so we'll use that!" - echo "If you'd prefer we not use it, please specify NO_ARCHIVEMOUNT=1" - istar=1 - iszip=1 - israr=1 -fi - -# Now we set the right command -if (( $istar == 0 )); then - comm2=(tar xvf "$target" -C) -elif (( $iszip == 0 )); then - which unzip 1>/dev/null - exitcode=$? - if (( $exitcode == 0 )); then - comm2=(unzip -q "$target" -d) - else - comm1=(echo "The utility 'unzip' is missing, please install it") - comm3=(exit 1) - fi -elif (( $israr == 0 )); then - which unrar 1>/dev/null - exitcode=$? - if (( exitcode == 0 )); then - comm2=(unrar -i nul "$target") - else - comm1=(echo "The utility 'unrar' is missing, please install it") - comm3=(exit 1) - fi -elif (( $hasmounter == 0 )); then - comm2=(archivemount "$target") - comm4=(cd ..) - comm5=(umount) -fi - -# Create the temp dir, usually -dir=$(mktemp -d /tmp/extracted.XXXXXXXX) - -# And the rest of the commands -"${comm1[@]}" -"${comm2[@]}" $dir -"${comm3[@]}" - -currentpath=$(realpath .) -cd $dir - -# With archivemount, making a symlink will alter the archive -if (( $hasmounter == 1 )); then - ln -s $currentpath ./link-back - echo "A symlink to your original path has been created under the name \`link-back\`." - echo "You can use this to copy out files, but you can also just access your filesystem regularly." -fi - -echo "Type 'exit' to exit the extracted archive's folder and auto-delete it." -eval $SHELL -"${comm4[@]}" -"${comm5[@]}" $dir -rm -rf $dir -} -# Module 'editx': -function editx() -{ -# !/bin/sh -# This utility pre-allocs a file and adds execution permissions. It also -# removes the resulting file if it is empty after the editor closes. - -DAISY_INTERNAL=1 -. $(dirname $(realpath $0))/daisy.source - -if [[ -z $1 ]]; -then - echo "No filename specified." - exit 2 -fi - -if [[ -z "${EDITOR}" ]]; -then - ched "EDITOR env variable not set! You will have to set it yourself in the next screen." -fi - -exists=$(file "$1" >/dev/null && echo $?) - -touch "$1" -chmod +x "$1" -$EDITOR "$1" -wait $! -SIZE=$(du "$1" | cut -f 1) - -if [[ $SIZE -eq 0 && $exists -ne 0 ]]; -then - rm -rf "$1" -fi -} -# Module 'filewait': -function filewait() -{ -# A simple utility that waits for a file to become available, infinitely - -DAISY_INTERNAL=1 -. $(dirname $(realpath $0))/daisy.source - -FILE=$@ -while [ ! -f "$FILE" ] -do - sleep 0.1 -done -echo $FILE -} -# Module 'newday': -function newday() -{ -# This script is intended to be run via cron. - -# It creates a folder structure in home for the current date in the following format: -# $HOME/ByDate/// - -# It also sets up a symlink in home: $HOME/Today -# This symlink will always point to the folder for the current date. - -# Finally, it removes any folders without data, to prevent clutter. - -# - Why did you make this? -# I remember things better when they have a date attached to them. -# You can use this for a primitive form of note-taking, but aside from notes - -# you can store any data this way. - -DAISY_INTERNAL=1 -. $(dirname $(realpath $0))/daisy.source - -BINSELF=$(basename $0) -DIR_NAME=ByDate -ROOT_DIR=$HOME/$DIR_NAME -TODAY_SYM=$HOME/Today - -# Present day -TODAY=$(date -I) -YEAR=$(echo $TODAY | awk -F"-" '{print $1}') -MONTH=$(echo $TODAY | awk -F"-" '{print $2}') -DAY=$(echo $TODAY | awk -F"-" '{print $3}') - -set -e - -function errorFn() -{ - ERROR=$? - if [[ $ERROR -gt 0 ]]; - then - echo "$BINSELF error ($ERROR): " - perl -E 'say $!=shift' $ERROR - fi - exit $ERROR -} - -# Error handling -trap errorFn ERR - -# First we clear out empty folders, and remove the symlink if it exists -test -e "$ROOT_DIR" && find "$ROOT_DIR" -maxdepth 3 -type d -empty -print | xargs rm -rf -test -L "$TODAY_SYM" && rm -rf "$TODAY_SYM" - -# Now we can set up today's directory -mkdir -p "$ROOT_DIR/$YEAR/$MONTH/$DAY" -cd $ROOT_DIR -ln -s "./$DIR_NAME/$YEAR/$MONTH/$DAY" "$TODAY_SYM" -exitcode=@? -} -# Module 'own': -function own() -{ -# Simple program that changes ownership to the current -# user, recursively. - -DAISY_INTERNAL=1 -. $(dirname $(realpath $0))/daisy.source - -if [[ $@ == '' ]]; -then - echo "$DAISY_BIN: Used to quickly take ownership of files/folders." - echo "Requires sudo. If sudo is not installed, this tool will fai." - echo "Usage: $DAISY_BIN " - echo "Means: chown -R : " - exit 2 -fi - -sudo chown -R $(whoami):$(whoami) $@ -} -# Module 'short': -function short() -{ -# short: Creates shortcuts that can be used anywhere. -# Can also be used as an alternative for "alias". -# -# Example usage: -# Add a shortcut: short -A dev "/home/john/Development" -# Print shortcut content: short dev -> "/home/john/Development" -# Remove shortcut: short -D dev -# -# One could use this to do things like: -# cp -R files $(short dev) -# cd $(short www) -# ssh $(short server) -# -# Uses a file named .shortcuts in $HOME - -DAISY_INTERNAL=1 -. $(dirname $(realpath $0))/daisy.source - -SHORT_FILE="$DAISY_CONFIG_FOLDER/.shortcuts" -} -# Module 'shrc': -function shrc() -{ -# `FROM_RC=1 source shrc` in your RC file to set up an alias. - -# Just opens your .rc file easily, for your current shell -# and sources the .rc afterwards! - -# Source standard setup -if [[ $DAISY_INTERNAL -ne 1 ]]; -then - DAISY_INTERNAL=1 source $DAISY_SOURCE_FILE -fi - -function md5_opt() -{ - if [[ $DAISY_HAS_md5sum -eq 1 ]]; - then - echo $(md5sum "$1" | awk '{print $1}') - fi -} - -if [[ $FROM_RC -eq 1 ]]; then - alias shrc=". shrc" -else - BASENAME=$(basename $SHELL) - RC_NAME="."$BASENAME"rc" - RC_PATH="$HOME/$RC_NAME" - - # Optional MD5 checks - HAS_CHANGED=1 - SUM1=$(md5_opt "$RC_PATH") - SUM2= - - # This sets a default if the variable does not exist. - EDITOR=${EDITOR:-$(ched)} - $EDITOR "$RC_PATH" - wait_for_editor $EDITOR "$RC_PATH" - - SUM2=$(md5_opt "$RC_PATH") - - if [[ $DAISY_HAS_md5sum -eq 1 && "$SUM1" == "$SUM2" ]]; - then - echo "The RC-file $RC_NAME has not changed on disk. Not sourcing." - return - fi - - source "$RC_PATH" -fi -} -# Module 'sw': -function sw() -{ -# It just swaps two files - -export DAISY_INTERNAL=1 -. $(dirname $(realpath $0))/daisy.source - -FILE1=$1 -FILE2=$2 - -function helpFn() -{ - ERROR=$? - if [[ $ERROR -gt 0 ]]; - then - ERROR_TEXT=$(perl -E 'say $!=shift' $ERROR) - echo "$DAISY_BIN error ($ERROR): $ERROR_TEXT" - fi - echo "Usage: $DAISY_BIN " - echo Swap two files in a filesystem. - exit $ERROR -} - -if [[ $@ == *"--help"* ]]; -then - helpFn -elif [[ $@ == '' ]]; -then - echo "No arguments specified." - helpFn -fi - -# We set a trap here, together with 'set -e' above, -# this makes sure we exit gracefully if we have an -# error in one of the ls or mv calls. -trap helpFn ERR - -# We want to swap two files -# Easy, but let's be safe about it -ls "$FILE1" >/dev/null -ls "$FILE2" >/dev/null - -# Files should exist, now we move -mv "$FILE1" "$FILE1.sw" -mv "$FILE2" "$FILE2.sw" - -# We got our moved copies, now we simply rename -mv "$FILE1.sw" "$FILE2" -mv "$FILE2.sw" "$FILE1" -} -# Module 'what': -function what() -{ -# Where is the binary? -# Usage: what [] -# Returns: -# With no parameters, all visible binaries in PATH. -# With parameter, all binaries that match the pattern -# given. Accepts default grep patterns, case insensitive -# -# Examples: -# $ what zs.* -# pzstd -# zsh -# zstd -# -# $ what ftp -# ftppass -# sftp -# vsftpd -# -# $ what ftp | xargs which -# /usr/bin/ftppass -# /usr/bin/sftp -# /usr/sbin/vsftpd -# - -DAISY_INTERNAL=1 -. $(dirname $(realpath $0))/daisy.source - -PWD=/ -ALL_BINS=$(cd / && echo $PATH | sed 's/[:]/ /g' | xargs ls -A | grep -v ":" | sort | uniq) -OUTPUT=$(printf '%s\n' "-n" $ALL_BINS | grep -i "$1") -echo "$OUTPUT" -} -SYMED=1 -BINSELF=$(basename $0) -BOXFILE="daisy" -if [[ $BINSELF == $BOXFILE ]]; then - SYMED=0 - if [[ $# -eq 0 ]]; then - echo 'Available modules:' - echo 'binbox' - echo 'calm' - echo 'cdz' - echo 'editx' - echo 'filewait' - echo 'newday' - echo 'own' - echo 'short' - echo 'shrc' - echo 'sw' - echo 'what' - exit 0 - fi -fi -if [[ $SYMED -eq 0 ]]; then - eval $@ - exit $? -fi -if [[ $SYMED -eq 1 ]]; then - eval $(basename $0) $@ -fi diff --git a/daisy.source b/daisy.source index 629e17b..52d3327 100755 --- a/daisy.source +++ b/daisy.source @@ -25,7 +25,7 @@ then fi # Check for dependencies -function daisy_dependency_check() +function daisy_dependency_check { command -v $1 1>/dev/null 2>/dev/null; res=$? @@ -78,7 +78,7 @@ fi ############################################################################### # bak and unbak -function bak() +function bak { # Input: target=$1 @@ -108,12 +108,12 @@ alias lsn="ls -a -l -tu -r -h" alias lss="ls -a -l -S -r -h" # Simple version of `cdf` -function cdf() +function cdf { cd $(dirname $(fzf)) } -function cdp() +function cdp { if [[ $DAISY_HAS_peco != 1 || $DAISY_HAS_tree != 1 ]]; then @@ -136,13 +136,13 @@ function editpeco } # for convenience purposes -function editbin() +function editbin { editx $(which $1) } # sets a new editor based on commony available ones, and some visual ones -function ched() +function ched { editors=("nano" "vim" "nvim" "vi" "emacs" "gedit" "kate" "mousepad" "micro" \ "code" "subl" "joe" "kwrite" "gnome-text-editor") @@ -189,7 +189,7 @@ function ched() source "$DAISY_CONFIG_FOLDER/editor.src" } -function wait_for_editor() +function wait_for_editor { pname="$1" fname="$2" @@ -208,13 +208,13 @@ function wait_for_editor() done } -function ldrc() +function ldrc { FROM_RC=0 $EDITOR "$DAISY_SOURCE_FILE" source "$DAISY_SOURCE_FILE" } -function daisy_enc() +function daisy_enc { has_file=$([[ ! -z $1 ]] && file $1 1>/dev/null; echo $?) has_file=$([[ has_file -eq 0 ]] && echo 1) @@ -234,9 +234,8 @@ function daisy_enc() } # Will only take input files, always outputs to stdout -function daisy_enc_multi() +function daisy_enc_multi { - [[ ! -d $1 ]] && echo "daisy_dec_multi: No input files specified" && return for file in "$@"; do if [[ -f "$file" ]]; then daisy_enc "$file" @@ -247,7 +246,7 @@ function daisy_enc_multi() done } -function daisy_dec() +function daisy_dec { data=$(cat ${1:-/dev/stdin} | grep -v "#" ) echo -e "$data" | cut -d "=" -f 2- | cut -b 2- | head -c -2 | base64 -d @@ -255,7 +254,7 @@ function daisy_dec() # Will only take a file and directory, sources it to find all encoded data # Extracts to the directory -function daisy_dec_multi() +function daisy_dec_multi { [[ ! -f $1 ]] && echo "daisy_dec_multi: No input file specified" && return [[ ! -d $2 ]] && echo "daisy_dec_multi: No output directory specified" && return @@ -266,11 +265,59 @@ function daisy_dec_multi() if [[ ! "$file" == '' ]] then - daisy_dec <(echo "$enc") | tee "$2"/"$file" + daisy_dec <(echo "$enc") > "$2"/"$file" fi done } +# Saves a bit on typing +function grab +{ + [[ -z $@ ]] && return; + awk '{print $'$1'}' +} + +# Functions for aliases that are added once, but always available +daisy_aliasfile="$DAISY_CONFIG_FOLDER"/.daisy_aliases +touch $daisy_aliasfile + +function daisy_unalias +{ + unalias_param=$@ + + if [[ -z $unalias_param ]]; then + return + fi + + unalias $@ 2>/dev/null + + # Remove from aliases list + newdata=$(cat $daisy_aliasfile | grep -v "alias $unalias_param") + echo -e $newdata > $daisy_aliasfile +} + +function daisy_alias +{ + alias_param="$@" + + if [[ -z $alias_param ]]; then + echo "Active lackadaisical alias lines:" + cat $daisy_aliasfile | sed 's/alias //g' + return + fi + + # Plain name and contents + alias_name=$(echo -e $alias_param | grep -o ".*=" | tr --delete =) + + # Make persistent + daisy_unalias $alias_name + echo alias ${alias_param%=*}"="\"${alias_param#*=}\" >> $daisy_aliasfile + + alias $alias_param +} + +source $daisy_aliasfile + alias daisy_init='source "$DAISY_SOURCE_FILE"' ############################################################################### @@ -281,7 +328,7 @@ alias daisy_init='source "$DAISY_SOURCE_FILE"' export DAISY_AVAILABLE=1 # Start of internal section -function daisy_quit_if_no() +function daisy_quit_if_no { has_dep=$DAISY_HAS_$1 @@ -303,133 +350,83 @@ function daisy_quit_if_no() [ -d "$DAISY_FOLDER" ] && export DAISY_AVAILABLE=1 -# Help function -function daisy_help() -{ - OLD_IFS="$IFS" - IFS= - echo -e "===================================================================" - echo -e "" - echo -e "Thanks for installing LACKADAISICAL!" - echo -e "This project aims to provide useful utilities as well as learning" - echo -e "material." - echo -e "" - echo -e "It is still under heavy development, not all of the things on this" - echo -e "list are present/implemented. Utils marked with * are incomplete." - echo -e "" - echo -e "===================================================================" - echo -e "" - echo -e "This suite provides a number of functions, aliases and scripts." - echo -e "They are all aimed at enhancing your efficiency." - echo -e "" - echo -e "===================================================================" - echo -e "" - echo -e "These are the included binaries:" - echo -e " - calm:" - echo -e " Reduce a process niceness to 0." - echo -e " - cdz:" - echo -e " This utility extracts an archive to /tmp and changes" - echo -e " directory to it in a new shell instance. Upon exit," - echo -e " the files are wiped. If \`archivemount\` is present," - echo -e " it will be used to mount the archive instead! You can" - echo -e " bypass this behavior by specifying an env value of;" - echo -e " NO_ARCHIVEMOUNT=1. The standard script supports zip," - echo -e " tarballs, and rar archives. We recommend relying on" - echo -e " archivemount\` if you have it installed." - echo -e " - editx:" - echo -e " Uses your standard CLI editor to create/modify a" - echo -e " file and make it executable." - echo -e " - filewait:" - echo -e " This tool is given a filename of a file that does" - echo -e " not exist yet. When the file appears on disk, the" - echo -e " program quits and simply returns the filename. This" - echo -e " can be used in personal workflows." - echo -e " - newday:" - echo -e " A basic but powerful journaling system. Recommended" - echo -e " to set up via crontab. Can be used for everything" - echo -e " from diaries to BTRFS snapshots." - echo -e " - own:" - echo -e " A simple utility. It effectively uses chown -R" - echo -e " user:user on its target. Root permissions required!" - echo -e " - short:" - echo -e " This tool allows you to set up directory shortcuts." - echo -e " It enhances cd t to integrate itsef using its own" - echo -e " syntax. It is similar to wd." - echo -e " - shrc:" - echo -e " This tool allows you to edit the RC file for your" - echo -e " shell in your preferred editor. After saving, the" - echo -e " file is sourced by your shell." - echo -e " - sw:" - echo -e " A basic function that swaps two files by content." - echo -e " Useful for restoring backups." - echo -e " - what:" - echo -e " This is a tool similar to which and others, the key" - echo -e " difference is that it returns partial matches. It can" - echo -e " be used to search for binaries." - echo -e " -*binbox:" - echo -e " This tool can be used to pack bash scripts into one" - echo -e " big megascript, much like how \`busybox\` works." - echo -e " You can also make symlinks to it to invoke a specific" - echo -e " script (current symlinks do not work well)." - echo -e "" - echo -e "===================================================================" - echo -e "" - echo -e "There are aliases and functions included within this file as well:" - echo -e " - bak/unbak:" - echo -e " These small utilities make backups of files by making" - echo -e " a copy with a .bak suffix. Unbak reverses the process" - echo -e " using sw and removes the backup." - echo -e " - lsa:" - echo -e " A simple alias for ls -lah." - echo -e " - lsn:" - echo -e " A simple alias for ls -lah --sort=time --reverse." - echo -e " - lss:" - echo -e " A simple alias for ls -lah --sort=size --reverse." - echo -e " - editbin:" - echo -e " An alias for editx $\(which \). Saves on typing." - echo -e " - editpeco:" - echo -e " This function uses peco+tree like 'cdp', but opens" - echo -e " your editor on the selected file(s). After you exit" - echo -e " your editor(s), you are returned to peco where you left" - echo -e " off." - echo -e " - ched:" - echo -e " Like chsh but for your editor (EDITOR env). A list" - echo -e " from which you can choose an installed editor" - echo -e " (CLI or GUI) is shown." - echo -e " - cdf:" - echo -e " Use fzf to find a file and then cd to its location." - echo -e " - cdp:" - echo -e " Similar to 'cdf' but uses tree+peco for the query." - echo -e " - ldrc:" - echo -e " Edits this file and sources it, similarly to shrc." - echo -e " - daisy_init:" - echo -e " Alias for directly sourcing this file from any" - echo -e " LACKADAISICAL binary. You may use this yourself." - echo -e " - daisy_cbin:" - echo -e " Contains the name of the current LACKADAISICAL" - echo -e " binary being run." - echo -e " -*daisy_enc:" - echo -e " Converts a file/stdin to a base64 block that can be" - echo -e " decoded by passing the output(s) to daisy_dec." - echo -e " - *_multi:" - echo -e " A version of daisy_enc that runs encodes multiple" - echo -e " files and outputs daisy_base64_data blocks to a file" - echo -e " or stdout." - echo -e " -*daisy_dec:" - echo -e " Converts daisy_base64_data blocks back to the form" - echo -e " it was in originally." - echo -e " - *_multi:" - echo -e " A version of daisy_dec that runs on multiple input" - echo -e " blocks that are either stored in a file or stdin." - echo -e "" - echo -e "===================================================================" - echo -e "" - echo -e "To uninstall LACKADAISICAL, simply remove the source line from your" - echo -e "shell RC, and reload it. This does not remove the files!" - echo -e "" - echo -e "To read this notice again, call the function 'daisy_help'." - echo -e "" - echo -e "===================================================================" +# Help function, courtesy of Google Gemini +function daisy_help() { + local target_tool="$1" + local file="README.md" # Updated filename - IFS="$OLD_IFS" + # 1. Extract the block between the new headers + sed -n '/--- BEGIN OF DAISY HELP ---/,/--- END OF DAISY HELP ---/{//!p;}' "$file" | \ + + if [ -z "$target_tool" ]; then + # If no argument, print the whole help text + cat + else + # 2. Parse specific tool + awk -v query="$target_tool" ' + BEGIN { found=0; printing=0 } + + # Match lines defining tools (e.g., " - calm:" or " - bak/unbak:") + $0 ~ /^[[:space:]]*- / { + printing=0 # Stop printing previous tool + + # Clean the line to get the "signature" + # " - bak/unbak:" becomes "bak/unbak" + sig = $0 + sub(/^[[:space:]]*- /, "", sig) + sub(/:[[:space:]]*$/, "", sig) + + # Check for exact match OR match within a slash-separated list + # This handles "bak", "unbak", and "daisy_alias" + split(sig, names, "/") + + is_match = 0 + if (sig == query) is_match = 1 + else { + for (i in names) { + if (names[i] == query) { is_match = 1; break } + } + } + + if (is_match) { + printing=1 + found=1 + print $0 # Print the header line (e.g., " - bak/unbak:") + next + } + } + + # Print description lines if we are in a "found" block + printing { + # Stop if we hit the start of the NEXT tool + if ($0 ~ /^[[:space:]]*- /) { printing=0; next } + print + } + + END { + if (found == 0) { + print "Tool '"'"'" query "'"'"' not found in README.md." + } + } + ' + fi +} + +# Courtesy of Google Gemini +daisy_list() { + local file="README.md" + + echo "Available LACKADAISICAL commands:" + + # Extract block -> Find tool lines -> Clean formatting -> Print + sed -n '/--- BEGIN OF DAISY HELP ---/,/--- END OF DAISY HELP ---/{//!p;}' "$file" | \ + awk ' + /^[[:space:]]*- / { + # Remove indentation and "- " + sub(/^[[:space:]]*- /, ""); + # Remove trailing ":" + sub(/:[[:space:]]*$/, ""); + print " " $0 + } + ' | sort }