zsh-workers
 help / color / mirror / code / Atom feed
From: "Štěpán Němec" <stepnem@gmail.com>
To: "Alexey I. Froloff" <raorn@altlinux.org>
Cc: zsh-workers@zsh.org
Subject: Re: [PATCH] _git: offer changed files relative to current directory
Date: Sat, 5 Dec 2009 18:00:53 +0100	[thread overview]
Message-ID: <20091205170053.GB21684@headley> (raw)
In-Reply-To: <20091205151202.GE3344@altlinux.org>

On Sat, Dec 05, 2009 at 06:12:03PM +0300, Alexey I. Froloff wrote:
> On Sat, Dec 05, 2009 at 03:42:58PM +0300, Alexey I. Froloff wrote:
> > Just need pure-zsh "relative" implementation.
> Here's my quick'n'dirty code:
> 
I'm not sure about the exact purpose of this function, but it doesn't
seem correct to me:
> relate()
> {
>     local -a what to res
> 
>     what=( ${(ps:/:)"${${${${1//\/\///}//\/.\///}%%/.}%%/}"} )
>     to=( ${(ps:/:)"${${${${2//\/\///}//\/.\///}%%/.}%%/}"} )
> 
>     while (( $#what > 0 )) && (( $#to > 0 )) && [[ $what[1] == $to[1] ]]; do
> 	what[1]=()
> 	to[1]=()
>     done
It is not unlikely to have more same-named directories in different
parts of directory tree. IIUC, the code above won't always work
correctly in such situation (i.e. it will remove the directory from the
path, wrongly assuming it is the same directory for both paths).

I believe the only correct way to solve the path relativization problem
for arbitrary input is to use the *absolute* paths.

In any case, it would be more useful/comprehensible (to me at least) if
you included the solution with the former patch to solve the actual
problem.


Anyway, here is what I've been succesfully using for some time; don't
laugh your teeth off:

------- 8< -------
From: Štěpán Němec <stepnem@gmail.com>
Date: Sat, 5 Dec 2009 17:42:56 +0100
Subject: [PATCH] _git: Fix commit path completion.

Paths returned by git-diff-index are relative to repository root; make
them relative to the current directory (i.e. how git-commit requires
them), using a `munge_paths' monsterfunction.

Signed-off-by: Štěpán Němec <stepnem@gmail.com>
---
 _git |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 54 insertions(+), 1 deletions(-)

diff --git a/_git b/_git
index e483133..b426612 100644
--- a/_git
+++ b/_git
@@ -2824,12 +2824,65 @@ __git_unmerged_files () {
 #this is for git-commit which can take files both git-added and not
 (( $+functions[__git_changed_files] )) ||
 __git_changed_files () {
+  # this function is needed to transform paths relative to the repo base dir
+  # (as returned by diff-index) into the form relative to the current directory
+  # :|
+  munge_paths () {
+    # SN FIXME is this needed? How come I don't see emulate -R anywhere in this file?
+    emulate -LR zsh
+    local cwd scnt scnta scntc
+    local -a abs paths
+    cwd=${"$(pwd)":a}
+    base=${${"$(git rev-parse --git-dir)":a}%.git}
+    abs=($base${^files})
+    scntc=${#${cwd//[^\/]}}
+    for ((i=1; i <= $#abs; i++)); do
+      scnta=${#${abs[$i]//[^\/]}}
+      scnt=$(($scntc - $scnta))
+      if ((scnt >= 0)); then
+      paths[$i]="$abs[$i]:t"
+        for ((j=0; j <= $scnt; j++)); do
+          paths[$i]="../$paths[$i]"
+        done
+      else
+        if [[ $abs[$i] == $cwd* ]]; then
+          paths[$i]="${${abs[$i]}#$cwd/}"
+        else
+          # longest common prefix
+          lcp () {
+            local lcp
+            for ((i=1; i<=$#1; i++)); do
+              if [[ ${1[i]} == ${2[i]} ]]; then
+                lcp+=${1[i]}
+              else
+                break
+              fi
+            done
+            echo "$lcp"
+          }
+          local common="$(lcp $cwd $abs[$i])"
+          local prefix=""
+          paths[$i]="${${abs[$i]}#$common}"
+          local cwdr="${${cwd}#$common}"
+          scntcr=${#${cwdr//[^\/]}}
+          for ((j=0; j <= $scntcr; j++)); do
+            prefix="../$prefix"
+          done
+          paths[$i]="$prefix$paths[$i]"
+        fi
+      fi
+    done
+    print ${(pj:\0:)paths}
+  }
+
   local -a files

   files=(${(ps:\0:)"$(_call_program files git diff-index -z --name-only --no-color HEAD 2>/dev/null)"})
   __git_command_successful || return
+  files=(${(ps:\0:)"$(munge_paths)"})

-  _wanted files expl 'index file' _multi_parts $@ - / files
+  _description files expl 'Changed files'
+  compadd "$expl[@]" - "$files[@]"
 }

 (( $+functions[__git_tree_files] )) ||
--


  reply	other threads:[~2009-12-05 17:00 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-05  0:32 Alexey I. Froloff
2009-12-05 12:07 ` Štěpán Němec
2009-12-05 12:42   ` Alexey I. Froloff
2009-12-05 15:12     ` Alexey I. Froloff
2009-12-05 17:00       ` Štěpán Němec [this message]
2009-12-05 17:45         ` Alexey I. Froloff
2009-12-06 21:52           ` [PATCH] _git: offer " Alexey I. Froloff
2009-12-07 22:40             ` Alexey I. Froloff
2009-12-08 10:48               ` Štěpán Němec
2009-12-08 10:50                 ` Nikolai Weibull
2009-12-08 11:37                   ` Štěpán Němec
2009-12-08 11:45                     ` Mikael Magnusson
2009-12-08 11:22                 ` Alexey I. Froloff
2009-12-08 11:39                   ` Štěpán Němec
2009-12-08 12:07                     ` Alexey I. Froloff
2009-12-13  0:08             ` Alexey I. Froloff
2009-12-13 21:33               ` Peter Stephenson
2009-12-13 22:16                 ` Nikolai Weibull
2009-12-13 22:22                 ` Štěpán Němec
2009-12-14 13:20                 ` Jörg Sommer
2009-12-08 12:08         ` [PATCH] _git: offer changed " Alexey I. Froloff
2009-12-08 13:20           ` Štěpán Němec
2009-12-08 13:30             ` Alexey I. Froloff

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091205170053.GB21684@headley \
    --to=stepnem@gmail.com \
    --cc=raorn@altlinux.org \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).