From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23218 invoked from network); 24 Jun 2007 15:14:09 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.1 (2007-05-02) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.1 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 24 Jun 2007 15:14:09 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 54867 invoked from network); 24 Jun 2007 15:14:03 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 24 Jun 2007 15:14:03 -0000 Received: (qmail 3692 invoked by alias); 24 Jun 2007 15:14:00 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 23594 Received: (qmail 3674 invoked from network); 24 Jun 2007 15:13:59 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 24 Jun 2007 15:13:59 -0000 Received: (qmail 54566 invoked from network); 24 Jun 2007 15:13:59 -0000 Received: from acolyte.scowler.net (216.254.112.45) by a.mx.sunsite.dk with SMTP; 24 Jun 2007 15:13:56 -0000 Received: by acolyte.scowler.net (Postfix, from userid 1000) id EB9DC5C3C6; Sun, 24 Jun 2007 11:13:55 -0400 (EDT) Date: Sun, 24 Jun 2007 11:13:55 -0400 From: Clint Adams To: zsh-workers@sunsite.dk Subject: PATCH: _git grep Message-ID: <20070624151355.GA2293@scowler.net> Mail-Followup-To: zsh-workers@sunsite.dk MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.13 (2006-08-11) git grep from Nikolai Weibull's repo. Index: Completion/Unix/Command/_git =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Unix/Command/_git,v retrieving revision 1.5 diff -u -r1.5 _git --- Completion/Unix/Command/_git 24 Jun 2007 14:58:16 -0000 1.5 +++ Completion/Unix/Command/_git 24 Jun 2007 15:11:50 -0000 @@ -829,10 +829,80 @@ '::my revision:__git_revisions' && ret=0 } -# TODO: something better _git-grep () { - service=grep _grep - ret=0 + local -a pattern_operators + + if (( words[(I)-e] == CURRENT - 2 )); then + pattern_operators=( + '--and[both patterns must match]' + '--or[either pattern must match]' + '--not[the following pattern must not match]') + fi + + local curcontext=$curcontext state line + declare -A opt_args + + _arguments -A '--*' \ + '--cached[grep blobs registered in index file instead of working tree]' \ + '(-a --text)'{-a,--text}'[process binary files as if they were text]' \ + '(-i --ignore-case)'{-i,--ignore-case}'[ignore case when matching]' \ + '(-w --word-regexp)'{-w,--word-regexp}'[match only whole words]' \ + '(-v --invert-match)'{-v,--invert-match}'[select non-matching lines]' \ + '( -H)-h[supress output of filenames]' \ + '(-h )-H[show filenames]' \ + '--full-name[output paths relative to the project top directory]' \ + '(-E --extended-regexp -G --basic-regexp)'{-E,--extended-regexp}'[use POSIX extended regexes]' \ + '(-E --extended-regexp -G --basic-regexp)'{-G,--basic-regexp}'[use POSIX basic regexes]' \ + '-n[prefix the line number to matching lines]' \ + '(-l --files-with-matches -L --files-without-match)'{-l,--files-with-match}'[show only names of matching files]' \ + '(-l --files-with-matches -L --files-without-match)'{-L,--files-without-match}'[show only names of non-matching files]' \ + '(-c --count)'{-c,--count}'[show number of matching lines in files]' \ + '-A[show trailing context]: :_guard "[[\:digit\:]]#" lines' \ + '-B[show leading context]: :_guard "[[\:digit\:]]#" lines' \ + '-C[show context]: :_guard "[[\:digit\:]]#" lines' \ + '(1)*-f[read patterns from given file]:pattern file:_files' \ + '(1)*-e[use the given pattern for matching]:pattern' \ + $pattern_operators \ + '--all-match[all patterns must match]' \ + ':pattern:' \ + '*::tree-or-file:->files' && ret=0 + + case $state in + (files) + integer first_tree last_tree start end + + (( start = words[(I)(-f|-e)] > 0 ? 1 : 2 )) + (( end = $#line - 1 )) + + for (( i = start; i <= end; i++ )); do + [[ line[i] == '--' ]] && break + git cat-file -e "${(Q)line[i]}^{tree}" 2>/dev/null || break + if (( first_tree == 0 )); then + (( first_tree = last_tree = i )) + else + (( last_tree = i )) + fi + done + + if (( last_tree == 0 || last_tree == end )); then + if (( first_tree == 0 )); then + _alternative \ + 'tree:tree:__git_trees' \ + "file:file:__git_cached_files" && ret=0 + else + _alternative \ + 'tree:tree:__git_trees' \ + "tree file:tree-files:__git_tree_files $line[first_tree,last_tree]" && ret=0 + fi + else + if (( first_tree == 0 )); then + __git_cached_files + else + __git_tree_files $line[first_tree,last_tree] + fi + fi + ;; + esac } # TODO: this isn't strictly right, but close enough