Pull in scripts

This commit is contained in:
Daniel Flanagan 2023-09-05 13:52:52 -05:00
parent bfd0952247
commit 838c330359
Signed by: lytedev
GPG key ID: 5B2020A0F9921EF4
91 changed files with 1332 additions and 3 deletions

8
bin/? Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env fish
echo "Keys you never remember:"
echo
echo "C-t fuzzy find a file or directory to insert into your command"
echo "C-g fuzzy find a directory to cd to"
# https://github.com/lotabout/skim/blob/master/shell/key-bindings.fish

2
bin/N Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env bash
fn="${1}"; shift; nf "${fn}.md" "$@"

5
bin/archive Executable file
View file

@ -0,0 +1,5 @@
#!/usr/bin/env bash
archive_name="$(basename "${1}").tar.zstd"
tar --zstd -cvf "${archive_name}" "${@}"
echo "Archive created at: ${archive_name} "

6
bin/archupdate Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
yay -Syu --nodiffmenu --nocleanmenu --noeditmenu
# TODO: update kernel with a flag?
# yes | pacman -Syu && kexec -l --initrd=/boot/initramfs-linux.img /boot/vmlinuz-linux && kexec -e

21
bin/at Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env bash
usage() {
echo "at - waits until after the specified datetime"
echo "Usage:"
echo " at <DATETIME> && command..."
echo
echo "Examples:"
echo " at 15:00:00 && echo \"it is 3 o'clock\""
}
[[ -z "$1" ]] && { echo "Error: No DATE argument provided." >&2; usage; exit 1; }
d="$(date -d "${@}" +%s)"
while [[ "$d" -ge "$(date +%s)" ]]; do
_dt=$((d - $(date +%s)))
days=$((_dt / 86400))
echo -ne "\rTime Remaining: ${days}d $(date -u --date @$((_dt)) +%H:%M:%S) ";
sleep 0.1
done
exit 0

5
bin/bp Executable file
View file

@ -0,0 +1,5 @@
#!/usr/bin/env sh
printf '\e[?2004h'
printf '\e[?2004l'
echo bp off

90
bin/check-domain-availability Executable file
View file

@ -0,0 +1,90 @@
#!/usr/bin/env bash
# TODO:
# + trap exit signals to cleanup all temp files and cancel all jobs
# + run in batches to prevent spawning way too many processes
# + detect when piping into another application and suppress colors?
# + temp file control (or none for no disk space)?
# + command line options or env vars?
# + --tlds "com,net,org"
# + --max-concurrent-whois-jobs
# + --avail-regex and --timeout-regex
# suggested usage: ./check_domain | tee /tmp/chkdmn && sort /tmp/chkdmn
# constants
AVAIL_REGEX='^No match|^NOT FOUND|^Not fo|AVAILABLE|^No Data Fou|has not been regi|No entri'
TIMEOUT_REGEX='^Timeout'
COLOR_RESET="\x1b[0m" COLOR_GREEN="\x1b[32m"
COLOR_YELLOW="\x1b[33m"
COLOR_RED="\x1b[31m"
TLDS=( \
'.com' '.net' '.org' '.eu' '.in' '.it' '.sk' '.ac' '.ae' '.af' '.ag' '.al' \
'.am' '.as' '.at' '.ax' '.be' '.bi' '.bo' '.by' '.bz' '.cc' '.cd' '.cf' '.cg' \
'.ch' '.ci' '.cl' '.cm' '.cn' '.co' '.cr' '.cx' '.cz' '.dk' '.dm' '.do' '.ec' \
'.ee' '.es' '.fi' '.fm' '.fo' '.ga' '.gd' '.gf' '.gg' '.gl' '.gp' '.gq' '.gr' \
'.gs' '.gt' '.gy' '.hk' '.hm' '.hn' '.ht' '.id' '.im' '.in' '.io' '.ir' '.is' \
'.je' '.ke' '.kg' '.kz' '.la' '.lc' '.li' '.lt' '.lu' '.lv' '.ly' '.me' '.mg' \
'.mk' '.ml' '.mn' '.mq' '.ms' '.mu' '.mw' '.mx' '.na' '.ne' '.ng' '.nl' '.nu' \
'.nz' '.pe' '.ph' '.pk' '.pl' '.pr' '.pt' '.pw' '.qa' '.ro' '.rs' '.ru' '.rw' \
'.sb' '.sc' '.sd' '.se' '.sh' '.si' '.sl' '.sr' '.st' '.su' '.sx' '.sg' '.tk' \
'.tl' '.to' '.tv' '.tw' '.ug' '.vc' '.ve' '.vg' '.vn' '.vu' '.ws' \
)
# check dependencies
if command -v whois >/dev/null 2>&1; then
:
else
echo "You need to install whois before proceeding!"
exit 2
fi
# check arguments
if [ "$#" == "0" ]; then
echo "You need to supply at least one argument!"
exit 1
fi
# main function
check_domain() {
local tmp
local domain
if [ "$#" == "0" ]; then
echo "No domain specified."
return
fi
domain="$1"
# create a unique temporary file
tmp=$(mktemp "${domain}_XXX")
# dump whois output into temp file
whois "$domain" > "$tmp" 2>&1
# check contents and output appropriately
if grep -E -q "$AVAIL_REGEX" "$tmp" > /dev/null 2>&1; then
echo -e "$COLOR_GREEN$domain / probably available$COLOR_RESET"
elif grep -E -q "$TIMEOUT_REGEX" "$tmp" > /dev/null 2>&1; then
echo -e "$COLOR_YELLOW$domain / timed out$COLOR_RESET"
else
echo -e "$COLOR_RED$domain / unavailable$COLOR_RESET"
fi
# cleanup
rm "$tmp"
}
# iterate all provided domain names combined with all TLDs and check them
# concurrently
elements=${#TLDS[@]}
while (( "$#" )); do
for (( i=0;i<elements;i++ )); do
check_domain "$1${TLDS[${i}]}" &
done
shift
done
wait

17
bin/check-port Executable file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env bash
if [[ $1 = t ]] || [[ $1 = tcp ]] || \
[[ $1 = T ]] || [[ $1 = TCP ]]; then
echo "TCP is the default. You don't need to specify it." >&2
exit 1
fi
if [[ $1 = u ]] || [[ $1 = udp ]] || \
[[ $1 = U ]] || [[ $1 = UDP ]]; then
shift
set -x
sudo nmap -sU "$1" -p "$2"
else
set -x
nmap "$1" -p "$2"
fi

15
bin/clip Executable file
View file

@ -0,0 +1,15 @@
#!/usr/bin/env bash
# TODO: detect MIME type?
# TODO: figure out how/why these programs "wait" -- can a `clip-once` script exist building on this?
# wl-copy `-o`, xclip `-l 1`?
if [ "$(uname)" == "Linux" ]; then
if is_wayland; then
wl-copy -n "$@"
else
xclip -i -sel c "$@"
fi
elif [ "$(uname)" == "Darwin" ]; then
pbcopy "$@"
fi

29
bin/clipshot Executable file
View file

@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -x
umask 077
d="$(date +"%Y-%m-%d_%H-%M-%S")"
fn="$SCROTS_PATH/clipshot_$d.png"
mkdir -p "$SCROTS_PATH"
dim="$(slurp -d -b \#00000066 -c \#ffffffff)"
if [ "$?" -eq 0 ]; then
grim -g "$dim" - | wl-copy -t image/png
wl-paste -n > "$fn"
echo "$fn"
else
exit 1
fi
# TODO: implement for X and other OSs?
# pkill unclutter
# sleep 0.1
# import "$fn"
# < "$fn" xclip -t image/png -i -selection clipboard
# < "$fn" xclip -t image/png -i -selection primary
# < "$fn" xclip -t image/png -i -selection secondary
# < "$fn" xclip -t image/png -i -selection buffer-cut
# unclutter &
# echo "$fn"

21
bin/copy-git-forge-url Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env sh
usage() {
echo "copy-git-forge-url <$FILE>[#L$LINE_NUMBERS]"
echo " Copies a link to the git forge's web interface for the current branch to the clipboard"
echo
echo " Examples:"
echo " \$ copy-git-forge-url readme.md#L12"
}
if [ "$#" -lt 1 ]; then
usage
exit 1
fi
url="$(gitforge-url.ts "$1")"
case "$(uname)" in
Linux*) echo "$url" | clip;;
Darwin*) echo "$url" | clip;;
*) echo "OS not supported"; exit 1;
esac

