diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9eacd62..39bd3cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,6 +35,6 @@ jobs: - name: Dry-run bootstrap (headless, no security) run: | su tester -c 'cd ~/forge && ./bootstrap.sh --dry-run --yes --no-desktop --no-security' - - name: Validate stow packages link cleanly (zsh/git/tmux) + - name: Validate stow packages link cleanly (zsh/git/tmux/yazi) run: | - su tester -c 'cd ~/forge && stow --no --target=$HOME --dir dotfiles zsh git tmux 2>&1 | tee /tmp/stow.log; ! grep -i conflict /tmp/stow.log' + su tester -c 'cd ~/forge && stow --no --target=$HOME --dir dotfiles zsh git tmux yazi 2>&1 | tee /tmp/stow.log; ! grep -i conflict /tmp/stow.log' diff --git a/dotfiles/tmux/.config/tmux/tmux.conf b/dotfiles/tmux/.config/tmux/tmux.conf index 2d70987..9310834 100644 --- a/dotfiles/tmux/.config/tmux/tmux.conf +++ b/dotfiles/tmux/.config/tmux/tmux.conf @@ -18,6 +18,7 @@ set -g default-terminal "tmux-256color" set -ag terminal-overrides ",xterm-kitty:RGB,xterm-256color:RGB" set -sg escape-time 0 # pas de délai après Échap (crucial pour nvim) set -g focus-events on # nvim sait quand le pane reprend le focus +set -g allow-passthrough on # laisse passer le protocole graphique kitty (previews d'images yazi) set -g history-limit 50000 # scrollback généreux set -g base-index 1 # fenêtres numérotées à partir de 1 (plus proche du clavier) setw -g pane-base-index 1 diff --git a/dotfiles/yazi/.config/yazi/yazi.toml b/dotfiles/yazi/.config/yazi/yazi.toml new file mode 100644 index 0000000..3d854aa --- /dev/null +++ b/dotfiles/yazi/.config/yazi/yazi.toml @@ -0,0 +1,39 @@ +# Yazi 26.x — note the section is [mgr]; [manager] is the old deprecated name. +# Shared between macOS and Ubuntu: openers are split with `for =` rather than +# forked into two files, so there is only one config to keep in sync. + +[mgr] +ratio = [1, 3, 4] # parent | current | preview +sort_by = "natural" # file2 before file10 +sort_dir_first = true +linemode = "size" +show_hidden = false # toggle at runtime with . +show_symlink = true +scrolloff = 5 + +[preview] +max_width = 1200 # generous: kitty draws real pixels, not cells +max_height = 1200 +image_filter = "lanczos3" +tab_size = 2 + +[opener] +edit = [ + { run = '$EDITOR "$@"', desc = "$EDITOR", block = true }, +] +open = [ + { run = 'open "$@"', desc = "Open in default app", for = "macos", orphan = true }, + { run = 'xdg-open "$@"', desc = "Open in default app", for = "linux", orphan = true }, +] +reveal = [ + { run = 'open -R "$1"', desc = "Reveal in Finder", for = "macos", orphan = true }, + { run = 'xdg-open "$(dirname "$1")"', desc = "Reveal enclosing folder", for = "linux", orphan = true }, +] + +[open] +prepend_rules = [ + # Text-ish files go to $EDITOR instead of the desktop default app. + { url = "*.log", use = "edit" }, + { url = "*.toml", use = "edit" }, + { url = "*.lock", use = "edit" }, +] diff --git a/dotfiles/zsh/.zsh/functions/40-yazi.zsh b/dotfiles/zsh/.zsh/functions/40-yazi.zsh new file mode 100644 index 0000000..990981e --- /dev/null +++ b/dotfiles/zsh/.zsh/functions/40-yazi.zsh @@ -0,0 +1,15 @@ +# y: yazi wrapper that leaves you in the directory you quit from. +# Yazi runs in its own process, so a plain `yazi` call can't change the shell's +# cwd — it dumps the last directory into --cwd-file and we cd there ourselves. +y() { + # Usage: y [path] + local tmp cwd + tmp="$(mktemp -t yazi-cwd.XXXXXX)" || return + yazi --cwd-file="$tmp" "$@" + cwd="$(<"$tmp")" + # `command rm`: bare rm is aliased to trash here, and zsh expands aliases when + # the function is *defined*, which would litter the trash with every cwd file. + command rm -f -- "$tmp" + # Quitting with Q (instead of q) writes nothing, which keeps you put on purpose. + [ -n "$cwd" ] && [ "$cwd" != "$PWD" ] && builtin cd -- "$cwd" +} diff --git a/install/10-packages.sh b/install/10-packages.sh index 739c50f..edab9c7 100755 --- a/install/10-packages.sh +++ b/install/10-packages.sh @@ -11,7 +11,8 @@ ARCH="$(dpkg --print-architecture)" # amd64 / arm64 log "Core CLI tools from apt" apt_install \ zsh tmux neovim ripgrep fd-find bat jq tree htop btop \ - fzf zoxide direnv trash-cli unrar p7zip-full \ + fzf zoxide direnv trash-cli unrar p7zip-full unzip \ + ffmpeg poppler-utils imagemagick \ fonts-firacode # Ubuntu ships fd as `fdfind` and bat as `batcat`; expose the canonical names. @@ -87,4 +88,37 @@ fi # --- 8. tldr (tealdeer) ------------------------------------------------------ apt_install tealdeer || warn "tealdeer not in repos; skip (optional)" +# --- 9. yazi (TUI file manager) — release binary ----------------------------- +# Not packaged for Ubuntu 24.04, so we take the upstream zip. It ships two +# binaries (yazi + ya, the plugin/package manager) nested in a versioned dir. +# The image previews need ffmpeg / poppler / imagemagick from section 1, plus +# `allow-passthrough on` in tmux — see dotfiles/tmux. +if ! have yazi; then + log "Installing yazi" + YAZI_VER="$(curl -fsSL https://api.github.com/repos/sxyazi/yazi/releases/latest \ + | grep -Po '"tag_name": *"v\K[^"]*' || echo '26.9.1')" + case "$ARCH" in + amd64) YAZI_ARCH="x86_64" ;; + arm64) YAZI_ARCH="aarch64" ;; + *) YAZI_ARCH="$ARCH" ;; + esac + tmp="$(mktemp -d)" + if run bash -c "curl -fsSL 'https://github.com/sxyazi/yazi/releases/download/v${YAZI_VER}/yazi-${YAZI_ARCH}-unknown-linux-gnu.zip' -o '$tmp/yazi.zip'"; then + run unzip -q "$tmp/yazi.zip" -d "$tmp" + for b in yazi ya; do + bin="$(find "$tmp" -type f -name "$b" | head -n1)" + if [[ -n "$bin" ]]; then + run install -m 0755 "$bin" "$HOME/.local/bin/$b" + elif [[ "${FORGE_DRY_RUN:-0}" != "1" ]]; then + # Under --dry-run nothing was downloaded or unzipped, so an empty find + # is expected and warning about it would be a false alarm. + warn "yazi archive did not contain '$b'; check the upstream layout." + fi + done + else + warn "yazi download failed; install manually later." + fi + rm -rf "$tmp" +fi + ok "packages installed" diff --git a/install/50-stow.sh b/install/50-stow.sh index a43d833..73d19bf 100755 --- a/install/50-stow.sh +++ b/install/50-stow.sh @@ -12,7 +12,7 @@ DOTFILES="$FORGE_DIR/dotfiles" [[ -d "$DOTFILES" ]] || die "missing $DOTFILES" # Desktop packages only stow when a GUI is present. -PACKAGES=(zsh starship git tmux kitty aerc jira) +PACKAGES=(zsh starship git tmux kitty aerc jira yazi) if has_gui; then PACKAGES+=(sway waybar dunst) fi