major zsh cleanup
This commit is contained in:
1 parent
c9ab492c60
commit
a9ef0503c7
4 files changed
+335
-210
No files matched your search
@@ -107,3 +107,13 @@ set -ga update-environment TERM_PROGRAM
|
|||||||
|
|
||||||
run '~/.config/tmux/plugins/tpm/tpm'
|
run '~/.config/tmux/plugins/tpm/tpm'
|
||||||
|
|
||||||
|
# Pane-Titel anzeigen
|
||||||
|
set -g pane-border-status top
|
||||||
|
set -g pane-border-format ' #{pane_index}: #{pane_title} '
|
||||||
|
|
||||||
|
|
||||||
|
set -g window-status-format \
|
||||||
|
' 🪟 #I:#W '
|
||||||
|
|
||||||
|
set -g window-status-current-format \
|
||||||
|
'#[bold] 🟢 #I:#W #[default]'
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
|
||||||
|
# --- Bandcamp ----------------------------------------------------------------
|
||||||
|
|
||||||
|
# bandcampdl <url>: download an album/track as MP3 (best quality) with
|
||||||
|
# metadata and cover art, sorted into Artist/Year - Album/
|
||||||
|
bandcampdl() {
|
||||||
|
if [[ -z "$1" ]]; then
|
||||||
|
echo "Usage: bandcampdl <bandcamp-url>"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
yt-dlp \
|
||||||
|
-x \
|
||||||
|
--audio-format mp3 \
|
||||||
|
--audio-quality 0 \
|
||||||
|
--embed-metadata \
|
||||||
|
--embed-thumbnail \
|
||||||
|
--convert-thumbnails jpg \
|
||||||
|
-o "%(album_artist)s/%(release_year)s - %(album)s/%(album_artist)s - %(album)s - %(track_number)02d - %(title)s.%(ext)s" \
|
||||||
|
"$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# bandcampbatch <file>: run bandcampdl for every URL in a file
|
||||||
|
# (empty lines and lines starting with # are skipped)
|
||||||
|
bandcampbatch() {
|
||||||
|
local file="$1" url
|
||||||
|
|
||||||
|
if [[ ! -r "$file" ]]; then
|
||||||
|
echo "Usage: bandcampbatch <url-file>"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r url; do
|
||||||
|
[[ -z "$url" || "$url" == \#* ]] && continue
|
||||||
|
bandcampdl "$url"
|
||||||
|
done < "$file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# bandcamplist <https://band.bandcamp.com/music> [output.txt]:
|
||||||
|
# write all album/track URLs of an artist to a file
|
||||||
|
# (default: bandcamp-<band>.txt) - input for bandcampbatch
|
||||||
|
bandcamplist() {
|
||||||
|
local url outfile tmpfile band count
|
||||||
|
|
||||||
|
if (( ! $+commands[yt-dlp] )); then
|
||||||
|
echo "Fehler: yt-dlp wurde nicht gefunden."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( $# < 1 || $# > 2 )); then
|
||||||
|
echo "Usage:"
|
||||||
|
echo " bandcamplist <https://band.bandcamp.com/music> [output.txt]"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
url="$1"
|
||||||
|
|
||||||
|
# zsh stores capture groups of =~ in $match
|
||||||
|
if [[ ! "$url" =~ ^https?://([^.]+)\.bandcamp\.com/music/?$ ]]; then
|
||||||
|
echo "Fehler: Keine gueltige Bandcamp-/music-URL:"
|
||||||
|
echo " $url"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
band="${match[1]}"
|
||||||
|
outfile="${2:-bandcamp-${band}.txt}"
|
||||||
|
tmpfile=$(mktemp)
|
||||||
|
|
||||||
|
if ! yt-dlp --flat-playlist --print webpage_url "$url" | sort -u > "$tmpfile"; then
|
||||||
|
rm -f "$tmpfile"
|
||||||
|
echo "Fehler beim Abrufen der Links."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
count=$(wc -l < "$tmpfile")
|
||||||
|
|
||||||
|
if (( count == 0 )); then
|
||||||
|
rm -f "$tmpfile"
|
||||||
|
echo "Keine Album- oder Track-Links gefunden."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mv "$tmpfile" "$outfile"
|
||||||
|
echo "✓ $count Links nach '$outfile' geschrieben."
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
if [[ -n "$TMUX" ]]; then
|
||||||
|
autoload -Uz add-zsh-hook
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Basisname des Windows aus aktuellem Verzeichnis
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
_tmux_set_base_window_name() {
|
||||||
|
local name
|
||||||
|
|
||||||
|
if [[ "$PWD" == "$HOME" ]]; then
|
||||||
|
name="sebastian"
|
||||||
|
else
|
||||||
|
name="${PWD:t}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Basisnamen separat merken
|
||||||
|
tmux set-option \
|
||||||
|
-w \
|
||||||
|
-t "$TMUX_PANE" \
|
||||||
|
@base_window_name "$name" \
|
||||||
|
2>/dev/null
|
||||||
|
|
||||||
|
_tmux_update_window_name
|
||||||
|
}
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Window-Name aus Basisname + allen SSH-Sessions dieses Windows bauen
|
||||||
|
#
|
||||||
|
# Beispiel:
|
||||||
|
# projects 🔐 P1→labgw P4→prod
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
_tmux_update_window_name() {
|
||||||
|
local base ssh_info line
|
||||||
|
|
||||||
|
base="$(
|
||||||
|
tmux show-options \
|
||||||
|
-w \
|
||||||
|
-v \
|
||||||
|
-t "$TMUX_PANE" \
|
||||||
|
@base_window_name \
|
||||||
|
2>/dev/null
|
||||||
|
)"
|
||||||
|
|
||||||
|
[[ -z "$base" ]] && base="${PWD:t}"
|
||||||
|
|
||||||
|
ssh_info=""
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
[[ -z "$line" ]] && continue
|
||||||
|
|
||||||
|
if [[ -n "$ssh_info" ]]; then
|
||||||
|
ssh_info+=" "
|
||||||
|
fi
|
||||||
|
|
||||||
|
ssh_info+="$line"
|
||||||
|
done < <(
|
||||||
|
tmux list-panes \
|
||||||
|
-t "$TMUX_PANE" \
|
||||||
|
-F '#{?@ssh_host,P#{pane_index}→#{@ssh_host},}' \
|
||||||
|
2>/dev/null
|
||||||
|
)
|
||||||
|
|
||||||
|
if [[ -n "$ssh_info" ]]; then
|
||||||
|
tmux rename-window \
|
||||||
|
-t "$TMUX_PANE" \
|
||||||
|
"${base} 🔐 ${ssh_info}" \
|
||||||
|
2>/dev/null
|
||||||
|
else
|
||||||
|
tmux rename-window \
|
||||||
|
-t "$TMUX_PANE" \
|
||||||
|
"$base" \
|
||||||
|
2>/dev/null
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
add-zsh-hook chpwd _tmux_set_base_window_name
|
||||||
|
_tmux_set_base_window_name
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# SSH wrapper
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
ssh() {
|
||||||
|
local host rc
|
||||||
|
|
||||||
|
# Bewusst SSH-Alias nehmen:
|
||||||
|
# ssh labgw
|
||||||
|
# zeigt "labgw", nicht die dahinterliegende IP.
|
||||||
|
host="$(
|
||||||
|
command ssh -G "$@" 2>/dev/null |
|
||||||
|
awk '$1 == "host" { print $2; exit }'
|
||||||
|
)"
|
||||||
|
|
||||||
|
if [[ -n "$host" ]]; then
|
||||||
|
tmux set-option \
|
||||||
|
-p \
|
||||||
|
-t "$TMUX_PANE" \
|
||||||
|
@ssh_host "$host" \
|
||||||
|
2>/dev/null
|
||||||
|
|
||||||
|
_tmux_update_window_name
|
||||||
|
fi
|
||||||
|
|
||||||
|
command ssh "$@"
|
||||||
|
rc=$?
|
||||||
|
|
||||||
|
# SSH-Markierung dieses Panes entfernen
|
||||||
|
tmux set-option \
|
||||||
|
-p \
|
||||||
|
-u \
|
||||||
|
-t "$TMUX_PANE" \
|
||||||
|
@ssh_host \
|
||||||
|
2>/dev/null
|
||||||
|
|
||||||
|
_tmux_update_window_name
|
||||||
|
|
||||||
|
return $rc
|
||||||
|
}
|
||||||
|
fi
|
||||||
@@ -1,46 +1,55 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
# ~/.zshrc
|
# ~/.zshrc
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Reihenfolge ist hier Absicht:
|
# Interactive shell configuration. Environment and PATH live in ~/.zshenv.
|
||||||
# 1. Profiling-Schalter
|
|
||||||
# 2. tmux-exec (ganz oben, damit die aeussere Shell sich die Init spart)
|
|
||||||
# 3. billige Optionen / Keybindings / History
|
|
||||||
# 4. teure Sachen: compinit + gecachte eval-Ausgaben
|
|
||||||
# 5. Aliases, Funktionen, PATH
|
|
||||||
#
|
#
|
||||||
# Cache leeren nach Theme-/Tool-Update: zshrc-refresh
|
# Order matters:
|
||||||
# Startzeit messen: ZSHRC_PROFILE=1 zsh -i -c exit
|
# 1. Profiling switch
|
||||||
|
# 2. tmux autostart (exec early, so the outer shell skips all init work)
|
||||||
|
# 3. Cheap stuff: options, keybindings, history
|
||||||
|
# 4. Expensive stuff: completion system, cached init output, prompt
|
||||||
|
# 5. Aliases
|
||||||
|
# 6. Functions
|
||||||
|
# 7. tmux integration (~/.zsh/tmux.zsh)
|
||||||
|
# 8. Finish: self-compile, profiling report
|
||||||
|
#
|
||||||
|
# Clear caches after a theme/tool update: zshrc-refresh
|
||||||
|
# Measure startup time: ZSHRC_PROFILE=1 zsh -i -c exit
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# 1. Profiling (optional, per Env-Variable)
|
# 1. Profiling (opt-in via environment variable)
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
if [[ -n "$ZSHRC_PROFILE" ]]; then
|
[[ -n "$ZSHRC_PROFILE" ]] && zmodload zsh/zprof
|
||||||
zmodload zsh/zprof
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# 2. tmux-Autostart
|
# 2. tmux autostart
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Muss vor allem anderen stehen: die aeussere Shell wird durch tmux ersetzt und
|
# Must come first: the outer shell gets replaced by tmux, so there's no point
|
||||||
# muss deshalb gar nicht erst komplett initialisiert werden. Frueher lief das
|
# initializing it. The shell inside tmux runs this file again with $TMUX set.
|
||||||
# zshrc pro Terminalstart zweimal komplett durch (einmal aussen, einmal im
|
|
||||||
# tmux-Fenster) - das faellt damit weg.
|
|
||||||
#
|
#
|
||||||
# Terminalerkennung laeuft ueber Environment-Variablen statt ueber ps/proc,
|
# Terminals are detected via environment variables instead of ps//proc, which
|
||||||
# das spart ~6 Forks pro Shellstart.
|
# saves a handful of forks per shell start.
|
||||||
|
#
|
||||||
|
# Note: none of these variables survive an SSH login, so SSH sessions don't
|
||||||
|
# autostart tmux. Use ZSH_FORCE_TMUX=1 or uncomment the SSH line below.
|
||||||
|
#
|
||||||
|
# Overrides:
|
||||||
|
# ZSH_FORCE_TMUX=1 always start tmux
|
||||||
|
# ZSH_NO_TMUX=1 never start tmux
|
||||||
if [[ -o interactive && -z "$TMUX" && -z "$ZSHRC_PROFILE" && $UID -ne 0 && -t 1 ]]; then
|
if [[ -o interactive && -z "$TMUX" && -z "$ZSHRC_PROFILE" && $UID -ne 0 && -t 1 ]]; then
|
||||||
# IDEs und eingebettete Terminals explizit ausnehmen
|
# Leave IDEs and embedded terminals alone
|
||||||
if [[ -z "$TERMINAL_EMULATOR" && -z "$INSIDE_EMACS" \
|
if [[ -z "$TERMINAL_EMULATOR" && -z "$INSIDE_EMACS" \
|
||||||
&& -z "$VSCODE_INJECTION" && -z "$NVIM" ]]; then
|
&& -z "$VSCODE_INJECTION" && -z "$NVIM" ]]; then
|
||||||
|
|
||||||
_zsh_want_tmux=0
|
_zsh_want_tmux=0
|
||||||
[[ "$TERM_PROGRAM" == ghostty || -n "$GHOSTTY_RESOURCES_DIR" ]] && _zsh_want_tmux=1
|
[[ "$TERM_PROGRAM" == ghostty || -n "$GHOSTTY_RESOURCES_DIR" ]] && _zsh_want_tmux=1 # Ghostty
|
||||||
[[ -n "$KITTY_WINDOW_ID" ]] && _zsh_want_tmux=1
|
[[ -n "$KITTY_WINDOW_ID" ]] && _zsh_want_tmux=1 # Kitty
|
||||||
[[ -n "$VTE_VERSION" ]] && _zsh_want_tmux=1 # xfce4-terminal, gnome-terminal
|
[[ -n "$VTE_VERSION" ]] && _zsh_want_tmux=1 # GNOME Terminal, xfce4-terminal, Tilix
|
||||||
[[ -n "$ZSH_FORCE_TMUX" ]] && _zsh_want_tmux=1 # manueller Override
|
# [[ -n "$SSH_CONNECTION" ]] && _zsh_want_tmux=1 # SSH logins
|
||||||
|
[[ -n "$ZSH_FORCE_TMUX" ]] && _zsh_want_tmux=1
|
||||||
[[ -n "$ZSH_NO_TMUX" ]] && _zsh_want_tmux=0
|
[[ -n "$ZSH_NO_TMUX" ]] && _zsh_want_tmux=0
|
||||||
|
|
||||||
if (( _zsh_want_tmux )) && (( $+commands[tmux] )); then
|
if (( _zsh_want_tmux )) && (( $+commands[tmux] )); then
|
||||||
@@ -53,63 +62,58 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# 3. Grundoptionen, Keybindings, History
|
# 3. Options, keybindings, history
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
bindkey -e # Emacs-Keybindings, auch wenn EDITOR=vi
|
bindkey -e # Emacs keybindings, even if EDITOR=vi
|
||||||
setopt interactivecomments # "#" auf der Kommandozeile = Kommentar
|
setopt interactive_comments # allow "# comments" on the command line
|
||||||
|
|
||||||
HISTFILE=~/.zsh_history
|
HISTFILE=~/.zsh_history
|
||||||
HISTSIZE=50000 # Eintraege im RAM
|
HISTSIZE=50000 # entries kept in memory
|
||||||
SAVEHIST=50000 # Eintraege in der Datei
|
SAVEHIST=50000 # entries written to $HISTFILE
|
||||||
# (vorher stand SAVEHIST auf 1000 - HISTFILESIZE
|
|
||||||
# ist eine Bash-Variable und hat nichts getan)
|
|
||||||
|
|
||||||
setopt hist_ignore_all_dups # aeltere Duplikate rauswerfen
|
setopt hist_ignore_all_dups # drop older duplicates
|
||||||
setopt hist_ignore_space # Zeilen mit fuehrendem Leerzeichen nicht merken
|
setopt hist_ignore_space # don't record lines starting with a space
|
||||||
setopt hist_reduce_blanks
|
setopt hist_reduce_blanks # squeeze superfluous whitespace
|
||||||
setopt hist_verify # Expansion erst anzeigen, dann ausfuehren
|
setopt hist_verify # show history expansion before running it
|
||||||
setopt extended_history # mit Zeitstempel (Ersatz fuer HISTTIMEFORMAT)
|
setopt extended_history # store timestamps
|
||||||
setopt share_history # History zwischen laufenden Shells teilen
|
setopt share_history # share history between running shells
|
||||||
|
|
||||||
# Falls die Shell sich beim Start traege anfuehlt, obwohl sonst alles schnell
|
# If prompts ever feel sluggish: share_history re-reads the history file on
|
||||||
# ist: share_history liest bei jedem Prompt die History-Datei neu ein. Dann
|
# every prompt. Alternative that only appends:
|
||||||
# stattdessen mal testen:
|
|
||||||
# unsetopt share_history
|
# unsetopt share_history
|
||||||
# setopt inc_append_history
|
# setopt inc_append_history
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# 4a. Cache-Verzeichnis
|
# 4a. Cache directory and prompt theme
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
ZSH_CACHE_DIR=${XDG_CACHE_HOME:-$HOME/.cache}/zsh
|
ZSH_CACHE_DIR=${XDG_CACHE_HOME:-$HOME/.cache}/zsh
|
||||||
[[ -d $ZSH_CACHE_DIR ]] || mkdir -p $ZSH_CACHE_DIR
|
[[ -d $ZSH_CACHE_DIR ]] || mkdir -p $ZSH_CACHE_DIR
|
||||||
|
|
||||||
# Pfad zum oh-my-posh-Theme
|
|
||||||
OMP_CONFIG=$HOME/.zsh/rudolfs-dark.omp.json
|
OMP_CONFIG=$HOME/.zsh/rudolfs-dark.omp.json
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# 4b. Completion-System
|
# 4b. Completion system
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Nacktes "compinit" laeuft bei jedem Start compaudit und statet alle
|
# A bare "compinit" runs compaudit and stats every $fpath directory on each
|
||||||
# $fpath-Verzeichnisse ab - hunderte stat()-Calls. Bei warmem Page-Cache egal,
|
# start - hundreds of stat() calls, noticeable with a cold page cache.
|
||||||
# bei kaltem Cache (also genau nach Idle) der teuerste Einzelposten.
|
# So: full check once a day, otherwise load straight from the dump.
|
||||||
# Deshalb: voller Audit nur einmal pro Tag, sonst direkt aus dem Dump.
|
|
||||||
() {
|
() {
|
||||||
emulate -L zsh
|
emulate -L zsh
|
||||||
setopt local_options extended_glob
|
setopt extended_glob
|
||||||
|
|
||||||
local zdump=$ZSH_CACHE_DIR/zcompdump
|
local zdump=$ZSH_CACHE_DIR/zcompdump
|
||||||
|
|
||||||
autoload -Uz compinit
|
autoload -Uz compinit
|
||||||
if [[ -n $zdump(#qNmh-24) ]]; then
|
if [[ -n $zdump(#qNmh-24) ]]; then
|
||||||
compinit -C -d $zdump # Dump juenger als 24h -> Check ueberspringen
|
compinit -C -d $zdump # dump younger than 24h -> skip the audit
|
||||||
else
|
else
|
||||||
compinit -d $zdump # einmal taeglich voll durchlaufen
|
compinit -d $zdump # full run, once a day
|
||||||
touch $zdump
|
touch $zdump
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Dump kompilieren: laedt deutlich schneller, gerade von kalter Platte
|
# Compiled dump loads noticeably faster
|
||||||
if [[ ! -s ${zdump}.zwc || $zdump -nt ${zdump}.zwc ]]; then
|
if [[ ! -s ${zdump}.zwc || $zdump -nt ${zdump}.zwc ]]; then
|
||||||
zcompile $zdump 2>/dev/null
|
zcompile $zdump 2>/dev/null
|
||||||
fi
|
fi
|
||||||
@@ -126,41 +130,38 @@ zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p
|
|||||||
zstyle ':completion:*' use-compctl false
|
zstyle ':completion:*' use-compctl false
|
||||||
zstyle ':completion:*' verbose true
|
zstyle ':completion:*' verbose true
|
||||||
|
|
||||||
# Completion-Ergebnisse cachen (z.B. apt-Paketlisten)
|
# Cache expensive completion results (e.g. apt package lists)
|
||||||
zstyle ':completion:*' use-cache on
|
zstyle ':completion:*' use-cache on
|
||||||
zstyle ':completion:*' cache-path $ZSH_CACHE_DIR/compcache
|
zstyle ':completion:*' cache-path $ZSH_CACHE_DIR/compcache
|
||||||
|
|
||||||
# list-colors: die Zeile "zstyle ':completion:*' list-colors ''" im alten zshrc
|
# kill: colored process list
|
||||||
# hat die LS_COLORS-Zuweisung direkt darueber wieder plattgemacht - deshalb hier
|
|
||||||
# nur noch einmal, weiter unten nach dircolors.
|
|
||||||
|
|
||||||
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'
|
zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'
|
||||||
zstyle ':completion:*:kill:*' command 'ps -u $USER -o pid,%cpu,tty,cputime,cmd'
|
zstyle ':completion:*:kill:*' command 'ps -u $USER -o pid,%cpu,tty,cputime,cmd'
|
||||||
|
|
||||||
# SSH-Hosts: mit "zstyle -e" wird das erst beim Tab-Druck ausgewertet,
|
# ssh: hosts from ~/.ssh/config (+ config.d). "zstyle -e" evaluates this lazily
|
||||||
# nicht mehr bei jedem Shellstart.
|
# on <Tab>, not on every shell start. Wildcard patterns are filtered out.
|
||||||
zstyle -e ':completion:*:*:ssh:*' hosts \
|
zstyle -e ':completion:*:*:ssh:*' hosts \
|
||||||
'reply=(${(f)"$(grep -h "^Host " ~/.ssh/config ~/.ssh/config.d/*(N) 2>/dev/null | sed "s/^Host //" | tr " " "\n" | grep -v "[*?]")"})'
|
'reply=(${(f)"$(grep -h "^Host " ~/.ssh/config ~/.ssh/config.d/*(N) 2>/dev/null | sed "s/^Host //" | tr " " "\n" | grep -v "[*?]")"})'
|
||||||
|
|
||||||
|
# (list-colors for files is set further down, once LS_COLORS exists)
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# 4c. Gecachte Init-Ausgaben (television, dircolors)
|
# 4c. Cached init output (television, dircolors)
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Beide Tools geben bei jedem Start denselben statischen Shell-Code aus. Statt
|
# Both tools print the same static shell code on every run. Instead of forking
|
||||||
# sie jedes Mal zu starten, wird die Ausgabe einmal in eine Datei geschrieben,
|
# them each time, their output is written to one file, compiled, and sourced.
|
||||||
# kompiliert und danach nur noch gesourct.
|
# The cache is rebuilt when ~/.dircolors or the tv binary is newer than it.
|
||||||
#
|
#
|
||||||
# WICHTIG: die Bloecke brauchen eine Trennzeile. Manche Tools beenden ihre
|
# Each block is followed by an explicit newline: some tools end their output
|
||||||
# Ausgabe ohne Newline, dann klebt die erste Zeile des naechsten Blocks hinten
|
# without one, which would glue the next block onto the last line.
|
||||||
# an der letzten Zeile des vorigen - und man bekommt kaputte Pfade wie
|
|
||||||
# ".../init.26.0.5.abc..zsh#compdef".
|
|
||||||
() {
|
() {
|
||||||
emulate -L zsh
|
emulate -L zsh
|
||||||
local cache=$ZSH_CACHE_DIR/init.zsh
|
local cache=$ZSH_CACHE_DIR/init.zsh
|
||||||
local stale=0
|
local stale=0
|
||||||
|
|
||||||
[[ -s $cache ]] || stale=1
|
[[ -s $cache ]] || stale=1
|
||||||
[[ -f ~/.dircolors && ~/.dircolors -nt $cache ]] && stale=1
|
[[ -f ~/.dircolors && ~/.dircolors -nt $cache ]] && stale=1
|
||||||
[[ -n $commands[tv] && $commands[tv] -nt $cache ]] && stale=1
|
[[ -n $commands[tv] && $commands[tv] -nt $cache ]] && stale=1
|
||||||
|
|
||||||
if (( stale )); then
|
if (( stale )); then
|
||||||
@@ -185,46 +186,26 @@ zstyle -e ':completion:*:*:ssh:*' hosts \
|
|||||||
[[ -s $cache ]] && source $cache
|
[[ -s $cache ]] && source $cache
|
||||||
}
|
}
|
||||||
|
|
||||||
# oh-my-posh cacht seinen Init-Code seit v26 selbst unter ~/.cache/oh-my-posh/
|
# LS_COLORS is set now -> colorize file completion
|
||||||
# (Dateiname enthaelt Version + Config-Hash). "oh-my-posh init zsh" gibt nur
|
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
|
||||||
# noch einen kleinen Stub aus, der diese Datei sourct. Ein eigener Cache
|
|
||||||
# darueber bringt deshalb nichts und bricht, sobald sich Version oder Theme
|
|
||||||
# aendert - der Stub zeigt dann auf einen Pfad, den es nicht mehr gibt.
|
# -----------------------------------------------------------------------------
|
||||||
|
# 4d. Prompt (oh-my-posh)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Since v26, oh-my-posh caches its init code itself under ~/.cache/oh-my-posh/
|
||||||
|
# (file name contains version + config hash); "init zsh" only prints a small
|
||||||
|
# stub that sources it. Caching that stub again would break on every update.
|
||||||
|
#
|
||||||
|
# If the prompt is suddenly plain ("host%"), oh-my-posh isn't in PATH -
|
||||||
|
# check ~/.zshenv.
|
||||||
if (( $+commands[oh-my-posh] )); then
|
if (( $+commands[oh-my-posh] )); then
|
||||||
eval "$(oh-my-posh init zsh --config "$OMP_CONFIG")"
|
eval "$(oh-my-posh init zsh --config "$OMP_CONFIG")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Jetzt steht LS_COLORS -> Completion einfaerben
|
|
||||||
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
|
|
||||||
|
|
||||||
# Cache verwerfen und Shell neu starten
|
|
||||||
zshrc-refresh() {
|
|
||||||
rm -f $ZSH_CACHE_DIR/init.zsh{,.zwc} \
|
|
||||||
$ZSH_CACHE_DIR/zcompdump{,.zwc} \
|
|
||||||
~/.zshrc.zwc
|
|
||||||
# oh-my-posh raeumt seinen eigenen Cache normalerweise selbst auf.
|
|
||||||
# Falls das Prompt nach einem Update zickt, zusaetzlich:
|
|
||||||
# rm -rf ~/.cache/oh-my-posh
|
|
||||||
echo "Cache geleert, starte Shell neu ..."
|
|
||||||
exec zsh
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# 5. PATH
|
# 5. Aliases
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
typeset -U path PATH # automatisch dedupliziert
|
|
||||||
path=(
|
|
||||||
$HOME/.local/bin # pip3 --user
|
|
||||||
$path
|
|
||||||
$HOME/go/bin
|
|
||||||
$HOME/.cargo/bin
|
|
||||||
)
|
|
||||||
path=($^path(N-/)) # nur existierende Verzeichnisse behalten
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
# 6. Aliases
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
alias ls='ls --color=auto'
|
alias ls='ls --color=auto'
|
||||||
alias grep='grep --color=auto'
|
alias grep='grep --color=auto'
|
||||||
@@ -236,113 +217,23 @@ alias egrep='egrep --color=auto'
|
|||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# 7. tmux-Fenstername = aktuelles Verzeichnis
|
# 6. Functions
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
# Vorher via PROMPT_COMMAND - das ist eine Bash-Variable und hat in zsh nie
|
|
||||||
# funktioniert. Jetzt korrekt als chpwd-Hook: laeuft nur beim Verzeichnis-
|
|
||||||
# wechsel, nicht bei jedem Prompt.
|
|
||||||
if [[ -n "$TMUX" ]]; then
|
|
||||||
autoload -Uz add-zsh-hook
|
|
||||||
_tmux_rename_window() { tmux rename-window "${PWD:t}" 2>/dev/null }
|
|
||||||
add-zsh-hook chpwd _tmux_rename_window
|
|
||||||
_tmux_rename_window
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
# 8. Funktionen
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
# yazi mit cwd-Uebernahme
|
# zshrc-refresh: clear all zsh caches and restart the shell
|
||||||
function y() {
|
zshrc-refresh() {
|
||||||
local tmp="$(mktemp -t "yazi-cwd.XXXXXX")" cwd
|
rm -f $ZSH_CACHE_DIR/init.zsh{,.zwc} \
|
||||||
yazi "$@" --cwd-file="$tmp"
|
$ZSH_CACHE_DIR/zcompdump{,.zwc} \
|
||||||
IFS= read -r -d '' cwd < "$tmp"
|
~/.zshrc.zwc
|
||||||
[ -n "$cwd" ] && [ "$cwd" != "$PWD" ] && builtin cd -- "$cwd"
|
# oh-my-posh normally cleans up its own cache. If the prompt misbehaves
|
||||||
rm -f -- "$tmp"
|
# after an update, additionally run:
|
||||||
|
# rm -rf ~/.cache/oh-my-posh
|
||||||
|
echo "Cache removed, restart shell"
|
||||||
|
exec zsh
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- Bandcamp -----------------------------------------------------------------
|
# tm [name]: create or switch to a tmux session (default: main)
|
||||||
|
tm() {
|
||||||
function bandcampdl() {
|
|
||||||
yt-dlp \
|
|
||||||
-x \
|
|
||||||
--audio-format mp3 \
|
|
||||||
--audio-quality 0 \
|
|
||||||
--embed-metadata \
|
|
||||||
--embed-thumbnail \
|
|
||||||
--convert-thumbnails jpg \
|
|
||||||
-o "%(album_artist)s/%(release_year)s - %(album)s/%(album_artist)s - %(album)s - %(track_number)02d - %(title)s.%(ext)s" \
|
|
||||||
"$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
function bandcampbatch() {
|
|
||||||
local file="$1"
|
|
||||||
|
|
||||||
while IFS= read -r url; do
|
|
||||||
[[ -z "$url" || "$url" == \#* ]] && continue
|
|
||||||
bandcampdl "$url"
|
|
||||||
done < "$file"
|
|
||||||
}
|
|
||||||
|
|
||||||
function bandcamplist() {
|
|
||||||
local url outfile tmpfile band count
|
|
||||||
|
|
||||||
command -v yt-dlp >/dev/null 2>&1 || {
|
|
||||||
echo "Fehler: yt-dlp wurde nicht gefunden."
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if (( $# < 1 || $# > 2 )); then
|
|
||||||
echo "Usage:"
|
|
||||||
echo " bandcamplist <https://band.bandcamp.com/music> [output.txt]"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
url="$1"
|
|
||||||
|
|
||||||
if [[ ! "$url" =~ ^https?://([^.]+)\.bandcamp\.com/music/?$ ]]; then
|
|
||||||
echo "Fehler: Keine gueltige Bandcamp-/music-URL:"
|
|
||||||
echo " $url"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
band="${match[1]}"
|
|
||||||
|
|
||||||
if [[ $# -eq 2 ]]; then
|
|
||||||
outfile="$2"
|
|
||||||
else
|
|
||||||
outfile="bandcamp-${band}.txt"
|
|
||||||
fi
|
|
||||||
|
|
||||||
tmpfile=$(mktemp)
|
|
||||||
|
|
||||||
if ! yt-dlp \
|
|
||||||
--flat-playlist \
|
|
||||||
--print webpage_url \
|
|
||||||
"$url" \
|
|
||||||
| sort -u > "$tmpfile"
|
|
||||||
then
|
|
||||||
rm -f "$tmpfile"
|
|
||||||
echo "Fehler beim Abrufen der Links."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
count=$(wc -l < "$tmpfile")
|
|
||||||
|
|
||||||
if (( count == 0 )); then
|
|
||||||
rm -f "$tmpfile"
|
|
||||||
echo "Keine Album- oder Track-Links gefunden."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mv "$tmpfile" "$outfile"
|
|
||||||
|
|
||||||
echo "✓ $count Links nach '$outfile' geschrieben."
|
|
||||||
}
|
|
||||||
|
|
||||||
# tm [name] -> Session anlegen oder hinwechseln (Default: main)
|
|
||||||
function tm() {
|
|
||||||
local s=${1:-main}
|
local s=${1:-main}
|
||||||
if [[ -n "$TMUX" ]]; then
|
if [[ -n "$TMUX" ]]; then
|
||||||
tmux has-session -t "=$s" 2>/dev/null || tmux new-session -d -s "$s"
|
tmux has-session -t "=$s" 2>/dev/null || tmux new-session -d -s "$s"
|
||||||
@@ -352,16 +243,37 @@ function tm() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# y: run yazi and cd into the directory it was closed in
|
||||||
|
y() {
|
||||||
|
local tmp="$(mktemp -t "yazi-cwd.XXXXXX")" cwd
|
||||||
|
yazi "$@" --cwd-file="$tmp"
|
||||||
|
IFS= read -r -d '' cwd < "$tmp"
|
||||||
|
[[ -n "$cwd" && "$cwd" != "$PWD" ]] && builtin cd -- "$cwd"
|
||||||
|
rm -f -- "$tmp"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Bandcamp Aliases
|
||||||
|
|
||||||
|
[[ -f ~/.zsh/bandcamp.zsh ]] && source ~/.zsh/bandcamp.zsh
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# 9. Abschluss
|
# 7. tmux integration
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Window names from the current directory plus active SSH hosts per pane.
|
||||||
|
# Only does something inside tmux.
|
||||||
|
[[ -f ~/.zsh/tmux.zsh ]] && source ~/.zsh/tmux.zsh
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# 8. Finish
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
# zshrc selbst kompilieren - zsh benutzt die .zwc-Datei automatisch, solange sie
|
# Compile this file. zsh picks up ~/.zshrc.zwc automatically as long as it is
|
||||||
# neuer ist als das Original. Nach jeder Aenderung wird sie hier neu gebaut.
|
# newer than ~/.zshrc, and it gets rebuilt here after every change.
|
||||||
if [[ ! -s ~/.zshrc.zwc || ~/.zshrc -nt ~/.zshrc.zwc ]]; then
|
if [[ ! -s ~/.zshrc.zwc || ~/.zshrc -nt ~/.zshrc.zwc ]]; then
|
||||||
zcompile ~/.zshrc 2>/dev/null
|
zcompile ~/.zshrc 2>/dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "$ZSHRC_PROFILE" ]]; then
|
[[ -n "$ZSHRC_PROFILE" ]] && zprof
|
||||||
zprof
|
|
||||||
fi
|
|
||||||
Reference in new issue
Block a user