15
bin/countdown Executable file
View file

@ -0,0 +1,15 @@
#!/usr/bin/env bash
[[ $# -lt 1 ]] && { echo "No argument provided." >&2 ; exit 1; }
d=$(($(date +%s) + $1));
echo "Countdown started at $(date)"
while [[ "$d" -ge "$(date +%s)" ]]; do
_dt=$((d - $(date +%s)))
days=$((_dt / 86400))
echo -ne "\r${days}d $(date -u --date @$((_dt)) +%H:%M:%S) ";
sleep 0.1
done
echo -ne "\rCountdown finished $(date)\n"

3
bin/dns Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
getent hosts "$@"

0
bin/dns-cleaner Executable file
View file

22
bin/dns-deleter Executable file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env bash
hostname="${1}"; shift || {
echo "No hostname arg to delete provided."
exit 1
}
API="https://api.netlify.com/api/v1"
TOKEN="$(pass netlify | grep -i token | tr -d ' ' | cut -d ':' -f 2)"
counter=0
curl -sL "$API/dns_zones/lyte_dev/dns_records?access_token=$TOKEN" | \
jq -r '.[] | select(.hostname=="'"$hostname"'") | .hostname+": "+.id' | \
while read -r l; do
counter=$((counter+1))
ID="$(echo $l | awk '{print $2}')"
URL="$API/dns_zones/lyte_dev/dns_records/$ID?access_token=$TOKEN"
curl -vvv -X DELETE -sL "$URL" 2>&1 | grep 'ratelimit-remaining' &
echo "counter: $counter"
jq 'del(.[] | select(.id == "'$ID'"))' /tmp/zone.json > /tmp/zone2.json
mv /tmp/zone2.json /tmp/zone.json
[ $counter -gt 450 ] && break
done
wait

11
bin/dns-deleter-matching Executable file
View file

@ -0,0 +1,11 @@
#!/usr/bin/env bash
API="https://api.netlify.com/api/v1"
TOKEN="$(pass netlify | grep -i token | tr -d ' ' | cut -d ':' -f 2)"
while read -r l; do
set -x -e
ID="$(echo $l | awk '{print $2}')"
URL="$API/dns_zones/lyte_dev/dns_records/$ID?access_token=$TOKEN"
curl -X DELETE -sL "$URL"
done
wait

View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
command -v git >/dev/null 2>&1 || { echo "git not installed"; exit 1; }
command -v fish >/dev/null 2>&1 || { echo "fish not installed"; exit 2; }
mkdir -p "$HOME/.config"
git clone https://git.lyte.dev/lytedev/dotfiles.git "$HOME/.config/lytedev-dotfiles"
exec "$HOME/.config/lytedev-dotfiles/common/bin/dotfiles-setup"

56
bin/dotfiles-init Executable file
View file

@ -0,0 +1,56 @@
#!/usr/bin/env bash
export dfp
export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
export ENV_PATH="$XDG_CONFIG_HOME/lytedev-env"
export CURDIR
mkdir -p "$ENV_PATH"
mkdir -p "$XDG_CONFIG_HOME"
dfp="$(realpath "$(dirname "$0")"/../..)"
# may not be running from inside the dotfiles repo, may have been curl'd down solo, so we need to check
if [[ ! -d "$dfp/.git" ]]; then
echo "Not running from inside the dotfiles git repo, so we need to download it first!"
# each os needs instructions to install git, then we can clone the repo and proceed
if ! command -v git; then
if head /etc/os-release --lines 1 | grep 'Arch Linux' > /dev/null 2>&1; then
if [[ "$EUID" -ne 0 ]]; then
if ! command -v sudo; then
echo "Error: No sudo command available to try and install 'git'"
exit 1
else
sudo pacman -Sy --needed git
fi
else
pacman -Sy --needed git
fi
fi
fi
dfp="$XDG_CONFIG_HOME/lytedev-dotfiles"
git clone https://git.lyte.dev/lytedev/dotfiles.git "$dfp"
fi
# auto-link any OS-specific environments
if head /etc/os-release --lines 1 | grep 'NixOS$' > /dev/null 2>&1; then
ln -s "$dfp/os/linux/nix" "$ENV_PATH/os-linux-nix" > /dev/null 2>&1
elif head /etc/os-release --lines 1 | grep 'Arch Linux' > /dev/null 2>&1; then
ln -s "$dfp/os/linux/arch" "$ENV_PATH/os-linux-arch" > /dev/null 2>&1
fi
# perform any pre-requisite setup (includes OS-specific setup scripts since we
# just included those)
for s in "$ENV_PATH"/*; do
f="$s/dotfiles-init.d.sh"
if [ -f "$f" ]; then
echo "dotfiles-init: Running $f..."
CURDIR="$s" "$f"
fi
done
# perform final dotfiles setup
echo "dotfiles-init: Running setup..."
"$dfp/common/bin/dotfiles-setup"
# TODO: setup personal files? (ssh keys, gpg keys, password stores, notes)
# these are probably best handled in a dotfiles-init.d.sh script in a particular layer

39
bin/dotfiles-link-environments Executable file
View file

@ -0,0 +1,39 @@
#!/usr/bin/env fish
has_command sk || begin
echo "sk not installed (skim fuzzy finder)"
exit 1
end
mkdir -p $ENV_PATH
function filter_existing_directory
while read -l line
test -d $DOTFILES_PATH/$line && echo $line
end
end
function reject_empty_lines
while read -l line
test $line = "" || echo $line
end
end
function link
while read -l line
set safe_fn (string replace -a / - $line)
echo "Linking $ENV_PATH/$safe_fn to $DOTFILES_PATH/$line"
rm -f $ENV_PATH/$safe_fn
ln -s $DOTFILES_PATH/$line $ENV_PATH/$safe_fn
end
end
cat $DOTFILES_PATH/common/envs |
filter_existing_directory |
sk --multi \
--prompt "Select applicable environments (multi-select w/ TAB): " \
--preview-window="up:50%:noborder" \
--preview="ls -la --color=always $DOTFILES_PATH/{}" |
string trim |
reject_empty_lines |
link

30
bin/dotfiles-make-env Executable file
View file

@ -0,0 +1,30 @@
#!/usr/bin/env bash
echo "Not implemented yet!"; exit 1
edfp="$ENV_PATH/$1"
mkdir -p "$edfp/"
mkdir -p "$edfp/.hidden/bash.d/"
mkdir -p "$edfp/bin/"
mkdir -p "$edfp/x/"
mkdir -p "$edfp/sway/waybar"
mkdir -p "$edfp/sway/config.d"
mkdir -p "$HOME/.bin/"
touches=(
"$edfp/bash"
"$edfp/x/init"
"$edfp/x/profile"
"$edfp/x/resources"
"$edfp/vim"
"$edfp/bspwm"
"$edfp/polybar"
"$edfp/app-launcher"
"$edfp/workdock"
)
for t in "${touches[@]}"; do
touch "$t"
done
chmod 700 -R "$edfp"

78
bin/dotfiles-setup Executable file
View file

@ -0,0 +1,78 @@
#!/usr/bin/env fish
# This script's purpose is to setup the dotfiles configuration for an existing
# and provisioned machine. For provisioning, see `./dotfiles-init`.
set dfp (realpath (dirname (status -f))/../..)
set lock_file $HOME/.using-lytedev-dotfiles.lock
if not test -f $lock_file
echo "This will delete existing files. Make sure you know what you're doing."
echo 'Are you sure you want to continue? [y/N]'
read response
set response (string lower $response)
if string match $response y
echo "agreed" > "$lock_file"
else
exit 1
end
end
set -q XDG_CONFIG_HOME || set XDG_CONFIG_HOME $HOME/.config
set h $HOME; set c $XDG_CONFIG_HOME
if test -d $c/lytedev-env
echo "Warning: no environment-specific configuration detected!"
end
function l -a dot -a target -d "Symlink a dotfile configuration file or directory"
if test -L $target || test -f $target || test -d $target
command rm -rf "$target"
end
# check if the directory that will contain the link exists
set -l d (dirname $target)
test -d $d || mkdir -p $d
ln -s (pwd)/$dot $target
echo Linked $dot to $target
end
pushd $dfp
test -d ~/.tmux/pluginx/tpm || \
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
l common/zellij $c/zellij
l common/tmux/conf $h/.tmux.conf
l common/bat $c/bat
l common/bash/rc $h/.bashrc
l common/wezterm $c/wezterm
l common/kitty $c/kitty
l common/weechat $h/.weechat
l common/scim/rc $h/.scimrc
l common/scim/lua $h/.scim/lua
l common/nnn $c/nnn
l common/kak $c/kak
l common/helix $c/helix
l common/gitui $c/gitui
l common/gpg/agent.conf $h/.gnupg/gpg-agent.conf
chmod og-rwx ~/.gnupg
l common/htop/rc $c/htop/htoprc
l common/kitty $c/kitty
l common/alacritty $c/alacritty
l common/pgcli $c/pgcli
l common/mutt/rc $h/.muttrc
l common/git/config $h/.gitconfig
l common/elixir/iex.exs $h/.iex.exs
l common/blender/userpref.blend $c/blender/2.93/config/userpref.blend
l common/lemonade/config.toml $c/lemonade.toml
l common/tig/rc $h/.tigrc
popd
for s in $c/lytedev-env/*/dotfiles-setup.d.fish
source $s $dfp $h $c
end
set -q ENV_PATH || set ENV_PATH $XDG_CONFIG_HOME/lytedev-env
set -q DOTFILES_PATH || set DOTFILES_PATH $XDG_CONFIG_HOME/lytedev-dotfiles
command rm -f $ENV_PATH/empty
ln -s $DOTFILES_PATH/common/empty-env $ENV_PATH/empty
echo "Dotfiles Installed! Don't forget to setup environments and change the user's shell as needed!"
exec fish

31
bin/dotfiles-setup-for-root Executable file
View file

@ -0,0 +1,31 @@
#!/usr/bin/env bash
if [[ $UID -ne 0 ]]; then
echo "Re-running with 'sudo -E'..."
sudo -E "$0" "$@"
exit
fi
dfp=$(cd "$(dirname "${BASH_SOURCE[0]}" )/../../" && pwd)
source "${dfp}/env/common/setup_helpers.bash"
cp "$dfp/apps/de/sway/dm-entry" "/usr/share/wayland-sessions/lsway.desktop"
links=(
# display manager files
"apps/de/sway/init" "/usr/bin/sway-lytedev"
# udev rules
# TODO: how does this work in nix?
"apps/udev-rules/gcadapter" "/etc/udev/rules.d/51-gcadapter.rules"
# tmpfiles
# TODO: does this even do anything anymore?
"apps/tmpfiles/disable-lid-wakeup" "/etc/tmpfiles.d/disable-lid-wakeup.conf"
# lightdm
"apps/de/gnome/gdm-tap-to-click" "/etc/dconf/db/gdm.d/06-tap-to-click"
)
_dotfiles_setup_run_setup "$HOME/.using-lytedev-etcfiles.lock" "${links[@]}"

3
bin/editscrot Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env sh
opener="$(command -v xdg-open 2>&1 >/dev/null && echo "xdg-open" || echo "open")"
exec nohup "$opener" "$NICE_HOME/img/scrots/$(ls -t "$NICE_HOME/img/scrots/" | head -n1)" >/dev/null 2>&1 &

72
bin/email-via-mailgun-smtp Executable file
View file

@ -0,0 +1,72 @@
#!/usr/bin/env bash
err() {
errpre=""
errpost=""
if test -t 1; then
ncolors=$(tput colors)
if test -n "$ncolors" && test "$ncolors" -ge 8; then
errpre="$(tput setaf 1)"
errpost="$(tput setaf 7)"
fi
fi
>&2 echo "${errpre}ERROR: $*${errpost}"; usage; exit 1
}
warn() {
pre=""
post=""
if test -t 1; then
ncolors=$(tput colors)
if test -n "$ncolors" && test "$ncolors" -ge 8; then
pre="$(tput setaf 3)"
post="$(tput setaf 7)"
fi
fi
>&2 echo "${pre}WARNING: $*${post}"
}
usage() { >&2 cat <<USAGEDOC
usage:
email-via-mailgun-smtp [recipient] [subject] [username] [password] <<< 'Hello, world!'
email-via-mailgun-smtp will read all the input from stdin and use the contents as the body of the email.
recipient will default to DEFAULT_MAILGUN_SMTP_RECIPIENT if not set
username will default to DEFAULT_MAILGUN_SMTP_USERNAME if not set
password will default to DEFAULT_MAILGUN_SMTP_PASSWORD if not set
subject will default to DEFAULT_MAILGUN_SMTP_SUBJECT if not set
USAGEDOC
}
recipient="${1:-$DEFAULT_MAILGUN_SMTP_RECIPIENT}"; shift
[[ -z $recipient ]] && err 'No recipient provided.'
subject="${1:-$DEFAULT_MAILGUN_SMTP_SUBJECT}"; shift
[[ -z $subject ]] && warn 'No subject provided. Leaving blank.'
username="${1:-$DEFAULT_MAILGUN_SMTP_USERNAME}"; shift
[[ -z $username ]] && err 'No username provided.'
password="${1:-$DEFAULT_MAILGUN_SMTP_PASSWORD}"; shift
[[ -z $password ]] && err 'No password provided.'
warn "Reading email body from stdin..."
body=""
while read -r line; do
body="${body}\n${line}"
done
[[ -z $body ]] && err 'Body was blank.'
echo "Recipient: $recipient"
>&2 echo "Finished reading body. Sending email..."
swaks --auth \
--server smtp.mailgun.org \
--au "$username" \
--ap "$password" \
--to "$recipient" \
--h-Subject: "$subject" \
--body "$body"

5
bin/emoji Executable file
View file

@ -0,0 +1,5 @@
#!/usr/bin/env sh
r="$(< "$HOME/.emoji.txt" sk --height 40%)"
echo "$r" | awk '$0=$1' | tr -d '\n' | clip
echo "Copied $r emoji to your clipboard"

6
bin/ezln Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
SOURCE="$(realpath "$1")" # this one exists
DEST="$(realpath -m "$2")" # this is the link to what exists
mkdir -p "$(dirname "$2")"
ln -s "$SOURCE" "$DEST"

6
bin/field Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env sh
has_command gawk || { echo "No gawk." >&2 ; exit 1; }
index="${1:-1}"
[ "$#" -lt 1 ] || shift
gawk "$@" '{print $'"${index}"'}'

4
bin/getip Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env sh
curl -s --connect-timeout 3 --max-time 10 --retry 5 --retry-delay 0 \
--retry-max-time 40 "$@" ifconfig.co/json | jq

8
bin/git-authors Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
git ls-tree -r -z --name-only HEAD -- "$1" \
| xargs -0 -n1 git blame --line-porcelain HEAD \
| grep "^author " \
| sort \
| uniq -c \
| sort -nr

73
bin/gitforge-url.ts Executable file
View file

@ -0,0 +1,73 @@
#!/usr/bin/env -S deno run --allow-read --allow-run --allow-net
import * as path from "https://deno.land/std@0.181.0/path/mod.ts";
// output the best guess URL for viewing the file at the current git revision in
// the git forge's web interface
// TODO: --help, -h menu
const file = Deno.args[0];
if (!file) {
console.error("No file argument provided");
Deno.exit(1);
}
async function cmdOutput(cmd: string[]) {
return new TextDecoder().decode(
await Deno.run({
cmd: cmd,
stdout: "piped",
})
.output(),
).trim();
}
type ForgeType = "gitlab" | "github" | "gitea";
function getForgeType(hostname: string): ForgeType {
if (hostname == "git.lyte.dev") {
return "gitea";
} else if (hostname.endsWith("github.com")) {
return "github";
} else {
return "gitlab";
}
}
function getUrl(repoRoot: string, remote: string, commit: string) {
try {
// try http remote
console.log(new URL(remote));
throw new Error("HTTP(S) remotes not implemented");
} catch {
const hostname = remote.split("@").slice(-1)[0].split(":")[0];
const forgeType = getForgeType(hostname);
let repoPath = remote.split(":")[1];
if (repoPath.endsWith(".git")) {
repoPath = repoPath.slice(0, -4);
}
let fileRepoPath = path.resolve(file);
if (fileRepoPath.startsWith(repoRoot)) {
fileRepoPath = fileRepoPath.slice(repoRoot.length + 1); // for the trailing slash
} else {
throw new Error(`File ${fileRepoPath} is not in repo at ${repoRoot}`);
}
switch (forgeType) {
case "gitlab":
return `https://${hostname}/${repoPath}/-/blob/${commit}/${fileRepoPath}`;
case "gitea":
return `https://${hostname}/${repoPath}/src/commit/${commit}/${fileRepoPath}`;
case "github":
return `https://${hostname}/${repoPath}/blob/${commit}/${fileRepoPath}`;
}
}
}
// TODO: cd to dir
const repoRoot = await cmdOutput(["git", "rev-parse", "--show-toplevel"]);
const remote = await cmdOutput(["git", "remote", "get-url", "origin"]);
const commit = await cmdOutput(["git", "rev-parse", "HEAD"]);
const url = getUrl(repoRoot, remote, commit);
console.log(url);

11
bin/glancepath Executable file
View file

@ -0,0 +1,11 @@
#!/usr/bin/env -S awk -f
{
split(substr($0, 2), p, "/");
for (k in p) {
if (k == length(p)) {
printf "/%s", p[k]
} else {
printf "/%.3s", p[k]
}
}
}

21
bin/good-morning Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env fish
# create a messages file for subscripts to write to or manipulate for ending
# output
set message_file (mktemp)
for f in (fd good-morning.d.fish $HOME/.config/lytedev-env --max-depth 2)
# run scripts for any linked environments with a hooked script
source $f $message_file
end
# output the messages file's contents
echo
command cat $message_file
echo
# since this script almost always runs in its own window which dies after
# finishing, give the user a chance to read the output
echo "When you're ready, hit enter to finish!"
read

4
bin/has_command Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env sh
[ "$#" -lt 1 ] && { echo "No arguments provided" >&2 ; exit 1; }
command -v "$1" >/dev/null 2>&1

View file

@ -0,0 +1,21 @@
#!/usr/bin/env fish
set profile_dirs $HOME/.mozilla/firefox/*.dev-edition-default $HOME/.mozilla/firefox/*.default-release
if test (uname) = Darwin
set profile_dirs $HOME/Library/Application\ Support/Firefox/Profiles/*.dev-edition-default $HOME/.mozilla/firefox/*.default-release
end
for p in $profile_dirs
mkdir -p $p/chrome
set user_chrome_css_file $p/chrome/userChrome.css
echo '/* Generated by '(status -f)' -- do not edit manually! */' > $user_chrome_css_file
cat $DOTFILES_PATH/common/firefox/userChrome.d.css >> $user_chrome_css_file
echo >> $user_chrome_css_file
for file_part in $ENV_PATH/*/firefox/userChrome.d.css
cat $file_part >> $user_chrome_css_file
echo >> $user_chrome_css_file
end
echo Built $user_chrome_css_file
end
echo Make sure you set 'toolkit.legacyUserProfileCustomizations.stylesheets' to true in about:config

4
bin/is_wayland Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
exit 0
# loginctl show-session "$(loginctl | grep "$(whoami)" | head -n 1 | field 1)" -p Type | grep -i wayland >/dev/null

8
bin/k8s-yaml-diff Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
[ "$#" -lt 2 ] && echo "Need two filenames." && exit 1
f1="$1"; shift
f2="$1"; shift
nvim -d <(k8s-yaml-sort "$f1") <(k8s-yaml-sort "$f2")

17
bin/k8s-yaml-sort Executable file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env bash
[ "$#" -lt 1 ] && echo "Need a filename." && exit 1
< "$1" yq -s . | jq -S '
sort_by(.metadata.name) |
sort_by(.kind) |
.[] | .spec.template.spec.containers |=
if . == null then empty
else
map(
if . == null then empty
else .env |= sort_by(.name)
| .volumeMounts |= sort_by(.name)
end
)
end
'

3
bin/keyrepeat Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
xset r rate 250 80

9
bin/kubeline Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env sh
c="$(kubectl config current-context | tr -d "\n")"
if [ -n "$c" ]; then
printf "%s" "$c"
fi
a="$(kubectl config view --minify --output 'jsonpath={..namespace}')"
if [ -n "$a" ]; then
printf ".%s" "$a"
fi

9
bin/kubfc Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env sh
kubectl config get-contexts --no-headers | \
uniq | \
sort | \
tr -s ' ' | \
sed -E 's/^\*?[[:space:]]*//g' | \
cut -d ' ' -f1 | \
sk | \
xargs -I{} kubectl config use-context '{}'

12
bin/kubfn Executable file
View file

@ -0,0 +1,12 @@
#!/usr/bin/env sh
has_command kubectl || {
echo "kubectl command not found"
exit 1
}
kubectl get namespaces --show-labels | \
uniq | \
sort | \
cut -d ' ' -f1 | \
sk | \
xargs -I{} kubectl config set-context --current --namespace='{}'

19
bin/launch Executable file
View file

@ -0,0 +1,19 @@
#!/usr/bin/env bash
LAUNCHER_HISTORY_FILE="$HOME/.local/share/lytelaunch/launch.log"
mkdir --parents "$(dirname "$LAUNCHER_HISTORY_FILE")"
touch "$LAUNCHER_HISTORY_FILE"
app="$(
< "$LAUNCHER_HISTORY_FILE" \
awk 'NF{NF--};1' | \
cat - <(dmenu_path) | \
sort | uniq -c | sort -nr | \
sd -fm '^\s+' '' | \
cut -d' ' -f2- | \
grep "\S" | \
sk
)"
# if no app is selected, just exit
test -z "$app" && exit 1
echo "$app $(date +%s)" >> "$LAUNCHER_HISTORY_FILE"
echo "$app"

10
bin/linewise Executable file
View file

@ -0,0 +1,10 @@
#!/usr/bin/env bash
if [[ -n "${1+x}" ]]; then
while read -r line; do
<<< "${line}" "$@"
done
else
echo "No reader program provided."
exit 1
fi

5
bin/maybe_source_env_file Executable file
View file

@ -0,0 +1,5 @@
#!/usr/bin/env bash
f="$1"; shift
[ -f "$f" ] && source "$f" "$@"
true

3
bin/nd Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
fn="${1}"; shift; N "$(date +%Y-%m-%d)_${fn}" "$@"

7
bin/nf Executable file
View file

@ -0,0 +1,7 @@
#!/usr/bin/env sh
SUBDIR="${2:-./}"
mkdir -p "$NOTES_PATH/$SUBDIR"
cd "$NOTES_PATH/$SUBDIR" || exit 1
"$EDITOR" "$NOTES_PATH/$SUBDIR/$1"
cd - || exit 1

2
bin/note Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env sh
fn="${1}"; shift; N "$(date +%Y-%m-%d)_${fn}" "$@"

8
bin/nsync Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
# TODO: warn on merge conflicts?
cd "${NOTES_PATH}" || exit
git add -A
git commit -m Updates
git fetch && git merge origin/master && git push
cd - || exit

2
bin/nvimdiff Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env sh
nvim -d "$@"

21
bin/open-in-git-forge Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env sh
usage() {
echo "open-in-git-forge <$FILE>[#L$LINE_NUMBERS]"
echo " Opens the URL in your browser to the git forge's web interface for the current branch for $FILE"
echo
echo " Examples:"
echo " \$ open-in-git-forge readme.md#L12"
}
if [ "$#" -lt 1 ]; then
usage
exit 1
fi
url="$(gitforge-url.ts "$1")"
case "$(uname)" in
Linux*) xdg-open "$url";;
Darwin*) open "$url";;
*) echo "OS not supported"; exit 1;
esac

18
bin/optimize-photo-for-web Executable file
View file

@ -0,0 +1,18 @@
#!/usr/bin/env bash
mogrify \
-filter Triangle \
-define filter:support=2 \
-resize 2000x2000\> \
-unsharp 0.25x0.08+8.3+0.045 \
-dither None \
-posterize 136 \
-quality 82 \
-define jpeg:fancy-upsampling=off \
-define png:compression-filter=5 \
-define png:compression-level=9 \
-define png:compression-strategy=1 \
-define png:exclude-chunk=all \
-interlace none \
-colorspace sRGB \
"$1"

6
bin/pass-migrate-to-pass-otp Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env fish
set entry $argv[1]
set otp_secret (pass $entry | awk -F': ' '/^otp/{gsub(/\s/,"",$2);print $2}')
set otp_uri "otpauth://totp/totp-secret?secret=$otp_secret&issuer=$entry"
echo $otp_uri | pass otp append $entry

41
bin/pipeline Executable file
View file

@ -0,0 +1,41 @@
#!/usr/bin/env sh
SAVED_PIPELINE_DIR="$DOTFILES_PATH/env/common/data/pipelines"
mkdir -p "$SAVED_PIPELINE_DIR"
if [ -n "${1+x}" ]; then
pdir="$SAVED_PIPELINE_DIR/$1"; shift
mkdir -p "$pdir"
if [ -z ${1+x} ]; then
td="$(mktemp -p "$pdir" -d "tmp_pipeline.XXXXXXXX")"
# shellcheck disable=SC2064
trap "rm -rf '$td'" EXIT
else
td="$pdir/$1"; shift
mkdir -p "$td"
fi
transform="$pdir/transform"
else
td="$(mktemp --tmpdir -d pipeline.XXXXXXXX)"
transform="$td/transform"
# shellcheck disable=SC2064
trap "rm -rf '$td'" EXIT
fi
[ ! -e "$transform" ] && \
printf "#!/usr/bin/env bash\n# you must save this buffer manually\n# for %s\n
base64" "${td}" > "$transform"
in="$td/in"; [ -n "${1+x}" ] && in="${1}" && shift
out="$td/out"; [ -n "${1+x}" ] && out="${1}" && shift
# TODO: if no logging, log="/dev/null"
log="$td/log"
touch "$log"
chmod +x "$transform"
# TODO: saved inputs?
echo "Hello World" > "$in"
env PIPELINE_IN="$in" PIPELINE_TRANSFORM="$transform" PIPELINE_OUT="$out" nvim --cmd "source $DOTFILES_PATH/apps/neovim/scripts/pipeline.vim"

