![](/img/trans.png)
[英]How can I make bash tab completion behave like vim tab completion and cycle through matching matches?
[英]How can I make tab completion for my Git alias behave like an existing command?
我正在編寫一個shell腳本,向git添加“ review”子命令,以使其更容易進行代碼審查。 從git difftool
,它是git diff
和git difftool
命令的精美包裝器,但所需的鍵入較少。
一些示例用法:
# Lists added, deleted, renamed and modified files between master and current branch
git review master -l
# Opens difftool for files modified between master and current branch
git review -m
我想在我的shell腳本中啟用分支自動完成功能,但是我一生都無法解決如何做到這一點。 這是我真正追求的:
git review ma<tab><tab>
然后,它的行為應類似於git checkout ma<tab><tab>
。
我的shell腳本:
#!/bin/env bash
function print_usage {
echo "Usage: git review <branch> <-a|-d|-m|-l> [-- paths/to filter/by]"
echo ""
echo " -a: Only review added files"
echo " -d: Only review delete files"
echo " -m: Only review modified files"
echo " -l: List files and and type of modification"
}
if [ -z "$1" ] || [ -z "$2" ]; then
print_usage
exit 1
fi
git_branch=$1
review_command=$2
path_filters=""
shift
shift
if [ "$1" = "--" ]; then
path_filters="$@"
fi
case $review_command in
"-a")
echo "Reviewing added files..."
if [ -z "$path_filters" ]; then
git difftool $git_branch -- $(git diff --name-status $git_branch | grep -E '^A' | awk '{print $2}')
else
git difftool $git_branch -- $(git diff --name-status $git_branch -- $path_filters | grep -E '^A' | awk '{print $2}')
fi
;;
"-d")
echo "Reviewing deleted files..."
if [ -z "$path_filters" ]; then
git difftool $git_branch -- $(git diff --name-status $git_branch | grep -E '^D' | awk '{print $2}')
else
git difftool $git_branch -- $(git diff --name-status $git_branch -- $path_filters | grep -E '^D' | awk '{print $2}')
fi
;;
"-m")
echo "Reviewing modified files..."
if [ -z "$path_filters" ]; then
git difftool $git_branch -- $(git diff --name-status $git_branch | grep -E '^M' | awk '{print $2}')
else
git difftool $git_branch -- $(git diff --name-status $git_branch -- $path_filters | grep -E '^M' | awk '{print $2}')
fi
;;
"-l")
echo "Differences between $git_branch and $(git mybranch)..."
if [ -z "$path_filters" ]; then
git diff --name-status $git_branch
else
git diff --name-status $git_branch -- $path_filters
fi
;;
esac
echo ""
echo "Review finished."
確實,由於我正在輸入命令,因此我懷疑我的shell腳本是否與解決方案有關。
其他一些有用的信息:
有沒有一種方法可以將git分支自動完成功能添加到自定義git擴展命令中?
Linux的一個有趣的相關問題: 自定義git命令autocompletion 。
讓我們假設您的腳本的最低版本,例如
#!/usr/bin/env bash
git diff "$1"
這是可執行文件,位於$PATH
。 我們稱之為gitreview
。
要為其獲取別名,可以在.gitconfig
像這樣添加它:
[alias]
review = "!f() { gitreview \"$@\"; }; f"
當您輸入git
時,這將使您完成review
。 現在,要使其行為與git checkout
相同,可以使用null命令,如下所示:
review = "!f() { : git checkout ; gitreview \"$@\"; }; f"
它將完成與git checkout
相同的操作! 請注意, checkout
和;
之間的空白;
是必須的。
這在 git-completion.bash
的注釋中提到:
# If you use complex aliases of form '!f() { ... }; f', you can use the null
# command ':' as the first command in the function body to declare the desired
# completion style. For example '!f() { : git commit ; ... }; f' will
# tell the completion to use commit completion. This also works with aliases
# of form "!sh -c '...'". For example, "!sh -c ': git commit ; ... '".
另外,您可以通過將腳本命名為git-review
並將其放在$PATH
某個位置,從而使腳本成為適當的外部命令。 要獲得完成(假設您同時具有Bash和Git完成),請將其添加到~/.bash_completion
文件中(如果不存在,請創建它):
_git_review() { _git_checkout; }
Git完成(對於Git 2.18或更高版本)檢查名為_git_$command
完成功能,然后您說“只調用_git_checkout
”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.