Merge pull request 'feat(gi): merge gitig into gi with prompt, dedup, and boilerplate support' (#19) from feat/git-ignorer into main

Reviewed-on: #19
This commit was merged in pull request #19.
This commit is contained in:
2026-05-23 03:50:05 +00:00
7 changed files with 233 additions and 91 deletions
+62 -27
View File
@@ -1,45 +1,80 @@
# GitIgnore for Fish-config
### Fish ###
fishd.*
fish_history
fish_variables
config.local.fish
### Linux ###
# id: gitig-boilerplate-7f0528027e23f210196ae4583c408e5b
# ╭──────────────────────────────────────────────────────────╮
# │ GitIgnore Boilerplate Template │
# ╰──────────────────────────────────────────────────────────╯
#
# ──────────────────── OS-Generated Files ────────────────────
# automatic backup files created by some editors (e.g., Vim, Emacs)
*~
# temporary files which can be created if a process still has a handle open of a deleted file
# temporary files created if a process still has a handle to a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# MacOS junk
.DS_Store
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
# files created when an open file is removed but is still being accessed
.nfs*
# Debug Files/Folders
OLD/
*.OLD
*.DISABLE
*.DISABLED
*_old
# ─────────────────── Debug/Temporary/Testing ────────────────
# Matches OLD / .OLD
[Oo][Ll][Dd]/
.[Oo][Ll][Dd]/
# AI Session IDs
.claud*
.gemin*
.antigrav*
.remember
# Matches DISABLE / .DISABLE
[Dd][Ii][Ss][Aa][Bb][Ll][Ee]/
.[Dd][Ii][Ss][Aa][Bb][Ll][Ee]/
# Matches DISABLED / .DISABLED
[Dd][Ii][Ss][Aa][Bb][Ll][Ee][Dd]/
.[Dd][Ii][Ss][Aa][Bb][Ll][Ee][Dd]/
# Matches DEBUG / .DEBUG
[Dd][Ee][Bb][Uu][Gg]/
.[Dd][Ee][Bb][Uu][Gg]/
# Matches TMP / .TMP
[Tt][Mm][Pp]/
.[Tt][Mm][Pp]/
# Matches TEMP / .TEMP
[Tt][Ee][Mm][Pp]/
.[Tt][Ee][Mm][Pp]/
# Matches TEMPORARY / .TEMPORARY
[Tt][Ee][Mm][Pp][Oo][Rr][Aa][Rr][Yy]/
.[Tt][Ee][Mm][Pp][Oo][Rr][Aa][Rr][Yy]/
# Matches TESTING / .TESTING
[Tt][Ee][Ss][Tt][Ii][Nn][Gg]/
.[Tt][Ee][Ss][Tt][Ii][Nn][Gg]/
# ─────────────────── AI Sessions and Rules ──────────────────
# Matches CLAUDE.md, .claud*, etc.
[Cc][Ll][Aa][Uu][Dd][Ee].[Mm][Dd]
.[Cc][Ll][Aa][Uu][Dd]*
# Matches GEMINI.md, .gemin*, etc.
[Gg][Ee][Mm][Ii][Nn][Ii].[Mm][Dd]
.[Gg][Ee][Mm][Ii][Nn]*
# Matches ANTIGRAVITY.md, .antigrav*, etc.
[Aa][nN][Tt][Ii][Gg][Rr][Aa][Vv][Ii][Tt][Yy].[Mm][Dd]
.[Aa][Nn][Tt][Ii][Gg][Rr][Aa][Vv]*
# Matches AGENTS.md, .remember, etc.
[Aa][Gg][Ee][Nn][Tt][Ss].[Mm][Dd]
.[Rr][Ee][Mm][Ee][Mm][Bb][Ee][Rr]
# ──────────────────────────────────────────────────────────────
# Auto-managed by fish; contains machine-local state and universal vars
fish_variables
# Personal testing/temporary files
[Tt][Mm][Pp]/
[Tt][Ee][Mm][Pp]/
[Tt][Ee][Mm][Pp][Oo][Rr][Aa][Rr][Yy]/
[Tt][Ee][Ss][Tt][Ii][Nn][Gg]/
[Dd][Ee][Bb][Uu][Gg]/
+5 -1
View File
@@ -76,7 +76,6 @@ Managed via [Fisher](https://github.com/jorgebucaran/fisher):
| `jorgebucaran/autopair.fish` | Auto-close brackets, quotes, and other pairs |
| `jorgebucaran/replay.fish` | Run bash commands in fish without losing state |
| `nickeb96/puffer-fish` | Expand `...` to `../..`, `!!` to last command, etc. |
| `mattmc3/magic-enter.fish` | Smart Enter: runs `ls` / `git status` on blank line |
| `jorgebucaran/spark.fish` | Sparkline bar charts in the terminal |
Fisher and all listed plugins are installed automatically by the bootstrap script in `config.fish` upon launching the shell for the first time.
@@ -231,6 +230,7 @@ rm -f file.txt # Falls through to standard rm -f
| `git-clean --force` | Same but force-deletes unmerged orphaned branches |
| `clone` | `clone-in-kitty` wrapper |
| `gitui` | Fast terminal Git UI |
| `gi` | Generate and append `.gitignore` patterns from gitignore.io; `gi` (no args) appends boilerplate then prompts interactively; `gi <targets>` appends named patterns; `gi -s <targets>` prints to stdout; `gi -l` lists all targets |
### Package Management (Arch / paru)
@@ -412,6 +412,7 @@ These abbreviations replicate Bash's bang-style history expansions. They expand
|---|---|
| `g` | `git` |
| `lg` | `lazygit` |
| `gitig` / `git-ignore` | `gi` |
### Chezmoi
@@ -598,6 +599,9 @@ Use this file for paths and variables that are specific to one machine — thing
# CDPATH — directories searched by cd
set -gx CDPATH . /home/youruser/projects /home/youruser
# Path to your shared .gitignore boilerplate (used by `gi -b` / `gi` default)
set -gx GITIGNORE_BOILERPLATE ~/.config/git/gitignore_boilerplate
### SSH ###
# Quick shortcuts to your own servers
abbr -a sshr 'ssh you@your-server.local'
+2
View File
@@ -69,6 +69,8 @@ abbr -a e edit
abbr -a se sudoedit
# Git
abbr -a g git
abbr -a gitig gi
abbr -a git-ignore gi
# Antigravity
abbr -a ag antigravity
abbr -a ag. antigravity .
-25
View File
@@ -1,25 +0,0 @@
function magic-enter-cmd --description "Print the command to run when no command was given"
set -l cmd ls
if command git rev-parse --is-inside-work-tree &>/dev/null
set cmd "git status -sb"
end
echo $cmd
end
function magic-enter
set -l cmd (commandline)
if test -z "$cmd"
commandline -r (magic-enter-cmd)
commandline -f suppress-autosuggestion
end
commandline -f execute
end
function magic-enter-bindings --description "Bind magic-enter for default and vi key bindings"
bind \r magic-enter
if functions -q fish_vi_key_bindings
bind -M insert \r magic-enter
bind -M default \r magic-enter
end
end
magic-enter-bindings
-7
View File
@@ -1,8 +1 @@
catppuccin/fish
patrickf1/fzf.fish
jorgebucaran/fisher
jorgebucaran/autopair.fish
jorgebucaran/replay.fish
nickeb96/puffer-fish
mattmc3/magic-enter.fish
jorgebucaran/spark.fish
-3
View File
@@ -1,6 +1,3 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
function fisher --argument-names cmd --description "A plugin manager for Fish"
set --query fisher_path || set --local fisher_path $__fish_config_dir
set --local fisher_version 4.4.8
+164 -28
View File
@@ -1,55 +1,191 @@
# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# Generate .gitignore files using the gitignore.io API
function gi --description 'Generate .gitignore files using the gitignore.io API'
# Define the flags
argparse h/help d/description l/list -- $argv
argparse h/help d/description l/list b/boilerplate p/prompt s/stdout -- $argv
or return 1
# Help output
if set -q _flag_help
echo "Usage: gi [TARGETS...] [FLAGS]"
set_color --bold
echo "Usage:"(set_color normal)" gi "(set_color cyan)"[TARGETS...]"(set_color yellow)" [FLAGS]"(set_color normal)
echo ""
echo "Arguments:"
echo " TARGETS Comma-separated list of languages or tools (e.g., c++,neovim,archlinux)"
set_color --bold
echo "Arguments:"(set_color normal)
echo " "(set_color cyan)"TARGETS"(set_color normal)" Comma-separated list of languages or tools"
echo " "(set_color brblack)"e.g. c++,neovim,archlinux"(set_color normal)
echo ""
echo "Flags:"
echo " -h, --help Show this help message"
echo " -d, --description Show the Fish function description"
echo " -l, --list List all supported targets from the API"
set_color --bold
echo "Flags:"(set_color normal)
echo " "(set_color yellow)"-h, --help "(set_color normal)" Show this help message"
echo " "(set_color yellow)"-d, --description "(set_color normal)" Show the Fish function description"
echo " "(set_color yellow)"-l, --list "(set_color normal)" List all supported targets from the API"
echo " "(set_color yellow)"-b, --boilerplate "(set_color normal)" Append boilerplate from "(set_color cyan)"\$GITIGNORE_BOILERPLATE"(set_color normal)" to .gitignore"
echo " "(set_color yellow)"-p, --prompt "(set_color normal)" Prompt for patterns and append them to .gitignore"
echo " "(set_color yellow)"-s, --stdout "(set_color normal)" Print API output to stdout instead of appending to .gitignore"
echo ""
echo "Examples:"
echo " gi c++ # Print C++ gitignore to stdout"
echo " gi python,venv > .gitignore # Create a file for Python and venv"
echo " gi -l | grep -i linux # Search for specific OS support"
set_color --bold
echo "Examples:"(set_color normal)
echo " "(set_color green)"gi"(set_color normal)" "(set_color brblack)"# Append boilerplate and prompt for patterns (default)"(set_color normal)
echo " "(set_color green)"gi -b"(set_color normal)" "(set_color brblack)"# Append boilerplate only"(set_color normal)
echo " "(set_color green)"gi -p"(set_color normal)" "(set_color brblack)"# Prompt for patterns and append to .gitignore"(set_color normal)
echo " "(set_color green)"gi"(set_color normal)" "(set_color cyan)"c++"(set_color normal)" "(set_color brblack)"# Append C++ patterns to .gitignore"(set_color normal)
echo " "(set_color green)"gi"(set_color normal)" "(set_color cyan)"python,venv"(set_color normal)" "(set_color brblack)"# Append Python+venv patterns to .gitignore"(set_color normal)
echo " "(set_color green)"gi -s"(set_color normal)" "(set_color cyan)"python,venv"(set_color normal)" "(set_color brblack)"# Print Python+venv patterns to stdout"(set_color normal)
echo " "(set_color green)"gi -l"(set_color normal)" | grep -i linux "(set_color brblack)"# Search for specific OS support"(set_color normal)
return 0
end
# Print the function description
if set -q _flag_description
functions -D gi
return 0
end
# Handle the list flag
if set -q _flag_list
curl -sL https://www.toptal.com/developers/gitignore/api/list
return 0
end
# Error if no arguments provided
if not set -q argv[1]
echo "Error: No targets provided. Use 'gi --help' for usage." >&2
return 1
# Determine which modes to run
set -l do_boilerplate 0
set -l do_prompt 0
if set -q _flag_boilerplate
set do_boilerplate 1
end
if set -q _flag_prompt
set do_prompt 1
end
# Execute the API call
# We replace any spaces with commas just in case you pass them as separate args
set -l targets (string join "," $argv)
# Default (no args, no interactive flags): run both boilerplate and prompt
if not set -q argv[1]; and test $do_boilerplate -eq 0; and test $do_prompt -eq 0
set do_boilerplate 1
set do_prompt 1
end
echo "## Generating .gitignore for: $targets"
curl -f -sL "https://www.toptal.com/developers/gitignore/api/$targets"
# Resolve git context for anything that writes to .gitignore
set -l gitignore_path ""
set -l readable_path ""
set -l needs_git 0
if test $do_boilerplate -eq 1; or test $do_prompt -eq 1
set needs_git 1
else if set -q argv[1]; and not set -q _flag_stdout
set needs_git 1
end
if test $status -ne 0
echo "Error: Failed to fetch gitignore. Are the targets spelled correctly?" >&2
return 1
if test $needs_git -eq 1
if not git rev-parse --is-inside-work-tree >/dev/null 2>&1
set_color red --bold
echo "Error:" (set_color normal)"Not a git repository (or any parent directories)" >&2
return 1
end
set -l git_root (git rev-parse --show-toplevel)
set gitignore_path "$git_root/.gitignore"
set readable_path (string replace -r "^$HOME" "~" $gitignore_path)
end
# Boilerplate mode
if test $do_boilerplate -eq 1
if not set -q GITIGNORE_BOILERPLATE
set_color red --bold
echo "Error:" (set_color normal)"\$GITIGNORE_BOILERPLATE environment variable is not defined" >&2
return 1
end
if not test -f "$GITIGNORE_BOILERPLATE"
set_color red --bold
echo "Error:" (set_color normal)"Boilerplate file not found at '$GITIGNORE_BOILERPLATE'" >&2
return 1
end
set -l template_hash ""
if command -q md5sum
set template_hash (md5sum "$GITIGNORE_BOILERPLATE" | string split ' ')[1]
else if command -q md5
set template_hash (md5 -q "$GITIGNORE_BOILERPLATE")
end
set -l sig "# id: gitig-boilerplate-$template_hash"
if test -f "$gitignore_path"; and grep -qF "$sig" "$gitignore_path"
set_color yellow --bold
echo "Notice:" (set_color normal)"Boilerplate already present in "(set_color cyan)"$readable_path"(set_color normal)"."
else
printf "\n%s\n" "$sig" >>"$gitignore_path"
cat "$GITIGNORE_BOILERPLATE" >>"$gitignore_path"
echo (set_color green)"✔"(set_color normal)" Appended boilerplate to "(set_color cyan)"$readable_path"(set_color normal)
end
end
# Prompt mode: ask for patterns, fetch and dedup each one individually
if test $do_prompt -eq 1
read -P "Enter gitignore patterns (comma-separated, e.g. python,vim): " patterns
or return 0
set patterns (string trim -- $patterns)
if test -n "$patterns"
for pattern in (string split "," -- $patterns)
set pattern (string trim -- $pattern)
test -z "$pattern"; and continue
set -l content (curl -f -sL "https://www.toptal.com/developers/gitignore/api/$pattern" | string collect)
if test $status -ne 0
echo "Error: Failed to fetch gitignore for '$pattern'. Is the target spelled correctly?" >&2
continue
end
__gi_append_dedup "$content" "$pattern" "$gitignore_path" "$readable_path"
end
end
return 0
end
# Direct API call mode
if set -q argv[1]
set -l targets (string join "," $argv)
if set -q _flag_stdout
# stdout: single combined request, no dedup
set -l content (curl -f -sL "https://www.toptal.com/developers/gitignore/api/$targets" | string collect)
if test $status -ne 0
echo "Error: Failed to fetch gitignore. Are the targets spelled correctly?" >&2
return 1
end
echo "$content"
else
# append: fetch and dedup each pattern individually
for target in (string split "," -- $targets)
set target (string trim -- $target)
test -z "$target"; and continue
set -l content (curl -f -sL "https://www.toptal.com/developers/gitignore/api/$target" | string collect)
if test $status -ne 0
echo "Error: Failed to fetch gitignore for '$target'. Is the target spelled correctly?" >&2
continue
end
__gi_append_dedup "$content" "$target" "$gitignore_path" "$readable_path"
end
end
end
end
# Append API content to .gitignore with MD5-based deduplication.
# Args: content, label, gitignore_path, readable_path
function __gi_append_dedup
set -l content $argv[1]
set -l label $argv[2]
set -l gitignore_path $argv[3]
set -l readable_path $argv[4]
set -l content_hash ""
if command -q md5sum
set content_hash (echo "$content" | md5sum | string split ' ')[1]
else if command -q md5
set content_hash (echo "$content" | md5)
end
set -l sig "# id: gi-patterns-$content_hash"
if test -f "$gitignore_path"; and grep -qF "$sig" "$gitignore_path"
set_color yellow --bold
echo "Notice:" (set_color normal)"$label patterns already present in "(set_color cyan)"$readable_path"(set_color normal)"."
else
printf "\n%s\n%s\n" "$sig" "$content" >>"$gitignore_path"
echo (set_color green)"✔"(set_color normal)" Appended $label patterns to "(set_color cyan)"$readable_path"(set_color normal)
end
end