12
bin/poll Executable file
View file

@ -0,0 +1,12 @@
#!/usr/bin/env fish
# make sure our stuff gets loaded so aliases will work
source ~/.config/fish/config.fish
while true
clear
sleep 2 &
echo (tput setaf 0)(date) polled (tput setaf 4)"'"$argv"'"(tput setaf 7)
eval $argv
wait
end

10
bin/pr-for-commit Executable file
View file

@ -0,0 +1,10 @@
#!/usr/bin/env sh
GITHUB_UPSTREAM="$(git remote -vv | awk '{$0=$2}')"
git log --merges --ancestry-path --oneline "$1"..master \
| grep -i 'pull request' \
| tail -n1 \
| awk '{$0=$5}' \
| cut -c2- \
| xargs -I % open https://github.com/"$GITHUB_UPSTREAM"/"${PWD##*/}"/pull/%

4
bin/readme.md Normal file
View file

@ -0,0 +1,4 @@
This directory contains scripts and stuff I want in my PATH whether NixOS, some
other Linux, or macOS.
For OS-specific executables, see the OS-specific subdirectories.

11
bin/remote Executable file
View file

@ -0,0 +1,11 @@
#!/usr/bin/env moon
arg_spec = {
{"target", "REMOTE_MACHINE", "remote"}
{"mpr", "MOSH_PORT_RANGE", "60000:61000"}
{"sargs", "SSH_ARGS", "-XY"}
{"margs", "MOSH_ARGS", ""}
}
args = {v[1], os.getenv(v[2]) or arg[i] or v[3] for i, v in ipairs(arg_spec)}
os.execute "mosh -p '#{args.mpr}' '#{args.target}' --ssh='ssh #{args.sargs}' #{args.margs}"

