|
|
@@ -1,20 +1,30 @@
|
|
|
-# Lazy load zoxide
|
|
|
+#!/bin/zsh
|
|
|
+
|
|
|
+# NAVIGATION AND FILE SYSTEM
|
|
|
z() {
|
|
|
- # Remove the placeholder function
|
|
|
unfunction "$0"
|
|
|
-
|
|
|
- # Load zoxide
|
|
|
eval "$(zoxide init zsh)"
|
|
|
-
|
|
|
- # Execute the command
|
|
|
$0 "$@"
|
|
|
}
|
|
|
|
|
|
-# Ensure we have all the zoxide command variants covered
|
|
|
zi() { z "$@" }
|
|
|
za() { z "$@" }
|
|
|
zrm() { zoxide remove "$@" }
|
|
|
|
|
|
+function open {
|
|
|
+ for i in $*; do
|
|
|
+ setsid nohup xdg-open $i > /dev/null 2> /dev/null
|
|
|
+ done
|
|
|
+}
|
|
|
+
|
|
|
+function fopen() {
|
|
|
+ local selected
|
|
|
+ selected=$(fd "$@" | fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}')
|
|
|
+ [[ -n "$selected" ]] && setsid nohup xdg-open "$selected" >/dev/null 2>&1 &
|
|
|
+}
|
|
|
+
|
|
|
+# DEVELOPMENT TOOLS
|
|
|
+# Package manager detection with caching
|
|
|
function _package_manager {
|
|
|
local pkg_manager=""
|
|
|
if [[ -f bun.lockb ]]; then
|
|
|
@@ -29,15 +39,12 @@ function _package_manager {
|
|
|
pkg_manager="pnpm"
|
|
|
fi
|
|
|
|
|
|
- # Check if the first argument is a script in package.json
|
|
|
if [[ -f package.json ]] && [[ $1 != "run" ]] && [[ $1 != "install" ]] && [[ $1 != "add" ]] && [[ $1 != "remove" ]] && [[ $1 != "i" ]] && [[ $1 != "rm" ]]; then
|
|
|
- # Check if the command exists in package.json scripts using jq
|
|
|
if jq -e ".scripts[\"$1\"] != null" package.json >/dev/null 2>&1; then
|
|
|
set -- "run" "$@"
|
|
|
fi
|
|
|
fi
|
|
|
|
|
|
- # Use corepack when available
|
|
|
if command -v corepack >/dev/null 2>&1; then
|
|
|
corepack ${pkg_manager} "$@"
|
|
|
else
|
|
|
@@ -45,36 +52,95 @@ function _package_manager {
|
|
|
fi
|
|
|
}
|
|
|
|
|
|
-yarn() { echo 🖕; }
|
|
|
-yarnpkg() { echo 🖕; }
|
|
|
-pnpm() { echo 🖕; }
|
|
|
-pn() { echo 🖕; }
|
|
|
-pnpx() { echo 🖕; }
|
|
|
-npm() { echo 🖕; }
|
|
|
+# Improved development commit with optional message
|
|
|
+function dc() {
|
|
|
+ if ! git rev-parse --is-inside-work-tree &>/dev/null; then
|
|
|
+ echo "Error: Not in a git repository"
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
|
|
|
-alias p='_package_manager'
|
|
|
+ if [[ -z $(git status --porcelain) ]]; then
|
|
|
+ echo "No changes to commit"
|
|
|
+ return 0
|
|
|
+ fi
|
|
|
|
|
|
-alias unChonk="echo '🧹 Starting the great node_modules purge...' && find . -name 'node_modules' -type d -prune -exec sh -c 'echo \"💥 Deleting {}\" && rm -rf \"{}\"' \;"
|
|
|
+ git add .
|
|
|
|
|
|
-# Open files using system default application
|
|
|
-function open {
|
|
|
- for i in $*
|
|
|
- do
|
|
|
- setsid nohup xdg-open $i > /dev/null 2> /dev/null
|
|
|
- done
|
|
|
+ local commit_msg
|
|
|
+ if [[ -n "$1" ]]; then
|
|
|
+ commit_msg="$1"
|
|
|
+ else
|
|
|
+ local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
|
|
|
+ commit_msg="dev: automated commit - ${timestamp}"
|
|
|
+ fi
|
|
|
+
|
|
|
+ git commit -m "$commit_msg" --no-gpg-sign
|
|
|
+ git push &>/dev/null || { echo "Push failed"; return 1; }
|
|
|
}
|
|
|
|
|
|
-function fopen() {
|
|
|
- local selected
|
|
|
- selected=$(fd "$@" | fzf)
|
|
|
- [[ -n "$selected" ]] && setsid nohup xdg-open "$selected" >/dev/null 2>&1 &
|
|
|
+# Git branch cleanup helper
|
|
|
+function git-clean() {
|
|
|
+ local current_branch=$(git rev-parse --abbrev-ref HEAD)
|
|
|
+ local branches_to_delete=$(git branch --merged | grep -v "^\*" | grep -v "master" | grep -v "main" | grep -v "develop")
|
|
|
+
|
|
|
+ if [[ -z "$branches_to_delete" ]]; then
|
|
|
+ echo "No merged branches to clean up"
|
|
|
+ return 0
|
|
|
+ fi
|
|
|
+
|
|
|
+ echo "The following merged branches will be deleted:"
|
|
|
+ echo "$branches_to_delete"
|
|
|
+ echo -n "Continue? [y/N] "
|
|
|
+ read confirm
|
|
|
+
|
|
|
+ if [[ "$confirm" =~ ^[Yy]$ ]]; then
|
|
|
+ echo "$branches_to_delete" | xargs git branch -d
|
|
|
+ echo "Branches deleted locally"
|
|
|
+
|
|
|
+ echo -n "Delete remote branches too? [y/N] "
|
|
|
+ read confirm_remote
|
|
|
+
|
|
|
+ if [[ "$confirm_remote" =~ ^[Yy]$ ]]; then
|
|
|
+ echo "$branches_to_delete" | xargs -I{} git push origin --delete {}
|
|
|
+ echo "Remote branches deleted"
|
|
|
+ fi
|
|
|
+ fi
|
|
|
}
|
|
|
|
|
|
-alias fo='fopen'
|
|
|
+function sm { /opt/sublime_merge/sublime_merge $1; }
|
|
|
+
|
|
|
+function vimrc {
|
|
|
+ cd $XDG_CONFIG_HOME/nvim
|
|
|
+ nvim
|
|
|
+ cd - >/dev/null
|
|
|
+}
|
|
|
+
|
|
|
+function zshrc {
|
|
|
+ cd $XDG_CONFIG_HOME/zsh
|
|
|
+ nvim
|
|
|
+ cd - >/dev/null
|
|
|
+}
|
|
|
|
|
|
+# FILE SHARING AND NETWORKING
|
|
|
function upload_file() {
|
|
|
+ local usage="Usage: $0 [-o] <file>"
|
|
|
+ local one_time=true
|
|
|
+
|
|
|
+ # Parse options
|
|
|
+ while getopts ":o" opt; do
|
|
|
+ case ${opt} in
|
|
|
+ o ) one_time=false ;;
|
|
|
+ \? )
|
|
|
+ echo "Invalid option: -$OPTARG" >&2
|
|
|
+ echo $usage
|
|
|
+ return 1 ;;
|
|
|
+ esac
|
|
|
+ done
|
|
|
+ shift $((OPTIND -1))
|
|
|
+
|
|
|
+ # Check file argument
|
|
|
if [[ -z "$1" ]]; then
|
|
|
- echo "Usage: $0 <file>"
|
|
|
+ echo $usage
|
|
|
return 1
|
|
|
fi
|
|
|
if [[ ! -f "$1" ]]; then
|
|
|
@@ -82,121 +148,74 @@ function upload_file() {
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
- local url="https://dump.mz.uy"
|
|
|
- # local url="http://localhost:8080"
|
|
|
- echo "Uploading $1 to $url..."
|
|
|
- local full_response=$(curl -i -F"file=@$1" -F"one_time=" "$url")
|
|
|
- # local full_response=$(curl -i -F"file=@$1" "$url")
|
|
|
- local url_response=$(echo "$full_response" | tail -n 1)
|
|
|
- local token=$(echo "$full_response" | grep -i "X-Token:" | awk '{print $2}' | tr -d '\r')
|
|
|
+ local url="https://drop.mz.uy"
|
|
|
+ echo "Uploading $1 to $url... (one-time: ${one_time})"
|
|
|
|
|
|
- if [[ -n "$url_response" ]]; then
|
|
|
- echo -n "$url_response" | wl-copy # Wayland
|
|
|
- echo "✓ Uploaded: $url_response (copied to clipboard)"
|
|
|
+ # Prepare upload options
|
|
|
+ local form_data=("-F" "file=@$1")
|
|
|
+ if $one_time; then
|
|
|
+ form_data+=("-F" "one_time=")
|
|
|
+ fi
|
|
|
+
|
|
|
+ # Try up to 3 times with a short delay between attempts
|
|
|
+ local max_attempts=3
|
|
|
+ local attempt=1
|
|
|
+ local success=false
|
|
|
|
|
|
- if [[ -n "$token" ]]; then
|
|
|
- echo "Management token: $token"
|
|
|
+ while (( attempt <= max_attempts )) && ! $success; do
|
|
|
+ if (( attempt > 1 )); then
|
|
|
+ echo "Retry attempt $attempt of $max_attempts..."
|
|
|
+ sleep 1
|
|
|
fi
|
|
|
- else
|
|
|
- echo "× Failed to upload file"
|
|
|
- return 1
|
|
|
- fi
|
|
|
-}
|
|
|
|
|
|
-# Create both commands as aliases to the same function
|
|
|
-alias drop='upload_file'
|
|
|
-alias dump='upload_file'
|
|
|
+ local full_response=$(curl -i "${form_data[@]}" "$url" 2>/dev/null)
|
|
|
+ local curl_status=$?
|
|
|
|
|
|
+ if [[ $curl_status -eq 0 ]]; then
|
|
|
+ local url_response=$(echo "$full_response" | tail -n 1)
|
|
|
+ local token=$(echo "$full_response" | grep -i "X-Token:" | awk '{print $2}' | tr -d '\r')
|
|
|
|
|
|
-# Wacom tablet configuration
|
|
|
-function wacom {
|
|
|
- if [ "$XDG_SESSION_TYPE" = "wayland" ]; then
|
|
|
- systemctl --user enable opentabletdriver --now
|
|
|
- otd loadsettings ~/Sync/wacom/wacom.json
|
|
|
- else
|
|
|
- # Reset area and map the stylus to DisplayPort-0, then rotate
|
|
|
- xsetwacom --set "Wacom One by Wacom S Pen stylus" ResetArea
|
|
|
- xsetwacom --set "Wacom One by Wacom S Pen stylus" MapToOutput DisplayPort-0
|
|
|
- xsetwacom --set "Wacom One by Wacom S Pen stylus" Rotate half
|
|
|
+ if [[ -n "$url_response" ]]; then
|
|
|
+ echo -n "$url_response" | wl-copy
|
|
|
+ echo "✓ Uploaded: $url_response (copied to clipboard)"
|
|
|
|
|
|
- # Reset area and map the eraser to DisplayPort-0
|
|
|
- xsetwacom --set "Wacom One by Wacom S Pen eraser" ResetArea
|
|
|
- xsetwacom --set "Wacom One by Wacom S Pen eraser" MapToOutput DisplayPort-0
|
|
|
- fi
|
|
|
-}
|
|
|
+ if [[ -n "$token" ]]; then
|
|
|
+ echo "Management token: $token"
|
|
|
+ fi
|
|
|
|
|
|
-# Enhanced git clone function
|
|
|
-function gc {
|
|
|
- if [[ "$1" == */* ]]
|
|
|
- then
|
|
|
- git clone "https://github.com/$1" "${@:2}"
|
|
|
- else
|
|
|
- git clone "https://github.com/marianozunino/$1" "${@:2}"
|
|
|
- fi
|
|
|
-}
|
|
|
+ success=true
|
|
|
+ break
|
|
|
+ fi
|
|
|
+ fi
|
|
|
|
|
|
-# Improved file sharing with croc
|
|
|
-function croc-send {
|
|
|
- croc send --code mzunino "$@"
|
|
|
-}
|
|
|
+ (( attempt++ ))
|
|
|
+ done
|
|
|
|
|
|
-function croc-receive {
|
|
|
- croc --yes mzunino
|
|
|
+ if ! $success; then
|
|
|
+ echo "× Failed to upload file after $max_attempts attempts"
|
|
|
+ return 1
|
|
|
+ fi
|
|
|
}
|
|
|
|
|
|
-# Fix swaymsg when inside tmux
|
|
|
-if [[ -v TMUX ]]; then
|
|
|
- function swaymsg {
|
|
|
- export SWAYSOCK=$XDG_RUNTIME_DIR/sway-ipc.$UID.$(pgrep -x sway).sock
|
|
|
- command swaymsg "$@"
|
|
|
- }
|
|
|
-fi
|
|
|
-
|
|
|
-# Expose local port to internet
|
|
|
function expose() {
|
|
|
if [ -z "$1" ]; then
|
|
|
echo "Usage: expose <port>"
|
|
|
- return
|
|
|
+ return 1
|
|
|
fi
|
|
|
ssh marianozunino@srv.us -R 1:localhost:$1
|
|
|
}
|
|
|
|
|
|
-# Helper function for command existence check
|
|
|
-function _has {
|
|
|
- return $( whence $1 >/dev/null )
|
|
|
-}
|
|
|
-
|
|
|
-# Sublime merge shortcut
|
|
|
-function sm {
|
|
|
- /opt/sublime_merge/sublime_merge $1
|
|
|
-}
|
|
|
-
|
|
|
-# Edit nvim config
|
|
|
-function vimrc {
|
|
|
- cd $XDG_CONFIG_HOME/nvim
|
|
|
- nvim
|
|
|
- cd -
|
|
|
-}
|
|
|
-
|
|
|
-# Edit zsh config
|
|
|
-function zshrc {
|
|
|
- cd $XDG_CONFIG_HOME/zsh
|
|
|
- nvim
|
|
|
- cd -
|
|
|
-}
|
|
|
-
|
|
|
-# Find process using a port
|
|
|
function ppid {
|
|
|
lsof -i :$1
|
|
|
}
|
|
|
|
|
|
-alias pport=ppid
|
|
|
+alias pport="ppid"
|
|
|
|
|
|
-# Kubernetes port forwarding helper
|
|
|
+# KUBERNETES AND DEVOPS
|
|
|
function kf {
|
|
|
if [ -z "$1" ]; then
|
|
|
echo "Usage: kf <cluster> [service-name]"
|
|
|
- return
|
|
|
+ return 1
|
|
|
fi
|
|
|
|
|
|
local namespace="oc-app"
|
|
|
@@ -210,6 +229,36 @@ function kf {
|
|
|
sudo -E kubefwd svc -n ${namespace} -x ${cluster} ${svc_filter}
|
|
|
}
|
|
|
|
|
|
+# SYSTEM AND UTILITY FUNCTIONS
|
|
|
+# Lazy-load handler for heavy tools
|
|
|
+function _lazy_load() {
|
|
|
+ local cmd="$1"
|
|
|
+ local loader="$2"
|
|
|
+
|
|
|
+ eval "${cmd}() {
|
|
|
+ unfunction $cmd
|
|
|
+ eval \"\$($loader)\"
|
|
|
+ $cmd \"\$@\"
|
|
|
+ }"
|
|
|
+}
|
|
|
+
|
|
|
+# Example: lazy load kubectl completion
|
|
|
+_lazy_load kubectl "kubectl completion zsh"
|
|
|
+
|
|
|
+function wacom {
|
|
|
+ if [ "$XDG_SESSION_TYPE" = "wayland" ]; then
|
|
|
+ systemctl --user enable opentabletdriver --now
|
|
|
+ otd loadsettings ~/Sync/wacom/wacom.json
|
|
|
+ else
|
|
|
+ xsetwacom --set "Wacom One by Wacom S Pen stylus" ResetArea
|
|
|
+ xsetwacom --set "Wacom One by Wacom S Pen stylus" MapToOutput DisplayPort-0
|
|
|
+ xsetwacom --set "Wacom One by Wacom S Pen stylus" Rotate half
|
|
|
+
|
|
|
+ xsetwacom --set "Wacom One by Wacom S Pen eraser" ResetArea
|
|
|
+ xsetwacom --set "Wacom One by Wacom S Pen eraser" MapToOutput DisplayPort-0
|
|
|
+ fi
|
|
|
+}
|
|
|
+
|
|
|
function cat {
|
|
|
if [ -n "$SSH_TTY" ] || [ -n "$SSH_CLIENT" ] || [ -n "$SSH_CONNECTION" ]; then
|
|
|
bat --plain --paging=never "$@"
|
|
|
@@ -218,101 +267,48 @@ function cat {
|
|
|
fi
|
|
|
}
|
|
|
|
|
|
-# Enhanced PrivateBin sharing function
|
|
|
-function pb {
|
|
|
- local usage="Usage: pb [-b] [-e <expiration>] <file>"
|
|
|
- local burn_after_reading=false
|
|
|
- local expiration="1week"
|
|
|
-
|
|
|
- while getopts ":be:" opt; do
|
|
|
- case ${opt} in
|
|
|
- b )
|
|
|
- burn_after_reading=true
|
|
|
- ;;
|
|
|
- e )
|
|
|
- expiration=$OPTARG
|
|
|
- ;;
|
|
|
- \? )
|
|
|
- echo "Invalid option: -$OPTARG" >&2
|
|
|
- echo $usage
|
|
|
- return 1
|
|
|
- ;;
|
|
|
- : )
|
|
|
- echo "Option -$OPTARG requires an argument." >&2
|
|
|
- echo $usage
|
|
|
- return 1
|
|
|
- ;;
|
|
|
- esac
|
|
|
- done
|
|
|
- shift $((OPTIND -1))
|
|
|
-
|
|
|
- if [ $# -eq 0 ]; then
|
|
|
- echo $usage
|
|
|
- return 1
|
|
|
- fi
|
|
|
-
|
|
|
- local file=$1
|
|
|
- if [ ! -f "$file" ]; then
|
|
|
- echo "Error: File '$file' not found." >&2
|
|
|
- return 1
|
|
|
- fi
|
|
|
-
|
|
|
- # Check for required commands
|
|
|
- for cmd in privatebin wl-copy; do
|
|
|
- if ! command -v $cmd &> /dev/null; then
|
|
|
- echo "Error: '$cmd' command not found. Please install it." >&2
|
|
|
- return 1
|
|
|
- fi
|
|
|
- done
|
|
|
-
|
|
|
- # Prepare the command
|
|
|
- local cmd="privatebin create --filename $file --expire $expiration"
|
|
|
- if $burn_after_reading; then
|
|
|
- cmd="$cmd --burn-after-reading"
|
|
|
- fi
|
|
|
-
|
|
|
- # Run command and handle result
|
|
|
- local result
|
|
|
- result=$(eval "$cmd" 2>&1)
|
|
|
- if [ $? -ne 0 ]; then
|
|
|
- echo "Error: Failed to upload file to PrivateBin. Details:" >&2
|
|
|
- echo "$result" >&2
|
|
|
- return 1
|
|
|
- fi
|
|
|
+function _has {
|
|
|
+ return $( whence $1 >/dev/null )
|
|
|
+}
|
|
|
|
|
|
- echo $result
|
|
|
- echo "$result" | wl-copy
|
|
|
- echo "PrivateBin link copied to clipboard."
|
|
|
- notify-send "PrivateBin" "Link copied to clipboard" 2>/dev/null || true
|
|
|
+# History-based directory navigation
|
|
|
+function cdr {
|
|
|
+ local dir
|
|
|
+ dir=$(dirs -pl | awk '!x[$0]++' | fzf --height 40% --reverse)
|
|
|
+ [[ -n "$dir" ]] && cd "$dir"
|
|
|
}
|
|
|
|
|
|
-# Load autocomplete files
|
|
|
+if [[ -v TMUX ]]; then
|
|
|
+ function swaymsg {
|
|
|
+ export SWAYSOCK=$XDG_RUNTIME_DIR/sway-ipc.$UID.$(pgrep -x sway).sock
|
|
|
+ command swaymsg "$@"
|
|
|
+ }
|
|
|
+fi
|
|
|
+
|
|
|
+# COMPLETIONS
|
|
|
for completion_file in ~/.local/share/zsh/*-autocomplete.zsh; do
|
|
|
if [ -f "$completion_file" ]; then
|
|
|
source "$completion_file"
|
|
|
fi
|
|
|
done
|
|
|
|
|
|
-# Initialize completions for common tools
|
|
|
if command -v rop &> /dev/null; then eval "$(rop completion zsh)"; fi
|
|
|
if command -v goq &> /dev/null; then eval "$(goq completion zsh)"; fi
|
|
|
if command -v kubefwd &> /dev/null; then eval "$(kubefwd completion zsh)"; fi
|
|
|
if command -v bombadil &> /dev/null; then eval "$(bombadil generate-completions zsh)"; fi
|
|
|
if command -v eza &> /dev/null; then compdef eza=ls; fi
|
|
|
|
|
|
-function dc() {
|
|
|
- if ! git rev-parse --is-inside-work-tree &>/dev/null; then
|
|
|
- echo "Error: Not in a git repository"
|
|
|
- return 1
|
|
|
- fi
|
|
|
-
|
|
|
- if [[ -z $(git status --porcelain) ]]; then
|
|
|
- echo "No changes to commit"
|
|
|
- return 0
|
|
|
- fi
|
|
|
+# ALIASES
|
|
|
+yarn() { echo 🖕; }
|
|
|
+yarnpkg() { echo 🖕; }
|
|
|
+pnpm() { echo 🖕; }
|
|
|
+pn() { echo 🖕; }
|
|
|
+pnpx() { echo 🖕; }
|
|
|
+npm() { echo 🖕; }
|
|
|
|
|
|
- git add .
|
|
|
- local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
|
|
|
- git commit -m "dev: automated commit - ${timestamp}" --no-gpg-sign
|
|
|
- git push &>/dev/null
|
|
|
-}
|
|
|
+alias p='_package_manager'
|
|
|
+alias fo='fopen'
|
|
|
+alias drop='upload_file'
|
|
|
+alias dump='upload_file'
|
|
|
+alias pport=ppid
|
|
|
+alias unChonk="echo '🧹 Starting the great node_modules purge...' && find . -name 'node_modules' -type d -prune -exec sh -c 'echo \"💥 Deleting {}\" && rm -rf \"{}\"' \;"
|