From: Mark Lodato <hidden> Date: 2016-06-15 22:49:23
Modify git-completion.bash so that it also works with zsh when using
bashcompinit. In particular:
declare -F
Zsh doesn't have the same 'declare -F' as bash, but 'declare -f'
is the same, and it works just as well for our purposes.
${var:2}
Zsh does not implement ${var:2} to skip the first 2 characters, but
${var#??} works in both shells to replace the first 2 characters
with nothing. Thanks to Jonathan Nieder for the suggestion.
for (( n=1; "$n" ... ))
Zsh does not allow "$var" in arithmetic loops. Instead, pre-compute
the endpoint and use the variables without $'s or quotes.
shopt
Zsh uses 'setopt', which has a different syntax than 'shopt'. Since
'shopt' is used infrequently in git-completion, we provide
a bare-bones emulation.
emulate -L bash
KSH_TYPESET
Zsh offers bash emulation, which turns on a set of features to
closely resemble bash. In particular, this enables SH_WORDSPLIT,
which splits scalar variables on word boundaries in 'for' loops.
We also need to set KSH_TYPESET, to fix "local var=$(echo foo bar)"
issues.
The last set of options are turned on only in _git and _gitk. Some of
the sub-functions may not work correctly if called directly.
Signed-off-by: Mark Lodato <redacted>
---
Those on the CC list either responded to the original patch or are the authors
of the lines affected by this patch:
- Andrew wrote __git_ps1_show_upstream().
- SZEDER wrote the part using 'declare -F'.
contrib/completion/git-completion.bash | 50 +++++++++++++++++++++++++++++--
1 files changed, 46 insertions(+), 4 deletions(-)
@@ -21,6 +21,11 @@# 2) Added the following line to your .bashrc:# source ~/.git-completion.sh#+# Or, add the following lines to your .zshrc:+# autoload bashcompinit+# bashcompinit+# source ~/.git-completion.sh+## 3) Consider changing your PS1 to also show the current branch:# PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '#
@@ -138,11 +143,12 @@ __git_ps1_show_upstream ()# get the upstream from the "git-svn-id: ..." in a commit message# (git-svn uses essentially the same procedure internally)localsvn_upstream=($(gitlog--first-parent-1\---grep="^git-svn-id: \(${svn_url_pattern:2}\)"2>/dev/null))+--grep="^git-svn-id: \(${svn_url_pattern#??}\)"2>/dev/null))if[[0-ne${#svn_upstream[@]}]];thensvn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}svn_upstream=${svn_upstream%@*}-for((n=1;"$n"<="${#svn_remote[@]}";++n));do+localn_stop="${#svn_remote[@]}"+for((n=1;n<=n_stop;++n));dosvn_upstream=${svn_upstream#${svn_remote[$n]}}done
From: SZEDER Gábor <hidden> Date: 2016-06-15 22:49:24
Hi,
On Thu, Aug 26, 2010 at 10:45:56PM -0400, Mark Lodato wrote:
Modify git-completion.bash so that it also works with zsh when using
bashcompinit. In particular:
declare -F
Zsh doesn't have the same 'declare -F' as bash, but 'declare -f'
is the same, and it works just as well for our purposes.
quoted hunk
@@ -2372,17 +2383,22 @@ _git () fi local completion_func="_git_${command//-/_}"- declare -F $completion_func >/dev/null && $completion_func && return+ declare -f $completion_func >/dev/null && $completion_func && return local expansion=$(__git_aliased_command "$command") if [ -n "$expansion" ]; then completion_func="_git_${expansion//-/_}"- declare -F $completion_func >/dev/null && $completion_func+ declare -f $completion_func >/dev/null && $completion_func fi }
I chose -F back then because it does not print the definition of the
completion function, so there is less stuff to throw away immediately.
However, the run-time difference seems to be barely measureable (i.e.
'time declare -f _git_config >/dev/null' vs. 'declare -F _git_config
>/dev/null' sometimes shows 0.001s difference), so I'm fine with this
change.
From: Peter Kjellerstedt <hidden> Date: 2016-06-15 22:49:25
quoted hunk
-----Original Message-----
From: git-owner@vger.kernel.org [mailto:git-owner@vger.kernel.org] On
Behalf Of Mark Lodato
Sent: den 31 augusti 2010 02:56
To: SZEDER Gábor
Cc: Shawn O. Pearce; git@vger.kernel.org; avarab@gmail.com; Jonathan
Nieder; Andrew Sayers
Subject: Re: [PATCHv2] completion: make compatible with zsh
2010/8/30 SZEDER Gábor [off-list ref]
quoted
On Thu, Aug 26, 2010 at 10:45:56PM -0400, Mark Lodato wrote:
quoted
@@ -2417,3 +2433,29 @@ if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
-z? I think you wanted to use -n here, like at the other places.
Oh, yes, sorry. This was a mistake. Thanks for catching it.
quoted
Nit: why "if [[ ... ]]"? FWIW "if [ ... ]" would be enough.
Because you don't need to quote variables with [[ ... ]] --- e.g. [
$lines = 0 ] fails, though in this case this feature does not matter
--- and because [[ ... ]] is faster.
Bash 4.1.5:
quoted
time (for (( i = 0; i < 200000; i++ )); do [ -z $foo ]; done)
real 0m3.430s
user 0m3.240s
sys 0m0.180s
quoted
time (for (( i = 0; i < 200000; i++ )); do [[ -z $foo ]]; done)
real 0m2.219s
user 0m2.090s
sys 0m0.100s
Zsh 4.3.10:
quoted
time (for (( i = 0; i < 2000000; i++ )); do [ -z $foo ]; done)
(; for ((i = 0; i < 2000000; i++ )) do; [ -z $foo ]; done; ) 13.56s
user 1.64s system 99% cpu 15.327 total
quoted
time (for (( i = 0; i < 2000000; i++ )); do [[ -z $foo ]]; done)
(; for ((i = 0; i < 2000000; i++ )) do; [[ -z $foo ]]; done; ) 4.62s
user 0.01s system 99% cpu 4.644 total
Is there a reason to prefer [ ... ] ?
The [ command is defined by POSIX, while [[ is an extension to the
shell language implemented by bash (and zsh). Thus the [[ construct
would fail on a stricter POSIX implementation of the shell language,
e.g., as implemented by dash. Thus to be POSIX compliant (which is
required for shell scripts installed by a multi system supporting
application like git), the [[ construct cannot be used.
Of course, this does not really apply to a script explicitly written
for bash, but that is the common reason to prefer [ over [[ in shell
scripts.
//Peter