23
bin/resource-usage Executable file
View file

@ -0,0 +1,23 @@
#!/usr/bin/env bash
# TODO: radeontop can continuously dump to a file, would be fast to just keep
# last line and have this run in the background
gpu_usage="$(radeontop -l 1 -d - | rg --color never -o "gpu (\d+.\d+)" -r '$1')"
gpu_temp="$(sensors | rg 'amdgpu.*mem:\s+\+(\d+\.\d+)' --multiline-dotall --multiline -o -r '$1')"
# NOTE: this is all cpu usage since boot:
# cpu_usage_data_snapshot="$(cat /proc/stat | head -n 1 | cut -d ' ' -f 2- | sd '^\s+' '')"
# function cpu_usage_data() {
# echo "$cpu_usage_data_snapshot"
# }
# cpu_usage="$(bc -l <<< "100-(100*($(cpu_usage_data | awk '{printf $4}').0/$(cpu_usage_data | sd " " "+" | bc).0))")"
mpstat_samples=2
mpstat_sample_seconds=1
cpu_idle="$(mpstat --dec=2 "$mpstat_sample_seconds" "$mpstat_samples" | tail -n 1 | field 12)"
cpu_usage="$(echo "100.0-$cpu_idle" | bc -l)"
cpu_temp="0.0"
printf "GPU [USAGE: %6.2f%%] [THERMALS: %6.2f°C]\n" "$gpu_usage" "$gpu_temp"
printf "CPU [USAGE: %6.2f%%] [THERMALS: %6.2f°C]\n" "$cpu_usage" "$cpu_temp"

3
bin/restartbar Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
stopbar && startbar &

3
bin/s Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
N _scratch

3
bin/scn Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env sh
EDITOR="sc-im" nf "$@"

6
bin/screenshot Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
SCROT_DIR="$NICE_HOME/img/scrots"
mkdir -p "$SCROT_DIR/"
FILENAME="$SCROT_DIR/screenshot_$(date +%Y-%m-%d_%H-%M-%S).png"
grim -t png "$@" "${FILENAME}" >/dev/null && echo "Saved screenshot to: ${FILENAME}"

3
bin/script-opts Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
# TODO: helper for taking a data structure and building bash args?

19
bin/scrup Executable file
View file

@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -x
remote_dir="scrots"
url_prefix="https://files.lyte.dev/$remote_dir"
u="$(uuid -v4)"
d="$(date +%Y-%m-%d_%H-%M-%S)"
fn="$(clipshot)"
if [ $? -eq 0 ]; then
echo "Scrot captured. Uploading..."
upload "${fn}" "scrup-$u-$d.png" "$remote_dir"
echo "$url_prefix/scrup-$u-$d.png" | clip
notify-send "Scrot uploaded. URL in clipboard."
else
exit 1
fi

4
bin/scwd Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env sh
addon=""; [ -n "$1" ] && addon="-${1}"
echo "${PWD}" > "${DOTFILES_PATH}/.cwd${addon}.tmp"

