#!/bin/bash set -euo pipefail # --- Defaults --- COPY=true CLIP_CMD=() # --- Detect clipboard tool --- detect_clipboard() { # Pick the right tool for the session: # wl-copy on Wayland, xclip/xsel on X11. Fall back to whatever exists. if [[ "${XDG_SESSION_TYPE:-}" == "wayland" || -n "${WAYLAND_DISPLAY:-}" ]]; then if command -v wl-copy &> /dev/null; then CLIP_CMD=(wl-copy) elif command -v xclip &> /dev/null; then CLIP_CMD=(xclip -selection clipboard) elif command -v xsel &> /dev/null; then CLIP_CMD=(xsel --clipboard --input) fi else if command -v xclip &> /dev/null; then CLIP_CMD=(xclip -selection clipboard) elif command -v xsel &> /dev/null; then CLIP_CMD=(xsel --clipboard --input) elif command -v wl-copy &> /dev/null; then CLIP_CMD=(wl-copy) fi fi } # --- Help --- usage() { cat << 'EOF' cat-md — concatenate files as a Markdown code block, copy to clipboard. Usage: cat-md [OPTIONS] [FILE|DIR]... Each file is printed as: path/to/file: ``` ``` Directories are expanded non-recursively (all files inside). Options: -n, --no-copy Print to stdout only, skip clipboard copy -h, --help Show this help and exit Examples: cat-md file1.txt file2.txt cat-md src/ cat-md -n file.txt # no clipboard cat-md -n file.txt | less # pipe manually Requirements (one of): wl-copy — Wayland clipboard (from wl-clipboard) xclip — X11 clipboard (preferred on X11) xsel — alternative X11 clipboard tool EOF exit 0 } # --- Parse arguments --- ARGS=() while [[ $# -gt 0 ]]; do case "$1" in -n | --no-copy) COPY=false shift ;; -h | --help) usage ;; --) shift ARGS+=("$@") break ;; -*) echo "Unknown option: $1" >&2 echo "Try -h for help." >&2 exit 1 ;; *) ARGS+=("$1") shift ;; esac done # --- Validate --- if [[ ${#ARGS[@]} -eq 0 ]]; then echo "Error: no files or directories provided. Try -h for help." >&2 exit 1 fi detect_clipboard if $COPY && [[ ${#CLIP_CMD[@]} -eq 0 ]]; then echo "Warning: no clipboard tool found (tried wl-copy, xclip, xsel). Output will go to stdout only." >&2 COPY=false fi # --- Generate output --- generate() { for path in "$@"; do if [[ -d "$path" ]]; then for file in "$path"/*; do if [[ -f "$file" ]]; then generate "$file" fi done elif [[ -f "$path" ]]; then echo "$path:" echo '```' cat "$path" echo echo '```' echo fi done } if $COPY; then generate "${ARGS[@]}" | "${CLIP_CMD[@]}" echo "Copied to clipboard." >&2 else generate "${ARGS[@]}" fi