111 lines
3.7 KiB
Bash
111 lines
3.7 KiB
Bash
setopt interactivecomments
|
|
|
|
HISTSIZE=100000
|
|
SAVEHIST=100000
|
|
setopt EXTENDED_HISTORY
|
|
setopt INC_APPEND_HISTORY
|
|
setopt SHARE_HISTORY
|
|
setopt HIST_EXPIRE_DUPS_FIRST
|
|
setopt HIST_IGNORE_DUPS
|
|
setopt HIST_IGNORE_ALL_DUPS
|
|
setopt HIST_FIND_NO_DUPS
|
|
setopt HIST_IGNORE_SPACE
|
|
setopt HIST_SAVE_NO_DUPS
|
|
setopt HIST_REDUCE_BLANKS
|
|
|
|
bindkey '^q' clear-screen
|
|
(( $+commands[nvim] )) && alias vim=nvim
|
|
(( $+commands[nvim] )) && export EDITOR=nvim VISUAL=nvim
|
|
alias sudo='sudo '
|
|
alias ls='ls --color=always'
|
|
alias cgrep='grep --color=always'
|
|
alias cdiff='git diff --color-words --no-index'
|
|
|
|
# Remove the files an archive extracted into the current directory.
|
|
# Lists what it will delete and asks first; -f skips the prompt, -n dry-runs.
|
|
# Directories are only removed if they end up empty.
|
|
delzip() {
|
|
emulate -L zsh
|
|
setopt local_options
|
|
|
|
local dry=0 force=0
|
|
while [[ $1 == -[nf] ]]; do
|
|
[[ $1 == -n ]] && dry=1 || force=1
|
|
shift
|
|
done
|
|
(( $# )) || { print -ru2 "usage: delzip [-n|-f] <archive.zip>..."; return 2 }
|
|
|
|
local zip entry parent
|
|
local -a entries files dirs
|
|
for zip in "$@"; do
|
|
[[ -f $zip ]] || { print -ru2 "delzip: no such file: $zip"; return 1 }
|
|
entries=("${(f)$(unzip -Z -1 -- $zip)}") || return 1
|
|
for entry in $entries; do
|
|
[[ -n $entry ]] || continue
|
|
# zip-slip guard: never touch anything outside the cwd
|
|
if [[ $entry == (/|~)* || $entry == (|*/)..(|/*) ]]; then
|
|
print -ru2 "delzip: refusing unsafe path: $entry"
|
|
return 1
|
|
fi
|
|
[[ $entry == */ ]] && dirs+=(${entry%/}) || files+=($entry)
|
|
# many archives omit directory entries, so infer them from the
|
|
# paths as well; unzip creates those dirs regardless
|
|
parent=${entry%/}
|
|
while [[ $parent == */* ]]; do
|
|
parent=${parent%/*}
|
|
dirs+=($parent)
|
|
done
|
|
done
|
|
done
|
|
dirs=(${(u)dirs})
|
|
|
|
# only keep what is actually on disk, so the list reflects reality;
|
|
# -L catches broken symlinks, which -e alone misses
|
|
local -a present
|
|
present=(); for entry in $files; do [[ -e $entry || -L $entry ]] && present+=($entry); done
|
|
files=($present)
|
|
present=(); for entry in $dirs; do [[ -d $entry ]] && present+=($entry); done
|
|
dirs=($present)
|
|
|
|
(( $#files + $#dirs )) || { print -ru2 "delzip: nothing to remove here (already gone?)"; return 1 }
|
|
|
|
if (( dry )); then
|
|
print -rl -- ${files} ${(O)dirs}
|
|
return 0
|
|
fi
|
|
|
|
if (( ! force )); then
|
|
[[ -t 0 ]] || { print -ru2 "delzip: not a terminal, use -f to skip the prompt"; return 1 }
|
|
print -r -- "delzip: remove ${#files} file(s) under ${PWD}:"
|
|
print -rl -- " "${^files[1,20]}
|
|
(( $#files > 20 )) && print -r -- " ... and $(( $#files - 20 )) more"
|
|
(( $#dirs )) && print -r -- "plus ${#dirs} directory/ies, if they end up empty."
|
|
read -q "?Proceed? [y/N] " || { print -r -- $'\naborted'; return 1 }
|
|
print
|
|
fi
|
|
|
|
(( $#files )) && rm -f -- $files
|
|
# deepest first, so parents can empty out; rmdir refuses non-empty dirs
|
|
for entry in ${(O)dirs}; do
|
|
[[ -d $entry ]] && rmdir -- $entry 2>/dev/null
|
|
done
|
|
return 0
|
|
}
|
|
export MITMPROXY_SSLKEYLOGFILE="$HOME/.mitmproxy/sslkeylogfile.txt"
|
|
|
|
unset ZSH_AUTOSUGGEST_USE_ASYNC
|
|
export LANG='en_US.UTF-8'
|
|
export LC_CTYPE='en_US.UTF-8'
|
|
export TIME_STYLE='long-iso'
|
|
|
|
pasteinit() {
|
|
OLD_SELF_INSERT=${${(s.:.)widgets[self-insert]}[2,3]}
|
|
zle -N self-insert url-quote-magic
|
|
}
|
|
pastefinish() {
|
|
zle -N self-insert "$OLD_SELF_INSERT"
|
|
}
|
|
zstyle :bracketed-paste-magic paste-init pasteinit
|
|
zstyle :bracketed-paste-magic paste-finish pastefinish
|
|
ZSH_AUTOSUGGEST_CLEAR_WIDGETS+=(bracketed-paste)
|