8
bin/setbg Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
index="${2}"
wp_file="${HOME}/.wallpaper${index}"
rm -f "${wp_file}"
echo "Setting ${1} as ${wp_file}"
ln -s "$(realpath "${1}")" "${wp_file}"
"${HOME}/.fehbg"

8
bin/simple-otp Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
# TODO: check for oathtool
key="$1"; shift
args=("$@")
oathtool --totp=sha1 -b "$key" "${args[@]}"

7
bin/source_if_exists Executable file
View file

@ -0,0 +1,7 @@
#!/usr/bin/env bash
[ "$#" -lt 1 ] && { echo "No arguments provided" >&2 ; exit 1; }
# shellcheck disable=SC1090
f="$1"; shift
{ [ -f "$f" ] && source "$f" "$@"; } || { echo "$f does not exist" >&2 ; exit 3; }

3
bin/startbar Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env sh
"${DOTFILES_PATH}/apps/de/polybar/run"

8
bin/stopbar Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
# TODO: get the proper monitor!
BAR_MONITOR="$(polybar --list-monitors | tail -n 1 | sed -n 's/^\s*\(.*\):.*$/\1/p')"
bspc config -m "${BAR_MONITOR}" bottom_padding "0"
bspc config -m "${BAR_MONITOR}" top_padding "0"
killall -q polybar
while pgrep -x polybar >/dev/null; do sleep 1; done

17
bin/sw Executable file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env bash
d="$(date +%s)"
_dt=$(($(date +%s) - d))
echo "Stopwatch started $(date)"
trap 'echo -ne "\nStopwatch stopped at $(date)\n" && exit 0' SIGINT
while true; do
_dt=$(($(date +%s) - d))
days=$((_dt / 86400))
echo -ne "\r${days}d $(date -u --date @$((_dt)) +%H:%M:%S) "
sleep 0.1
done
# TODO: add "lap" capabilities?

2
bin/tdf Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env fish
tmux-lyte-session dotfiles $DOTFILES_PATH

3
bin/tenv Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env sh
d="$(command ls "$ENV_PATH" | sk)" && \
tmux-lyte-session "env-$d" "$ENV_PATH/$d"

25
bin/terminal-rendering-test Executable file
View file

@ -0,0 +1,25 @@
#!/usr/bin/env bash
# sources:
# https://askubuntu.com/questions/528928/how-to-do-underline-bold-italic-strikethrough-color-background-and-size-i
# https://askubuntu.com/questions/27314/script-to-display-all-terminal-colors
indent=" "
padding=" "
reset="\e[0;39;49m"
for s in {0..8}; do # text styles
for t in {30..37}; do # text color
for b in {40..47}; do # background
echo -ne "${indent}\e[$s;$t;${b}m${padding}\\\e[$s;$t;${b}m${padding}${reset}"
done
echo
done
echo
done
echo -e "Emoji: 😱😍😬🎉"
echo -e "Possible Ligatures:"
echo -r " --> -> == != === ------> ** ++ |> <* := :: |] [| ===>"
echo -r " >= <= =>= ->- >>- <<- <***> =: <. <.> .> ~> ~~> ~~~~>"
echo -r " (* |- -| =!= :> <!-- <==> <--> |} {| >=> <=< ++++ ___"
echo

3
bin/termrec Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
asciinema rec -i 2 --stdin

2
bin/tls Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env sh
tmux list-sessions

4
bin/tmux-edit-buffer Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env sh
f="$(tmux-save-buffer)"
tmux new-window "$EDITOR $f"

11
bin/tmux-lyte-session Executable file
View file

@ -0,0 +1,11 @@
#!/usr/bin/env fish
set session_name $argv[1]
set dir (set -q argv[2] && echo $argv[2] || pwd)
if set -q TMUX
tmux switch -t $session_name
else
tmux new-session -D -s "$session_name" -c "$dir" $argv[3..-1] &>/dev/null || \
tmux attach -t "$session_name" -c "$dir"
end

9
bin/tmux-save-buffer Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env sh
d="$(date +%Y-%m-%d_%H-%M-%S)"
f="${USER_LOGS_PATH}/${d}.tmux-buffer.log"
mkdir -p "$(dirname "$f")"
touch "$f"
chmod 600 "$f"
tmux capture-pane -pS -1000000000 > "$f"
echo "$f"

9
bin/tmux-session-dir Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env sh
# if inside a session, use the current session
# if not, a session must be specified after the dir
d="${1}"
[ -z "$d" ] && d="#{pane_current_path}"
target_session="${2}"
[ -n "$TMUX" ] && target_session="."
tmux attach-session -t "$target_session" -c "$d"

13
bin/tmux-session-preview Executable file
View file

@ -0,0 +1,13 @@
#!/usr/bin/env sh
session_data="$1"
session_id="$(echo "$session_data" | cut -d':' -f1)"
S="$(tmux ls -F'#{session_id} #{session_name}: #{T:tree_mode_format}' | grep ^"$session_id")"
session_info="${S##$s}"
session_name="$(echo "$session_info" | cut -d ':' -f1)"
echo "RAW: $1"
echo "S: $S"
echo "INFO: $session_info"
echo "NAME: $session_name"

22
bin/tmuxswitcher Executable file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env sh
fmt='#{session_id}:|#S|(#{session_attached} attached)'
t="tmux switch-client -t"
[ -z "$TMUX" ] && t="tmux attach-session -t"
sess="$({ tmux display-message -p -F "$fmt" && tmux list-sessions -F "$fmt"; } \
| awk '!seen[$1]++' \
| column -t -s'|' \
| sk -q '$' --reverse --prompt 'switch session: ' -1 --preview "tmux-session-preview {}" \
| cut -d':' -f1)"
[ -z "$sess" ] && exit 1
$t "$sess"
# | while read w; do
# set W (tmux lsw -t"{}" -F'#{window_id}#{T:tree_mode_format}' | grep ^"$w")
# echo " ﬌ ${W##$w}"
# end

