From 0d65efc7698fa7149da53d064c7ae9ec492e1bbd Mon Sep 17 00:00:00 2001 From: sandroid Date: Tue, 11 Feb 2025 18:51:29 +0100 Subject: [PATCH] Feature: Add interactive git attributes generator --- README.md | 23 +++++++++++++---------- bin/git-forgit | 30 ++++++++++++++++++++++++++++++ conf.d/forgit.plugin.fish | 1 + forgit.plugin.zsh | 6 ++++++ 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 7f4fd2c..b0e0027 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,7 @@ forgit_show=gso forgit_add=ga forgit_reset_head=grh forgit_ignore=gi +forgit_attributes=gat forgit_checkout_file=gcf forgit_checkout_branch=gcb forgit_branch_delete=gbd @@ -263,14 +264,15 @@ Forgit will use the default configured pager from git (`core.pager`, `pager.show`, `pager.diff`) but can be altered with the following environment variables: -| Use case | Option | Fallbacks to | -| ------------ | ------------------- | --------------------------------------------- | -| common pager | `FORGIT_PAGER` | `git config core.pager` _or_ `cat` | -| pager on `git show` | `FORGIT_SHOW_PAGER` | `git config pager.show` _or_ `$FORGIT_PAGER` | -| pager on `git diff` | `FORGIT_DIFF_PAGER` | `git config pager.diff` _or_ `$FORGIT_PAGER` | -| pager on `git blame` | `FORGIT_BLAME_PAGER` | `git config pager.blame` _or_ `$FORGIT_PAGER` | -| pager on `gitignore` | `FORGIT_IGNORE_PAGER` | `bat -l gitignore --color always` _or_ `cat` | -| git log format | `FORGIT_GLO_FORMAT` | `%C(auto)%h%d %s %C(black)%C(bold)%cr%reset` | +| Use case | Option | Fallbacks to | +| ------------------------ | ------------------------- | ------------------------------------------------- | +| common pager | `FORGIT_PAGER` | `git config core.pager` _or_ `cat` | +| pager on `git show` | `FORGIT_SHOW_PAGER` | `git config pager.show` _or_ `$FORGIT_PAGER` | +| pager on `git diff` | `FORGIT_DIFF_PAGER` | `git config pager.diff` _or_ `$FORGIT_PAGER` | +| pager on `git blame` | `FORGIT_BLAME_PAGER` | `git config pager.blame` _or_ `$FORGIT_PAGER` | +| pager on `gitignore` | `FORGIT_IGNORE_PAGER` | `bat -l gitignore --color always` _or_ `cat` | +| pager on `gitatrributes` | `FORGIT_ATTRIBUTES_PAGER` | `bat -l gitattributes --color always` _or_ `cat` | +| git log format | `FORGIT_GLO_FORMAT` | `%C(auto)%h%d %s %C(black)%C(bold)%cr%reset` | ## fzf options @@ -295,6 +297,7 @@ Customizing fzf options for each command individually is also supported: | `glo` | `FORGIT_LOG_FZF_OPTS` | | `grl` | `FORGIT_REFLOG_FZF_OPTS` | | `gi` | `FORGIT_IGNORE_FZF_OPTS` | +| `gat` | `FORGIT_ATTRIBUTES_FZF_OPTS` | | `gd` | `FORGIT_DIFF_FZF_OPTS` | | `gso` | `FORGIT_SHOW_FZF_OPTS` | | `grh` | `FORGIT_RESET_HEAD_FZF_OPTS` | @@ -349,7 +352,7 @@ export FORGIT_LOG_FZF_OPTS=' - [`delta`](https://github.com/dandavison/delta) / [`diff-so-fancy`](https://github.com/so-fancy/diff-so-fancy): For better human-readable diffs. -- [`bat`](https://github.com/sharkdp/bat.git): Syntax highlighting for `gitignore`. +- [`bat`](https://github.com/sharkdp/bat.git): Syntax highlighting for `gitignore` and `gitattributes`. - [`emoji-cli`](https://github.com/wfxr/emoji-cli): Emoji support for `git log`. @@ -379,7 +382,7 @@ If you're having issues after updating, and commands such as `forgit::add` or al - Most of the commands accept optional arguments (e.g., `glo develop`, `glo f738479..188a849b -- main.go`, `gco main`). - `gd` supports specifying revision(e.g., `gd HEAD~`, `gd v1.0 README.md`). -- Call `gi` with arguments to get the wanted `.gitignore` contents directly(e.g., `gi cmake c++`). +- Call `gi` or `gat` with arguments to get the wanted `.gitignore`/`.gitattributes` contents directly(e.g., `gi cmake c++`). # 📃 License diff --git a/bin/git-forgit b/bin/git-forgit index e4cfca2..5eab5ac 100755 --- a/bin/git-forgit +++ b/bin/git-forgit @@ -164,6 +164,7 @@ _forgit_get_pager() { show) echo -n "${FORGIT_SHOW_PAGER:-$(git config pager.show || _forgit_get_pager)}" ;; diff) echo -n "${FORGIT_DIFF_PAGER:-$(git config pager.diff || _forgit_get_pager)}" ;; ignore) echo -n "${FORGIT_IGNORE_PAGER:-$(hash bat &>/dev/null && echo 'bat -l gitignore --color=always' || echo 'cat')}" ;; + attributes) echo -n "${FORGIT_ATTRIBUTES_PAGER:-$(hash bat &>/dev/null && echo 'bat -l gitattributes --color=always' || echo 'cat')}" ;; blame) echo -n "${FORGIT_BLAME_PAGER:-$(git config pager.blame || _forgit_get_pager)}" ;; enter) echo -n "${FORGIT_ENTER_PAGER:-"LESS='-r' less"}" ;; *) echo "pager not found: $1" >&2 ;; @@ -1075,6 +1076,34 @@ _forgit_ignore() { _forgit_path_get "$FORGIT_GI_TEMPLATES" .gitignore "${args[@]}" } +# git attributes generator +export FORGIT_ATTR_REPO_REMOTE=${FORGIT_ATTR_REPO_REMOTE:-https://github.com/gitattributes/gitattributes} +export FORGIT_ATTR_REPO_LOCAL=${FORGIT_ATTR_REPO_LOCAL:-${XDG_CACHE_HOME:-$HOME/.cache}/forgit/gat/repos/gitattributes/gitattributes} +export FORGIT_ATTR_TEMPLATES=${FORGIT_ATTR_TEMPLATES:-$FORGIT_ATTR_REPO_LOCAL} + +_forgit_attributes() { + [ -d "$FORGIT_ATTR_REPO_LOCAL" ] \ + || _forgit_repo_update "$FORGIT_ATTR_REPO_REMOTE" "$FORGIT_ATTR_REPO_LOCAL" + local IFS args opts + opts=" + $FORGIT_FZF_DEFAULT_OPTS + -m --preview-window='right:70%' + --preview=\"$FORGIT path_preview $FORGIT_ATTR_TEMPLATES {2} .gitattributes attributes\" + $FORGIT_ATTRIBUTES_FZF_OPTS + " + args=("$@") + if [[ $# -eq 0 ]]; then + args=() + while IFS='' read -r arg; do + args+=("$arg") + done < <(_forgit_paths_list "$FORGIT_ATTR_TEMPLATES" .gitattributes | + nl -w4 -s' ' | + FZF_DEFAULT_OPTS="$opts" fzf | awk '{print $2}') + fi + [ ${#args[@]} -eq 0 ] && return 1 + _forgit_path_get "$FORGIT_ATTR_TEMPLATES" .gitattributes "${args[@]}" +} + _forgit_repo_update() { local remote path remote=$1 @@ -1111,6 +1140,7 @@ _forgit_paths_list() { public_commands=( "add" + "attributes" "blame" "branch_delete" "checkout_branch" diff --git a/conf.d/forgit.plugin.fish b/conf.d/forgit.plugin.fish index 0c25d0a..c2b36a2 100644 --- a/conf.d/forgit.plugin.fish +++ b/conf.d/forgit.plugin.fish @@ -39,6 +39,7 @@ if test -z "$FORGIT_NO_ALIASES" abbr -a -- (string collect $forgit_diff; or string collect "gd") git-forgit diff abbr -a -- (string collect $forgit_show; or string collect "gso") git-forgit show abbr -a -- (string collect $forgit_ignore; or string collect "gi") git-forgit ignore + abbr -a -- (string collect $forgit_attributes; or string collect "gi") git-forgit attributes abbr -a -- (string collect $forgit_checkout_file; or string collect "gcf") git-forgit checkout_file abbr -a -- (string collect $forgit_checkout_branch; or string collect "gcb") git-forgit checkout_branch abbr -a -- (string collect $forgit_branch_delete; or string collect "gbd") git-forgit branch_delete diff --git a/forgit.plugin.zsh b/forgit.plugin.zsh index ef7aa10..3043f1e 100755 --- a/forgit.plugin.zsh +++ b/forgit.plugin.zsh @@ -141,6 +141,10 @@ forgit::ignore::clean() { "$FORGIT" ignore_clean "$@" } +forgit::attributes() { + "$FORGIT" attributes "$@" +} + # register aliases # shellcheck disable=SC2139 if [[ -z "$FORGIT_NO_ALIASES" ]]; then @@ -152,6 +156,7 @@ if [[ -z "$FORGIT_NO_ALIASES" ]]; then export forgit_diff="${forgit_diff:-gd}" export forgit_show="${forgit_show:-gso}" export forgit_ignore="${forgit_ignore:-gi}" + export forgit_attributes="${forgit_attributes:-gat}" export forgit_checkout_file="${forgit_checkout_file:-gcf}" export forgit_checkout_branch="${forgit_checkout_branch:-gcb}" export forgit_checkout_commit="${forgit_checkout_commit:-gco}" @@ -173,6 +178,7 @@ if [[ -z "$FORGIT_NO_ALIASES" ]]; then alias "${forgit_diff}"='forgit::diff' alias "${forgit_show}"='forgit::show' alias "${forgit_ignore}"='forgit::ignore' + alias "${forgit_attributes}"='forgit::attributes' alias "${forgit_checkout_file}"='forgit::checkout::file' alias "${forgit_checkout_branch}"='forgit::checkout::branch' alias "${forgit_checkout_commit}"='forgit::checkout::commit'