diff --git a/src/_ack b/src/_ack index b75210b..55a38b8 100644 --- a/src/_ack +++ b/src/_ack @@ -1,4 +1,4 @@ -#compdef ack ack-grep +#compdef ack ack2 ack-grep ack-standalone # ------------------------------------------------------------------------------ # Copyright (c) 2011 Github zsh-users - http://github.com/zsh-users # All rights reserved. @@ -28,7 +28,7 @@ # Description # ----------- # -# Completion script for ack 1.94 and 2.04 (http://betterthangrep.com). +# Completion script for ack 1.96 and 2.14 (http://betterthangrep.com). # # ------------------------------------------------------------------------------ # Authors @@ -43,39 +43,55 @@ _ack_version() { local version version=(${(f)"$(_call_program version $words[1] --version)"}) version=${${(z)${version[1]}}[2]} - printf $version + echo $version } - _ack() { local context curcontext="$curcontext" state line cmds update_policy ret=1 integer NORMARG typeset -A opt_args + # Don't complete if command doesn't exist + [[ ${+commands[${words[1]}]} -eq 0 ]] && return 0 + zstyle -s ":completion:${curcontext}:" cache-policy update_policy [[ -z "$update_policy" ]] && zstyle ":completion:${curcontext}:" cache-policy _ack_types_caching_policy unset _ack_raw_types if ( [[ ${+_ack_raw_types} -eq 0 ]] || _cache_invalid "ack-grep" ) && ! _retrieve_cache "ack-grep"; then - _ack_raw_types=(${(S)${(S)${(f)${${"$(_call_program types $words[1] --help=types)"}#*--\[no\]}}%; first line matches \/*\/}#*no\]}) [[ $#_ack_raw_types -gt 0 ]] && _store_cache "ack-grep" _ack_raw_types fi - ack_20_options=( - '(- 1 *)--dump[Writes the list of options loaded and where they came from to standard output]' - '(- 1 *)--create-ackrc[create custom ackrc files based on the default settings loaded by ackr]' + ack_20_options=( + '--ackrc[specify an ackrc file to use]:files:_files' '(- 1 *)--bar[consult Admiral Ackbar]' + '(--nobreak --break)'{--nobreak,--break}'[print a break between results from different files, default on]' + '(- 1 *)--cathy[chocolate chocolate chocolate]' + '(- 1 *)--create-ackrc[create custom ackrc files based on the default settings loaded by ackrc]' + '(- 1 *)--dump[writes the list of options loaded and where they came from to standard output]' + '(--files-from -x)--files-from=[read the list of files to search from FILE]:files:_files' + '(--filter --nofilter)--filter[force ack to treat input as pipe]' + '(--filter --nofilter)--nofilter[force ack to treat input as tty]' + '(--noheading --heading)'{--noheading,--heading}'[print a filename heading above results, default on]' + '(- 1 *)--help-types[display all known types]' + '--ignore-ack-defaults[ignore default definitions included with ack]' '*--ignore-file=[ignore file]:ignore file filter: _describe "ignore file filter" ignore_filter_opts' - '*--file-from=[Read the list of files to search from FILE]:file:_files' - '-s[Suppress error messages about nonexistent or unreadable files]' - '--ignore-ack-defaults[ignore ack default options in favor of their own]' + '(-k --known-types)'{-k,--known-types}'[include only files of types that ack recognizes]' + '--lines=[only print line(s) NUM of each file]:number' + '--nopager[do not send output through a pager, overrides ackrc, ACK_PAGER & ACK_PAGER_COLOR]' + '-s[suppress error messages about nonexistent or unreadable files]' + '(- 1 *)--thpppt[bill the cat]' + '*--type-del[remove all filters associated with TYPE]' \ + '(-x --files-from)-x[read the list of files to search from STDIN]' ) - ack_19_options=( '(-a --all -u --unrestricted)'{-a,--all}'[operate on all files, regardless of type (but still skip directories like blib, CVS, etc.)]' - '(-u --unrestricted -a --all)'{-u,--unrestricted}'[all files and directories (including blib/, core.*, ...) are searched, nothing is skipped]' + ack_19_options=( + '(-a --all -u --unrestricted)'{-a,--all}'[operate on all files, regardless of type (but still skip directories like blib, CVS, etc.)]' '-G+[only paths matching the given regex are included in the search]:regex' - '--invert-file-match[print/search handle files that do not match -g/-G]' + '--invert-file-match[print/search handle files that do not match -g/-G]' + '--line=[only print given line of each file]:number' \ + '(-u --unrestricted -a --all)'{-u,--unrestricted}'[all files and directories (including blib/, core.*, ...) are searched, nothing is skipped]' ) if (( $(_ack_version) > 2.0 )); then @@ -113,7 +129,6 @@ _ack() { '(-i --ignore-case)'{-i,--ignore-case}'[ignore case in the search strings]' \ '*--ignore-dir=[ignore directory]:directory:_files' \ '*--noignore-dir=[ignore directory]:directory:_files' \ - '--line=[only print given line of each file]:number' \ '(-l --files-with-matches -L --files-without-matches)'{-l,--files-with-matches}'[only print the filenames of matching files, instead of the matching text]' \ '(-L --files-without-matches -l --files-with-matches)'{-L,--files-without-matches}'[only print the filenames of files that do NOT match]' \ '--match=[specify the regular expression explicitly]:regex' \ @@ -143,15 +158,14 @@ _ack() { case $state in args) - if [[ CURRENT -eq NORMARG && ${+opt_args[--match]} -eq 0 ]] - then + if [[ CURRENT -eq NORMARG && ${+opt_args[--match]} -eq 0 ]]; then # If the current argument is the first non-option argument # and --match isn't present then a pattern is expected _message -e patterns 'pattern' && ret=0 else _files fi - ;; + ;; colors) local colors; colors=( 'black' 'on_black' @@ -173,7 +187,7 @@ _ack() { 'concealed' ) _describe -t 'colors' 'color' colors && ret=0 - ;; + ;; type-defs) if compset -P '*='; then local extensions; extensions=(*.*(:e)) @@ -181,11 +195,11 @@ _ack() { else _message -e type-name 'type name' && ret=0 fi - ;; + ;; types) local types; types=({'','no'}${_ack_raw_types/ ##/:}) _describe -t 'types' 'type' types - ;; + ;; esac return ret @@ -203,7 +217,7 @@ _ack_types_caching_policy() { # Rebuild if ackrc more recent than cache. [[ -f ${ACKRC:-$HOME/.ackrc} && ${ACKRC:-$HOME/.ackrc} -nt "$1" ]] && return 0 - # Rebuild if cache is older than one week. + # Rebuild if cache is older than one week. local -a oldp oldp=( "$1"(Nmw+1) ) (( $#oldp )) && return 0 diff --git a/src/_ag b/src/_ag index e35c133..6a41710 100644 --- a/src/_ag +++ b/src/_ag @@ -41,48 +41,41 @@ # vim: ft=zsh sw=2 ts=2 et # ------------------------------------------------------------------------------ _ag_version() { - local version cnt=0 - for i in $(ag --version); do - if [[ $cnt -eq 2 ]]; then - version=$i - break - fi - ((cnt += 1)) - done - + local version + version=( $($words[1] --version) ) + version=${version[@]:2:1} version=( "${(@s/./)version}" ) - printf "${version[2]}" + echo "${version[2]}" } # Dynamically build the file type completion # Modifies the global $AG_OPTS array _ag_add_file_types() { - local ttype exts - for i in $(ag --list-file-types); do - if [[ "$i" =~ '--' ]]; then - if [[ "${ttype}x" != "x" ]]; then - AG_OPTS+="(${ttype})${ttype}[${exts%% }]" + local typ exts + for i in $($words[1] --list-file-types); do + if [[ "${i:0:2}" = '--' ]]; then + if [[ "${typ}x" != "x" ]]; then + AG_OPTS+="${typ}[${exts}]" fi - ttype=$i + typ=$i exts= else - exts+="$i " + exts+=$i fi done - AG_OPTS+="(${ttype})${ttype}[${exts%% }]" + AG_OPTS+="${typ}[${exts}]" } # Add version appropriate options above base # Modifies the global $AG_OPTS array _ag_add_version_opts() { - local minor - minor=$(_ag_version) + local minor=$(_ag_version) if [[ $minor -gt 21 ]];then _ag_add_file_types AG_OPTS+=( - '(--list-file-types)--list-file-types[list supported filetypes to search]' - '(--silent)--silent[suppress all log messages, including errors]' + '(- 1 *)--list-file-types[list supported filetypes to search]' + '--silent[suppress all log messages, including errors]' ) fi @@ -102,7 +95,7 @@ _ag_add_version_opts() { AG_OPTS+=( '(-s --case-sensitive)'{-s,--case-sensitive}'[Match case sensitively. Default on.]' '(-H --noheading --heading)'{-H,--noheading,--heading}'[print file names above matching contents]' - '(--vimgrep)--vimgrep[output results like vim''s, :vimgrep /pattern/g would (report every match on the line)]' + '--vimgrep[output results like vim''s, :vimgrep /pattern/g would (report every match on the line)]' ) fi @@ -114,13 +107,13 @@ _ag_add_version_opts() { if [[ $minor -le 27 ]];then AG_OPTS+=( - '(--depth)--depth[Search up to NUM directories deep. Default is 25.]:NUM' + '--depth[Search up to NUM directories deep. Default is 25.]:number' ) fi if [[ $minor -gt 27 ]];then AG_OPTS+=( '(-c --count)'{-c,--count}'[only print the number of matches in each file]' - '(--depth)--depth[Search up to NUM directories deep, -1 for unlimited. Default is 25.]:NUM' + '--depth[Search up to NUM directories deep, -1 for unlimited. Default is 25.]:number' '(-F --fixed-strings)'{-F,--fixed-strings}'[alias for --literal for compatibility with grep]' ) fi @@ -145,62 +138,65 @@ _ag() { zstyle -s ":completion:${curcontext}:" cache-policy update_policy [[ -z "$update_policy" ]] && zstyle ":completion:${curcontext}:" cache-policy _ag_types_caching_policy + # Don't complete if command doesn't exist + [[ ${+commands[${words[1]}]} -eq 0 ]] && return 0 + if ( [[ ${+AG_OPTS} -eq 0 ]] || _cache_invalid "_AG_OPTS" ) && ! _retrieve_cache "_AG_OPTS"; then - # Base opts starts at ag version 0.14 + # Base opts starts at ag version 0.20 AG_OPTS=( '(- 1 *)--help[print a short help statement]' '(- 1 *)--man[print the manual page]' '(- 1 *)--version[display version and copyright information]' - '(--ackmate)--ackmate[output results in a format parseable by AckMate]' - '(-A --after)'{-A,--after}'[Print NUM lines before match. Default is 2]:LINES' - '(-t --all-text)'{-t,--all-text}"[search all text files, not including hidden]" - '(-a --all-types)'{-a,--all-types}"[Search all files. This doesn't include hidden files, and also doesn't respect any ignore files.]" - '(-B --before)'{-B,--before}'[Print NUM lines after match. Defaults is 2]:LINES' - '(-C --context)'{-C,--context}'[Print NUM lines before and after matches. Default is 2.]:LINES' - '(--color-line-number)--color-line-number[Color codes for line numbers. Default is 1;33.]' - '(--color-match)--color-match[Color codes for result match numbers. Default is 30;43.]' - '(--color-path)--color-path[Color codes for path names. Default is 1;32.]' - '(--column)--column[print column numbers in results]' + '--ackmate[output results in a format parseable by AckMate]' + '(-A --after)'{-A,--after}'[Print NUM lines before match. Default is 2]:number' + '(-t --all-text -a --all-types -u --unrestricted)'{-t,--all-text}"[search all text files, excluding hidden ones]" + '(-a --all-types -t --all-text -u --unrestricted)'{-a,--all-types}"[search all text files, excluding hidden ones and not obeying ignore files (.agignore, .gitignore...)]" + '(-B --before)'{-B,--before}'[Print NUM lines after match. Defaults is 2]:number' + '(--nobreak --break)'{--nobreak,--break}'[Print a newline between matches in different files. Default on.]' + '(--color --nocolor)--color[Print color codes in results. Default on.]' + '(--nocolor --color --color-line-number --color-match --color-path)--nocolor[Do not print color codes in results. Default on.]' + '(--nocolor)--color-line-number[Color codes for line numbers. Default is 1;33.]' + '(--nocolor)--color-match[Color codes for result match numbers. Default is 30;43.]' + '(--nocolor)--color-path[Color codes for path names. Default is 1;32.]' + '--column[print column numbers in results]' + '(-C --context)'{-C,--context}'[Print NUM lines before and after matches. Default is 2.]:number' '(-D --debug)'{-D,--debug}'[enable debug logging]' - '(-G --file-search-regex)'{-G,--file-search-regex}'[only search file names matching PATTERN]:PATTERN' + '(-G --file-search-regex)'{-G,--file-search-regex}'[only search file names matching PATTERN]:pattern' '(-l --files-with-matches)'{-l,--files-with-matches}'[only print filenames containing matches, not matching lines]' '(-L --files-without-matches)'{-L,--files-without-matches}"[only print filenames that don't contain matches]" '(-f --follow)'{-f,--follow}'[follow symlinks]' - '(-g)-g[print filenames that match PATTERN]:PATTERN' - '(--hidden)--hidden[search hidden files, still obeys ignore files.]' - '(--ignore)--ignore[Ignore files/directories matching this pattern. Literal file and directory names are also allowed.]' - '(-i --ignore-case)'{-i,--ignore-case}'[match case insensitively]:PATTERN' - '(--ignore-dir)--ignore-dir[alias for --ignore for compatibility with ack]' - '(-v --invert-match)'{-v,--invert-match}'[invert match]' - '(-Q --literal)'{-Q,--literal}'[Do not parse PATTERN as a regular expression. Try to match it literally.]' - '(-m --max-count)'{-m,--max-count}'[Skip the rest of a file after NUM matches. Default is 10,000.]:NUM' - '(--nobreak --break)'{--nobreak,--break}'[Print a newline between matches in different files. Default on.]' - '(--nocolor --color)'{--nocolor,--color}'[Print color codes in results. Default on.]' + '(-g)-g[print filenames that match PATTERN]:pattern' '(--nogroup --group)'{--nogroup,--group}'[same as --\[no\]break --\[no\]heading]' - '(--pager --nopager)'{--pager,--nopager}'[Display results with PAGER. Disabled by default.]' + '--hidden[search hidden files, still obeys ignore files.]' + '*--ignore[Ignore files/directories matching this pattern. Literal file and directory names are also allowed.]:files:_files' + '(-i --ignore-case)'{-i,--ignore-case}'[match case insensitively]:pattern' + '*--ignore-dir[alias for --ignore for compatibility with ack]:files:_files' + '(-v --invert-match)'{-v,--invert-match}'[invert match]' + '(-Q --literal)'{-Q,--literal}'[match PATTERN literally, no regular expression]' + '(-m --max-count)'{-m,--max-count}'[Skip the rest of a file after NUM matches. Default is 10,000.]:number' + '(--pager --nopager)'{--pager,--nopager}'[Display results with PAGER. Disabled by default.]:pager program:_command_names' '(--passthrough)--passthrough[when searching a stream, print all lines even if they don''t match]' - '(-p --path-to-agignore)'{-p,--path-to-agignore}'[provide a path to a specific .agignore file]:STRING' - '(--print-long-lines)--print-long-lines[Print matches on very long lines (> 2k characters by default)]' - '(--search-binary)--search-binary[search binary files for matches]' + '(-p --path-to-agignore)'{-p,--path-to-agignore}'[provide a path to a specific .agignore file]:files:_files' + '--print-long-lines[print matches on very long lines, > 2k characters by default]' + '--search-binary[search binary files]' '(-U --skip-vcs-ignores)'{-U,--skip-vcs-ignores}'[ignore VCS ignore files (.gitigore, .hgignore, svn:ignore), but still use .agignore]' '(-S --smart-case)'{-S,--smart-case}'[match case sensitively if PATTERN contains any uppercase letters, else match case insensitively]' - '(--stats)--stats[print stats (files scanned, time taken, etc)]' - '(-u --unrestricted)'{-u,--unrestricted}'[Search *all* files. This ignores .agignore, .gitignore, etc. It searches binary and hidden files as well.]' + '--stats[print stats (files scanned, time taken, etc)]' + '(-u --unrestricted -t --all-text -a --all-types)'{-u,--unrestricted}'[search ALL files, includes: hidden, binary & ignored files (.agignore, .gitignore...)]' '(-w --word-regexp)'{-w,--word-regexp}'[only match whole words]' - '*: :_files' - '1: :->patterns' ) _ag_add_version_opts + AG_OPTS+=( + '*: :_files' + ) [[ $#AG_OPTS -gt 0 ]] && _store_cache '_AG_OPTS' AG_OPTS fi - _arguments -C -s ${AG_OPTS} && ret=0 + _arguments -C -s -S ${AG_OPTS} && ret=0 unset AG_OPTS case $state in - patterns) - _message -e patterns 'pattern' && ret=0 - ;; + # placeholder esac return ret