9
bin/unarchive Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env bash
archive_name="${1}"; shift
to_dir="$(basename "$archive_name")"
mkdir -p "${to_dir}"
pushd "${to_dir}" || ( echo "${to_dir} does not exist" ; exit 1 )
tar --zstd -xvf "${archive_name}"
echo "Unarchived to: ${to_dir}"
popd || exit 2

56
bin/unbackupify Executable file
View file

@ -0,0 +1,56 @@
#!/usr/bin/env fish
# deps: fish, zstd, gpg, ssh
set -q HOST || set HOST (head -n 1 /etc/hostname | tr -d '\n')
# use the backup-host in the ~/.ssh/config as the default backup remote host
set -q BACKUP_REMOTE_HOST || set BACKUP_REMOTE_HOST backup-host
# use a user-specific dir by default to backup to
set -q BACKUP_REMOTE_DIR || set BACKUP_REMOTE_DIR "/storage/"(whoami)"/backups/$HOST"
set BACKUP_FILE_EXT .tar.zstd.gpg
set target $argv[1]
if test $target = '--list-backup-files'
ssh $BACKUP_REMOTE_HOST "command ls -1 $BACKUP_REMOTE_DIR"
exit 0
else if test (count $argv) -lt 1
echo "No remote backup filename provided (use --list-backup-files to show)"
exit 1
end
ssh $BACKUP_REMOTE_HOST "echo 1" &>/dev/null || begin
echo "Cannot ssh to $BACKUP_REMOTE_HOST"
exit 6
end
ssh $BACKUP_REMOTE_HOST "test -d $BACKUP_REMOTE_DIR/$target" || begin
echo "Remote directory $BACKUP_REMOTE_DIR/$target does not exist on $BACKUP_REMOTE_HOST (use --list-backup-files to show)"
exit 5
end
# TODO: autocomplete?
# TODO: checksum?
# TODO: progress indicator?
set local_dir (echo $target | awk -F. '{print $1}')
mkdir $local_dir || begin
echo "Local unbackup directory '$local_dir' exists"
exit 2
end
pushd $local_dir >/dev/null
ssh $BACKUP_REMOTE_HOST "cat $BACKUP_REMOTE_DIR/$target" |
gpg --decrypt 2>/dev/null |
zstd --ultra -T2 -22 -dc |
tar -xf - || begin
echo "Failed to stream backup"
exit 4
end
popd >/dev/null
echo "Restored to $local_dir"

3
bin/weather Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env sh
curl 'wttr.in/@h.lyte.dev?format=%l%20%T:%20%t%20%C%20%w%20%h'

4
bin/work-journal-entry Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env fish
N work/divvy/(date +%Y-%m-%d) && \
pushd $NOTES_PATH && git add -A && \
git commit -m "Edit work journal entry for "(date +%Y-%m-%d) && nsync

8
bin/yamldiff Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
[ "$#" -lt 2 ] && echo "Need two filenames." && exit 1
f1="$1"; shift; echo "$f1" >&2
f2="$1"; shift; echo "$f2" >&2
nvim -d <(yq . "$f1" | jq -S .) <(yq . "$f2" | jq -S .)

View file

@ -1,4 +1,4 @@
{ pkgs, lib, ... }: { { pkgs, lib, inputs, ... }: {
# TODO: email access? # TODO: email access?
# accounts.email.accounts = { # accounts.email.accounts = {
# google = { # google = {
@ -14,7 +14,7 @@
home.stateVersion = "23.05"; home.stateVersion = "23.05";
home.packages = [ home.packages = [
inputs.rtx.packages.rtx
]; ];
programs.password-store = { programs.password-store = {
@ -130,7 +130,7 @@
}; };
verbs = [ verbs = [
{ invocation = "edit"; shortcut = "e"; execution = "$EDITOR +{line} {file}"; } { invocation = "edit"; shortcut = "e"; execution = "$EDITOR {file}"; }
]; ];
}; };
}; };

View file

@ -122,6 +122,21 @@
"type": "github" "type": "github"
} }
}, },
"flake-utils_3": {
"locked": {
"lastModified": 1678901627,
"narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"helix": { "helix": {
"inputs": { "inputs": {
"crane": "crane", "crane": "crane",
@ -221,9 +236,31 @@
"helix": "helix", "helix": "helix",
"home-manager": "home-manager", "home-manager": "home-manager",
"nixpkgs": "nixpkgs_2", "nixpkgs": "nixpkgs_2",
"rtx": "rtx",
"sops-nix": "sops-nix" "sops-nix": "sops-nix"
} }
}, },
"rtx": {
"inputs": {
"flake-utils": "flake-utils_3",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1693923183,
"narHash": "sha256-TH2JC+Cjw+ed1O33QKGq+lonIKlu6pHuY1jtrZh/FMM=",
"owner": "jdx",
"repo": "rtx",
"rev": "f333ac5f8e8de399fcb3ce40576baeef0271081b",
"type": "github"
},
"original": {
"owner": "jdx",
"repo": "rtx",
"type": "github"
}
},
"rust-overlay": { "rust-overlay": {
"inputs": { "inputs": {
"flake-utils": [ "flake-utils": [

View file

@ -34,6 +34,11 @@
url = "github:helix-editor/helix"; url = "github:helix-editor/helix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
rtx = {
url = "github:jdx/rtx";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
outputs = { self, ... }@inputs: { outputs = { self, ... }@inputs: {
@ -42,6 +47,7 @@
normalUefiBtrfs = import ./machines/musicbox-disks.nix; normalUefiBtrfs = import ./machines/musicbox-disks.nix;
}; };
homeConfigurations = homeConfigurations =
# TODO: per arch?
let let
system = "x86_64-linux"; system = "x86_64-linux";
pkgs = inputs.nixpkgs.legacyPackages.${system}; pkgs = inputs.nixpkgs.legacyPackages.${system};

View file

@ -182,6 +182,7 @@ in
git-lfs git-lfs
grim grim
inputs.helix.packages."x86_64-linux".helix inputs.helix.packages."x86_64-linux".helix
inputs.rtx.packages."x86_64-linux".rtx
hexyl hexyl
htop htop
inkscape inkscape