You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

130 lines
2.7 KiB

#!/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:
```
<contents>
```
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