Skip to content

Instantly share code, notes, and snippets.

@GabrielVidal1
Created November 19, 2025 18:21
Show Gist options
  • Select an option

  • Save GabrielVidal1/0597bacc7d7ceac5fbd501a98c9738e6 to your computer and use it in GitHub Desktop.

Select an option

Save GabrielVidal1/0597bacc7d7ceac5fbd501a98c9738e6 to your computer and use it in GitHub Desktop.
fcat, cat for llms
#!/usr/bin/env bash
# detect type based on extension
get_type() {
local file="$1"
case "$file" in
*.py) echo "python" ;;
*.sh) echo "shell" ;;
*.c) echo "c" ;;
*.cpp|*.cc|*.cxx) echo "cpp" ;;
*.js) echo "javascript" ;;
*.jsx) echo "jsx" ;;
*.ts) echo "typescript" ;;
*.tsx) echo "tsx" ;;
*.java) echo "java" ;;
*.go) echo "go" ;;
*.rb) echo "ruby" ;;
*.php) echo "php" ;;
*.html|*.htm) echo "html" ;;
*.css) echo "css" ;;
*.json) echo "json" ;;
*.yaml|*.yml) echo "yaml" ;;
*.md) echo "markdown" ;;
*) detect_from_shebang "$file" ;;
esac
}
# detect from shebang if no extension matched
detect_from_shebang() {
local file="$1"
if [ -f "$file" ]; then
local firstline
firstline=$(head -n 1 "$file")
case "$firstline" in
*python*) echo "python" ;;
*bash*|*sh) echo "shell" ;;
*node*|*deno*) echo "javascript" ;;
*ruby*) echo "ruby" ;;
*php*) echo "php" ;;
*perl*) echo "perl" ;;
*go*) echo "go" ;;
*) echo "text" ;;
esac
else
echo "text"
fi
}
# choose comment style
get_comment_prefix() {
local type="$1"
case "$type" in
python|shell|ruby|perl) echo "#" ;;
*) echo "//" ;;
esac
}
# collect files from args or stdin
files=()
if [ "$#" -gt 0 ]; then
files=("$@")
else
while IFS= read -r line; do
[ -n "$line" ] && files+=("$line")
done
fi
for f in "${files[@]}"; do
[ -d "$f" ] && { continue; }
[ -f "$f" ] || { echo "Skipping missing file: $f" >&2; continue; }
[ "$f" != "${files[0]}" ] && echo
type=$(get_type "$f")
prefix=$(get_comment_prefix "$type")
echo "\`\`\`$type"
echo "$prefix path: $f"
cat "$f"
echo "\`\`\`" # blank line separator
done
@GabrielVidal1
Copy link
Author

fcat.sh

fcat prints files wrapped in Markdown code fences, with automatic language detection.

I made this to easily put whole files (with their path) into LLMs.

Install

cp fcat ~/.local/bin/fcat
chmod +x ~/.local/bin/fcat

Make sure ~/.local/bin is in your PATH.

Use

# Single file
$ fcat file.py

# All files in directory 
$ find . -type f | fcat

# To clipboard (WSL)
$ fcat *.yml | clip.exe

# To clipboard (linux)
$ fcat *.yml | xclip -selection clipboard

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment