This commit is contained in:
Barrett Ruth 2026-02-11 17:54:03 -05:00
parent 02a97d7208
commit 43f68c58a2
Signed by: barrett
GPG key ID: A6C96C9349D2FC81
3 changed files with 228 additions and 73 deletions

View file

@ -1,5 +1,5 @@
{ {
"blink.cmp": { "branch": "main", "commit": "7c80e36023c5499a97e097cb5f229e9b635725a0" }, "blink.cmp": { "branch": "main", "commit": "4b18c32adef2898f95cdef6192cbd5796c1a332d" },
"cp.nvim": { "branch": "main", "commit": "029ea125b97320ff5c2884bf84bf5aa4e7077c79" }, "cp.nvim": { "branch": "main", "commit": "029ea125b97320ff5c2884bf84bf5aa4e7077c79" },
"dial.nvim": { "branch": "master", "commit": "f2634758455cfa52a8acea6f142dcd6271a1bf57" }, "dial.nvim": { "branch": "master", "commit": "f2634758455cfa52a8acea6f142dcd6271a1bf57" },
"fzf-lua": { "branch": "main", "commit": "fb8c50ba62a0daa433b7ac2b78834f318322b879" }, "fzf-lua": { "branch": "main", "commit": "fb8c50ba62a0daa433b7ac2b78834f318322b879" },

View file

@ -11,7 +11,7 @@ return {
}, },
{ {
'saghen/blink.cmp', 'saghen/blink.cmp',
build = 'cargo build --release', version = '1.*',
dependencies = 'folke/lazydev.nvim', dependencies = 'folke/lazydev.nvim',
---@module 'blink.cmp' ---@module 'blink.cmp'
---@type blink.cmp.Config ---@type blink.cmp.Config

View file

@ -49,10 +49,11 @@ sets=(
"|/ \/-\ \|/\ /-" "|/ \/-\ \|/\ /-"
".. .... .... .." ".. .... .... .."
".o oo.o o.oo o." ".o oo.o o.oo o."
"-\ /\|/ /-\/ \|" "-\ /\|/ /-\/ \|" # railway
"╿┍ ┑┚╼┒ ┕╽┙┖ ┎╾" "╿┍ ┑┚╼┒ ┕╽┙┖ ┎╾" # knobby pipe
"████▀▀███▀█▀▀██▀" "████▀▀███▀█▀▀██▀"
) )
SETS=() # rearranged all pipe chars into individul elements for easier access
# pipes' # pipes'
x=() # current position x=() # current position
@ -61,13 +62,14 @@ l=() # current directions
# 0: up, 1: right, 2: down, 3: left # 0: up, 1: right, 2: down, 3: left
n=() # new directions n=() # new directions
v=() # current types v=() # current types
c=() # current color c=() # current escape codes
# selected pipes' # selected pipes'
V=() # types (indexes to sets[]) V=() # types (indexes to sets[])
C=() # colors C=() # color indices for tput setaf
VN=0 # number of selected types VN=0 # number of selected types
CN=0 # number of selected colors CN=0 # number of selected colors
E=() # pre-generated escape codes from BOLD, NOCOLOR, and C
# switches # switches
RNDSTART=0 # randomize starting position and direction RNDSTART=0 # randomize starting position and direction
@ -76,72 +78,160 @@ NOCOLOR=0
KEEPCT=0 # keep pipe color and type KEEPCT=0 # keep pipe color and type
# print help message in 72-char width
print_help() {
local cgap
printf -v cgap '%*s' $((15 - ${#COLORS})) ''
cat <<HELP
Usage: $(basename $0) [OPTION]...
Animated pipes terminal screensaver.
-p [1-] number of pipes (D=1)
-t [0-$((${#sets[@]} - 1))] pipe type (D=0)
-t c[16 chars] custom pipe type
-c [0-$COLORS]${cgap}pipe color INDEX (TERM=$TERM), can be
hexadecimal with '#' prefix
(D=-c 1 -c 2 ... -c 7 -c 0)
-f [20-100] framerate (D=75)
-s [5-15] going straight probability, 1 in (D=13)
-r [0-] reset after (D=2000) characters, 0 if no reset
-R randomize starting position and direction
-B no bold effect
-C no color
-K keep pipe color and type when crossing edges
-h print this help message
-v print version number
Note: -t and -c can be used more than once.
HELP
}
# parse command-line options
# It depends on a valid COLORS which is set by _CP_init_termcap_vars
parse() { parse() {
# test if $1 is a natural number in decimal, an integer >= 0
is_N() {
[[ -n $1 && -z ${1//[0-9]} ]]
}
# test if $1 is a hexadecimal string
is_hex() {
[[ -n $1 && -z ${1//[0-9A-Fa-f]} ]]
}
# print error message for invalid argument to standard error, this
# - mimics getopts error message
# - use all positional parameters as error message
# - has a newline appended
# $arg and $OPTARG are the option name and argument set by getopts.
pearg() {
printf "%s: -$arg invalid argument -- $OPTARG; %s\n" "$0" "$*" >&2
}
OPTIND=1 OPTIND=1
while getopts "p:t:c:f:s:r:RBCKhv" arg; do while getopts "p:t:c:f:s:r:RBCKhv" arg; do
case $arg in case $arg in
p) ((p = (OPTARG > 0) ? OPTARG : p));; p)
if is_N "$OPTARG" && ((OPTARG > 0)); then
p=$OPTARG
else
pearg 'must be an integer and greater than 0'
return 1
fi
;;
t) t)
if [[ "$OPTARG" = c???????????????? ]]; then if [[ "$OPTARG" = c???????????????? ]]; then
V+=(${#sets[@]}) V+=(${#sets[@]})
sets+=("${OPTARG:1}") sets+=("${OPTARG:1}")
elif is_N "$OPTARG" && ((OPTARG < ${#sets[@]})); then
V+=($OPTARG)
else else
((OPTARG >= 0 && OPTARG < ${#sets[@]})) && V+=("$OPTARG") pearg 'must be an integer and from 0 to' \
"$((${#sets[@]} - 1)); or a custom type"
return 1
fi
;;
c)
if [[ $OPTARG == '#'* ]]; then
if ! is_hex "${OPTARG:1}"; then
pearg 'unrecognized hexadecimal string'
return 1
fi
if ((16$OPTARG >= COLORS)); then
pearg 'hexadecimal must be from #0 to' \
"#$(printf '%X' $((COLORS - 1)))"
return 1
fi
C+=($((16$OPTARG)))
elif is_N "$OPTARG" && ((OPTARG < COLORS)); then
C+=($OPTARG)
else
pearg "must be an integer and from 0 to $((COLORS - 1));" \
'or a hexadecimal string with # prefix'
return 1
fi
;;
f)
if is_N "$OPTARG" && ((OPTARG >= 20 && OPTARG <= 100)); then
f=$OPTARG
else
pearg 'must be an integer and from 20 to 100'
return 1
fi
;;
s)
if is_N "$OPTARG" && ((OPTARG >= 5 && OPTARG <= 15)); then
s=$OPTARG
else
pearg 'must be an integer and from 5 to 15'
return 1
fi
;;
r)
if is_N "$OPTARG"; then
r=$OPTARG
else
pearg 'must be a non-negative integer'
return 1
fi fi
;; ;;
c) [[ $OPTARG =~ ^[0-7]$ ]] && C+=("$OPTARG");;
f) ((f = (OPTARG > 19 && OPTARG < 101) ? OPTARG : f));;
s) ((s = (OPTARG > 4 && OPTARG < 16) ? OPTARG : s));;
r) ((r = (OPTARG >= 0) ? OPTARG : r));;
R) RNDSTART=1;; R) RNDSTART=1;;
B) BOLD=0;; B) BOLD=0;;
C) NOCOLOR=1;; C) NOCOLOR=1;;
K) KEEPCT=1;; K) KEEPCT=1;;
h) echo -e "Usage: $(basename "$0") [OPTION]..." h)
echo -e "Animated pipes terminal screensaver.\n" print_help
echo -e " -p [1-]\tnumber of pipes (D=1)." exit 0
echo -e " -t [0-$((${#sets[@]} - 1))]\ttype of pipes, can be used more than once (D=0)." ;;
echo -e " -c [0-7]\tcolor of pipes, can be used more than once (D=1 2 3 4 5 6 7 0)."
echo -e " -t c[16 chars]\tcustom type of pipes."
echo -e " -f [20-100]\tframerate (D=75)."
echo -e " -s [5-15]\tprobability of a straight fitting (D=13)."
echo -e " -r LIMIT\treset after x characters, 0 if no limit (D=2000)."
echo -e " -R \t\trandomize starting position and direction."
echo -e " -B \t\tno bold effect."
echo -e " -C \t\tno color."
echo -e " -K \t\tpipes keep their color and type when hitting the screen edge."
echo -e " -h\t\thelp (this screen)."
echo -e " -v\t\tprint version number.\n"
exit 0;;
v) echo "$(basename -- "$0") $VERSION" v) echo "$(basename -- "$0") $VERSION"
exit 0 exit 0
;; ;;
*) *)
exit 1 return 1
;;
esac esac
done done
# set default values if not by options shift $((OPTIND - 1))
((${#V[@]})) || V=(0) if (($#)); then
VN=${#V[@]} printf "$0: illegal arguments -- $*; no arguments allowed\n" >&2
((${#C[@]})) || C=(1 2 3 4 5 6 7 0) return 1
CN=${#C[@]} fi
} }
cleanup() { cleanup() {
# clear out standard input # clear out standard input
read -r -t 0.001 && cat </dev/stdin>/dev/null read -t 0.001 && cat </dev/stdin>/dev/null
# terminal has no smcup and rmcup capabilities
((FORCE_RESET)) && reset && exit 0
tput reset # fix for konsole, see pipeseroni/pipes.sh#43 tput reset # fix for konsole, see pipeseroni/pipes.sh#43
tput rmcup tput rmcup
tput cnorm tput cnorm
# stty echo stty echo
((NOCOLOR)) && echo -ne '\e[0m' printf "$SGR0"
exit 0 exit 0
} }
@ -151,42 +241,92 @@ resize() {
} }
init() { init_pipes() {
# +_CP_init_pipes
local i local i
resize
trap resize SIGWINCH
ci=$((KEEPCT ? 0 : CN * RANDOM / M)) ci=$((KEEPCT ? 0 : CN * RANDOM / M))
vi=$((KEEPCT ? 0 : VN * RANDOM / M)) vi=$((KEEPCT ? 0 : VN * RANDOM / M))
for ((i = 0; i < p; i++)); {(( for ((i = 0; i < p; i++)); do
((
n[i] = 0, n[i] = 0,
l[i] = RNDSTART ? RANDOM % 4 : 0, l[i] = RNDSTART ? RANDOM % 4 : 0,
x[i] = RNDSTART ? w * RANDOM / M : w / 2, x[i] = RNDSTART ? w * RANDOM / M : w / 2,
y[i] = RNDSTART ? h * RANDOM / M : h / 2, y[i] = RNDSTART ? h * RANDOM / M : h / 2,
c[i] = C[ci], v[i] = V[vi]
v[i] = V[vi], ))
ci = (ci + 1) % CN, c[i]=${E[ci]}
vi = (vi + 1) % VN ((ci = (ci + 1) % CN, vi = (vi + 1) % VN))
));} done
# -_CP_init_pipes
}
# stty -echo
tput smcup || FORCE_RESET=1 init_screen() {
stty -echo
tput smcup
tput civis tput civis
tput clear tput clear
trap cleanup HUP TERM trap cleanup HUP TERM
resize
trap resize SIGWINCH
} }
main() { main() {
local i # simple pre-check of TERM, tput's error message should be enough
tput -T "$TERM" sgr0 >/dev/null || return $?
parse "$@" # +_CP_init_termcap_vars
init "$@" COLORS=$(tput colors) # COLORS - 1 == maximum color index for -c argument
SGR0=$(tput sgr0)
SGR_BOLD=$(tput bold)
# -_CP_init_termcap_vars
parse "$@" || return $?
# +_CP_init_VC
# set default values if not by options
((${#V[@]})) || V=(0)
VN=${#V[@]}
((${#C[@]})) || C=(1 2 3 4 5 6 7 0)
CN=${#C[@]}
# -_CP_init_VC
# +_CP_init_E
# generate E[] based on BOLD (SGR_BOLD), NOCOLOR, and C for each element in
# C, a corresponding element in E[] =
# SGR0
# + SGR_BOLD, if BOLD
# + tput setaf C, if !NOCOLOR
local i
for ((i = 0; i < CN; i++)) {
E[i]=$SGR0
((BOLD)) && E[i]+=$SGR_BOLD
((NOCOLOR)) || E[i]+=$(tput setaf ${C[i]})
}
# -_CP_init_E
# +_CP_init_SETS
local i j
for ((i = 0; i < ${#sets[@]}; i++)) {
for ((j = 0; j < 16; j++)) {
SETS+=("${sets[i]:j:1}")
}
}
unset i j
# -_CP_init_SETS
init_screen
init_pipes
# any key press exits the loop and this script # any key press exits the loop and this script
trap 'break 2' INT trap 'break 2' INT
local i
while REPLY=; do while REPLY=; do
read -r -t 0.0$((1000 / f)) -n 1 2>/dev/null read -t 0.0$((1000 / f)) -n 1 2>/dev/null
case "$REPLY" in case "$REPLY" in
P) ((s = s < 15 ? s + 1 : s));; P) ((s = s < 15 ? s + 1 : s));;
O) ((s = s > 3 ? s - 1 : s));; O) ((s = s > 3 ? s - 1 : s));;
@ -200,24 +340,39 @@ main() {
for ((i = 0; i < p; i++)); do for ((i = 0; i < p; i++)); do
# New position: # New position:
# l[] direction = 0: up, 1: right, 2: down, 3: left # l[] direction = 0: up, 1: right, 2: down, 3: left
# +_CP_newpos
((l[i] % 2)) && ((x[i] += -l[i] + 2, 1)) || ((y[i] += l[i] - 1)) ((l[i] % 2)) && ((x[i] += -l[i] + 2, 1)) || ((y[i] += l[i] - 1))
# -_CP_newpos
# Loop on edges (change color on loop): # Loop on edges (change color on loop):
# +_CP_warp
((!KEEPCT && (x[i] >= w || x[i] < 0 || y[i] >= h || y[i] < 0))) \ ((!KEEPCT && (x[i] >= w || x[i] < 0 || y[i] >= h || y[i] < 0))) \
&& ((c[i] = C[CN * RANDOM / M], v[i] = V[VN * RANDOM / M])) && { c[i]=${E[CN * RANDOM / M]}; ((v[i] = V[VN * RANDOM / M])); }
((x[i] = (x[i] + w) % w)) ((x[i] = (x[i] + w) % w,
((y[i] = (y[i] + h) % h)) y[i] = (y[i] + h) % h))
# -_CP_warp
# New random direction: # new turning direction:
((n[i] = s * RANDOM / M - 1)) # $((s - 1)) in $s, going straight, therefore n[i] == l[i];
((n[i] = (n[i] > 1 || n[i] == 0) ? l[i] : l[i] + n[i])) # and 1 in $s that pipe makes a right or left turn
((n[i] = (n[i] < 0) ? 3 : n[i] % 4)) #
# s * RANDOM / M - 1 == 0
# n[i] == -1
# => n[i] == l[i] + 1 or l[i] - 1
# +_CP_newdir
((
n[i] = s * RANDOM / M - 1,
n[i] = n[i] >= 0 ? l[i] : l[i] + (2 * (RANDOM % 2) - 1),
n[i] = (n[i] + 4) % 4
))
# -_CP_newdir
# Print: # Print:
tput cup "${y[i]} ${x[i]}" # +_CP_print
echo -ne "\e[${BOLD}m" printf '\e[%d;%dH%s%s' \
((NOCOLOR)) && echo -ne "\e[0m" || echo -ne "\e[3${c[i]}m" $((y[i] + 1)) $((x[i] + 1)) ${c[i]} \
echo -n "${sets[v[i]]:l[i]*4+n[i]:1}" "${SETS[v[i] * 16 + l[i] * 4 + n[i]]}"
# -_CP_print
l[i]=${n[i]} l[i]=${n[i]}
done done
((r > 0 && t * p >= r)) && tput reset && tput civis && t=0 || ((t++)) ((r > 0 && t * p >= r)) && tput reset && tput civis && t=0 || ((t++))
@ -227,5 +382,5 @@ main() {
} }
main "$@" # when being sourced, $0 == bash, only invoke main when they are the same
[[ "$0" != "$BASH_SOURCE" ]] || main "$@"