diff --git a/default/bash/fns/compression b/default/bash/fns/compression new file mode 100644 index 00000000..4e8bb814 --- /dev/null +++ b/default/bash/fns/compression @@ -0,0 +1,3 @@ +# Compression +compress() { tar -czf "${1%/}.tar.gz" "${1%/}"; } +alias decompress="tar -xzf" diff --git a/default/bash/fns/drives b/default/bash/fns/drives new file mode 100644 index 00000000..2a0c6285 --- /dev/null +++ b/default/bash/fns/drives @@ -0,0 +1,59 @@ +# Write iso file to sd card +iso2sd() { + if [[ $# -lt 1 ]]; then + echo "Usage: iso2sd [output_device]" + echo "Example: iso2sd ~/Downloads/ubuntu-25.04-desktop-amd64.iso /dev/sda" + return 1 + fi + + local iso="$1" + local drive="$2" + + if [[ -z $drive ]]; then + local available_sds=$(lsblk -dpno NAME | grep -E '/dev/sd') + + if [[ -z $available_sds ]]; then + echo "No SD drives found and no drive specified" + return 1 + fi + + drive=$(omarchy-drive-select "$available_sds") + + if [[ -z $drive ]]; then + echo "No drive selected" + return 1 + fi + fi + + sudo dd bs=4M status=progress oflag=sync if="$iso" of="$drive" + sudo eject "$drive" +} + +# Format an entire drive for a single partition using exFAT +format-drive() { + if [ $# -ne 2 ]; then + echo "Usage: format-drive " + echo "Example: format-drive /dev/sda 'My Stuff'" + echo -e "\nAvailable drives:" + lsblk -d -o NAME -n | awk '{print "/dev/"$1}' + else + echo "WARNING: This will completely erase all data on $1 and label it '$2'." + read -rp "Are you sure you want to continue? (y/N): " confirm + + if [[ "$confirm" =~ ^[Yy]$ ]]; then + sudo wipefs -a "$1" + sudo dd if=/dev/zero of="$1" bs=1M count=100 status=progress + sudo parted -s "$1" mklabel gpt + sudo parted -s "$1" mkpart primary 1MiB 100% + sudo parted -s "$1" set 1 msftdata on + + partition="$([[ $1 == *"nvme"* ]] && echo "${1}p1" || echo "${1}1")" + sudo partprobe "$1" || true + sudo udevadm settle || true + + sudo mkfs.exfat -n "$2" "$partition" + + echo "Drive $1 formatted as exFAT and labeled '$2'." + fi + fi +} diff --git a/default/bash/fns/ssh-port-forwarding b/default/bash/fns/ssh-port-forwarding new file mode 100644 index 00000000..4dd701cf --- /dev/null +++ b/default/bash/fns/ssh-port-forwarding @@ -0,0 +1,20 @@ +# SSH Port Forwarding Functions +fip() { + [[ $# -lt 2 ]] && echo "Usage: fip [port2] ..." && return 1 + local host="$1" + shift + for port in "$@"; do + ssh -f -N -L "$port:localhost:$port" "$host" && echo "Forwarding localhost:$port -> $host:$port" + done +} + +dip() { + [[ $# -eq 0 ]] && echo "Usage: dip [port2] ..." && return 1 + for port in "$@"; do + pkill -f "ssh.*-L $port:localhost:$port" && echo "Stopped forwarding port $port" || echo "No forwarding on port $port" + done +} + +lip() { + pgrep -af "ssh.*-L [0-9]+:localhost:[0-9]+" || echo "No active forwards" +} diff --git a/default/bash/fns/tmux b/default/bash/fns/tmux new file mode 100644 index 00000000..e451bd4f --- /dev/null +++ b/default/bash/fns/tmux @@ -0,0 +1,75 @@ +# Create a tmux layout for dev with editor, ai, and terminal +tml() { + [[ -z $TMUX ]] && { echo "You must start tmux to use tml."; return 1; } + + local current_dir="${PWD}" + local editor_pane ai_pane + local ai="$1" + + # Use TMUX_PANE for the pane we're running in (stable even if active window changes) + editor_pane="$TMUX_PANE" + + # Name the current window after the base directory name + tmux rename-window -t "$editor_pane" "$(basename "$current_dir")" + + # Split window vertically - top 85%, bottom 15% (target editor pane explicitly) + tmux split-window -v -p 15 -t "$editor_pane" -c "$current_dir" + + # Split editor pane horizontally - AI on right 30% (capture new pane ID directly) + ai_pane=$(tmux split-window -h -p 30 -t "$editor_pane" -c "$current_dir" -P -F '#{pane_id}') + + # Run ai in the right pane + tmux send-keys -t "$ai_pane" "$ai" C-m + + # Run nvim in the left pane + tmux send-keys -t "$editor_pane" "$EDITOR ." C-m + + # Select the nvim pane for focus + tmux select-pane -t "$editor_pane" +} + +# Create a tml window per subdirectory in the current directory +tmlm() { + [[ -z $TMUX ]] && { echo "You must start tmux to use tmlm."; return 1; } + + local ai="$1" + local base_dir="$PWD" + local first=true + + # Rename the session to the current directory name (replace dots/colons which tmux disallows) + tmux rename-session "$(basename "$base_dir" | tr '.:' '--')" + + for dir in "$base_dir"/*/; do + [[ -d $dir ]] || continue + local dirpath="${dir%/}" + + if $first; then + # Reuse the current window for the first project + tmux send-keys -t "$TMUX_PANE" "cd '$dirpath' && tml $ai" C-m + first=false + else + local pane_id=$(tmux new-window -c "$dirpath" -P -F '#{pane_id}') + tmux send-keys -t "$pane_id" "tml $ai" C-m + fi + done +} + +# Create a dev layout using tmux with editor, opencode, and terminal +nic() { + tml c +} + +# Create a dev layout using tmux with editor, claude, and terminal +nicx() { + tml cx +} + +# Create tml windows for each subdirectory using opencode +nicm() { + tmlm c +} + +# Create tml windows for each subdirectory using claude +nicxm() { + tmlm cx +} diff --git a/default/bash/fns/transcoding b/default/bash/fns/transcoding new file mode 100644 index 00000000..96d5b2f3 --- /dev/null +++ b/default/bash/fns/transcoding @@ -0,0 +1,44 @@ +# Transcode a video to a good-balance 1080p that's great for sharing online +transcode-video-1080p() { + ffmpeg -i $1 -vf scale=1920:1080 -c:v libx264 -preset fast -crf 23 -c:a copy ${1%.*}-1080p.mp4 +} + +# Transcode a video to a good-balance 4K that's great for sharing online +transcode-video-4K() { + ffmpeg -i $1 -c:v libx265 -preset slow -crf 24 -c:a aac -b:a 192k ${1%.*}-optimized.mp4 +} + +# Transcode any image to JPG image that's great for shrinking wallpapers +img2jpg() { + img="$1" + shift + + magick "$img" $@ -quality 95 -strip ${img%.*}-converted.jpg +} + +# Transcode any image to JPG image that's great for sharing online without being too big +img2jpg-small() { + img="$1" + shift + + magick "$img" $@ -resize 1080x\> -quality 95 -strip ${img%.*}-small.jpg +} +# Transcode any image to JPG image that's great for sharing online without being too big +img2jpg-medium() { + img="$1" + shift + + magick "$img" $@ -resize 1800x\> -quality 95 -strip ${img%.*}-medium.jpg +} + +# Transcode any image to compressed-but-lossless PNG +img2png() { + img="$1" + shift + + magick "$img" $@ -strip -define png:compression-filter=5 \ + -define png:compression-level=9 \ + -define png:compression-strategy=1 \ + -define png:exclude-chunk=all \ + "${img%.*}-optimized.png" +} diff --git a/default/bash/functions b/default/bash/functions index a4ca112b..edc04750 100644 --- a/default/bash/functions +++ b/default/bash/functions @@ -1,196 +1,2 @@ -# Compression -compress() { tar -czf "${1%/}.tar.gz" "${1%/}"; } -alias decompress="tar -xzf" -# Write iso file to sd card -iso2sd() { - if [[ $# -lt 1 ]]; then - echo "Usage: iso2sd [output_device]" - echo "Example: iso2sd ~/Downloads/ubuntu-25.04-desktop-amd64.iso /dev/sda" - return 1 - fi - - local iso="$1" - local drive="$2" - - if [[ -z $drive ]]; then - local available_sds=$(lsblk -dpno NAME | grep -E '/dev/sd') - - if [[ -z $available_sds ]]; then - echo "No SD drives found and no drive specified" - return 1 - fi - - drive=$(omarchy-drive-select "$available_sds") - - if [[ -z $drive ]]; then - echo "No drive selected" - return 1 - fi - fi - - sudo dd bs=4M status=progress oflag=sync if="$iso" of="$drive" - sudo eject "$drive" -} - -# Format an entire drive for a single partition using exFAT -format-drive() { - if [ $# -ne 2 ]; then - echo "Usage: format-drive " - echo "Example: format-drive /dev/sda 'My Stuff'" - echo -e "\nAvailable drives:" - lsblk -d -o NAME -n | awk '{print "/dev/"$1}' - else - echo "WARNING: This will completely erase all data on $1 and label it '$2'." - read -rp "Are you sure you want to continue? (y/N): " confirm - - if [[ "$confirm" =~ ^[Yy]$ ]]; then - sudo wipefs -a "$1" - sudo dd if=/dev/zero of="$1" bs=1M count=100 status=progress - sudo parted -s "$1" mklabel gpt - sudo parted -s "$1" mkpart primary 1MiB 100% - sudo parted -s "$1" set 1 msftdata on - - partition="$([[ $1 == *"nvme"* ]] && echo "${1}p1" || echo "${1}1")" - sudo partprobe "$1" || true - sudo udevadm settle || true - - sudo mkfs.exfat -n "$2" "$partition" - - echo "Drive $1 formatted as exFAT and labeled '$2'." - fi - fi -} - -# Transcode a video to a good-balance 1080p that's great for sharing online -transcode-video-1080p() { - ffmpeg -i $1 -vf scale=1920:1080 -c:v libx264 -preset fast -crf 23 -c:a copy ${1%.*}-1080p.mp4 -} - -# Transcode a video to a good-balance 4K that's great for sharing online -transcode-video-4K() { - ffmpeg -i $1 -c:v libx265 -preset slow -crf 24 -c:a aac -b:a 192k ${1%.*}-optimized.mp4 -} - -# Transcode any image to JPG image that's great for shrinking wallpapers -img2jpg() { - img="$1" - shift - - magick "$img" $@ -quality 95 -strip ${img%.*}-converted.jpg -} - -# Transcode any image to JPG image that's great for sharing online without being too big -img2jpg-small() { - img="$1" - shift - - magick "$img" $@ -resize 1080x\> -quality 95 -strip ${img%.*}-small.jpg -} -# Transcode any image to JPG image that's great for sharing online without being too big -img2jpg-medium() { - img="$1" - shift - - magick "$img" $@ -resize 1800x\> -quality 95 -strip ${img%.*}-medium.jpg -} - -# Transcode any image to compressed-but-lossless PNG -img2png() { - img="$1" - shift - - magick "$img" $@ -strip -define png:compression-filter=5 \ - -define png:compression-level=9 \ - -define png:compression-strategy=1 \ - -define png:exclude-chunk=all \ - "${img%.*}-optimized.png" -} - -# SSH Port Forwarding Functions -fip() { - [[ $# -lt 2 ]] && echo "Usage: fip [port2] ..." && return 1 - local host="$1" - shift - for port in "$@"; do - ssh -f -N -L "$port:localhost:$port" "$host" && echo "Forwarding localhost:$port -> $host:$port" - done -} - -dip() { - [[ $# -eq 0 ]] && echo "Usage: dip [port2] ..." && return 1 - for port in "$@"; do - pkill -f "ssh.*-L $port:localhost:$port" && echo "Stopped forwarding port $port" || echo "No forwarding on port $port" - done -} - -lip() { - pgrep -af "ssh.*-L [0-9]+:localhost:[0-9]+" || echo "No active forwards" -} - -# Create a tmux layout for dev with editor, ai, and terminal -tml() { - [[ -z $TMUX ]] && { echo "You must start tmux to use tml."; return 1; } - - local current_dir="${PWD}" - local editor_pane ai_pane - local ai="$1" - - # Name the current window after the base directory name - tmux rename-window "$(basename "$current_dir")" - - # Get current pane ID (will become editor pane after splits) - editor_pane=$(tmux display-message -p '#{pane_id}') - - # Split window vertically - top 85%, bottom 15% - tmux split-window -v -p 15 -c "$current_dir" - - # Go back to top pane (editor_pane) and split it horizontally - tmux select-pane -t "$editor_pane" - tmux split-window -h -p 30 -c "$current_dir" - - # After horizontal split, cursor is in the right pane (new pane) - # Get its ID and run ai there - ai_pane=$(tmux display-message -p '#{pane_id}') - tmux send-keys -t "$ai_pane" "$ai" C-m - - # Run nvim in the left pane - tmux send-keys -t "$editor_pane" "$EDITOR ." C-m - - # Select the nvim pane for focus - tmux select-pane -t "$editor_pane" -} - -# Create a tml window per subdirectory in the current directory -tmlm() { - [[ -z $TMUX ]] && { echo "You must start tmux to use tmlm."; return 1; } - - local ai="$1" - - for dir in */; do - [[ -d $dir ]] || continue - local dirpath="${PWD}/${dir%/}" - tmux new-window -c "$dirpath" - tmux send-keys "tml $ai" C-m - done -} - -# Create a dev layout using tmux with editor, opencode, and terminal -nic() { - tml c -} - -# Create a dev layout using tmux with editor, claude, and terminal -nicx() { - tml cx -} - -# Create tml windows for each subdirectory using opencode -nicm() { - tmlm c -} - -# Create tml windows for each subdirectory using claude -nicxm() { - tmlm cx -} +for f in ~/.local/share/omarchy/default/bash/fns/*; do source "$f"; done