#compdef fd ## # zsh completion function for fd # # Based on ripgrep completion function. # Originally based on code from the zsh-users project — see copyright notice # below. autoload -U is-at-least _fd() { local curcontext="$curcontext" no='!' ret=1 local -a context line state state_descr _arguments_options fd_types fd_args local -A opt_args if is-at-least 5.2; then _arguments_options=( -s -S ) else _arguments_options=( -s ) fi fd_types=( {f,file}'\:"regular files"' {d,directory}'\:"directories"' {l,symlink}'\:"symbolic links"' {e,empty}'\:"empty files or directories"' {x,executable}'\:"executable (files)"' {s,socket}'\:"sockets"' {p,pipe}'\:"named pipes (FIFOs)"' ) # Do not complete rare options unless either the current prefix # matches one of those options or the user has the `complete-all` # style set. Note that this prefix check has to be updated manually to account # for all of the potential negation options listed below! if # (--[bpsu]* => match all options marked with '$no') [[ $PREFIX$SUFFIX == --[bopsu]* ]] || zstyle -t ":complete:$curcontext:*" complete-all then no= fi # We make heavy use of argument groups here to prevent the option specs from # growing unwieldy. These aren't supported in zsh <5.4, though, so we'll strip # them out below if necessary. This makes the exclusions inaccurate on those # older versions, but oh well — it's not that big a deal fd_args=( + '(hidden)' # hidden files {-H,--hidden}'[search hidden files/directories]' + '(no-ignore-full)' # all ignore files '(no-ignore-partial)'{-I,--no-ignore}"[don't respect .(git|fd)ignore and global ignore files]" $no'(no-ignore-partial)*'{-u,--unrestricted}'[alias for --no-ignore, when repeated also alias for --hidden]' + no-ignore-partial # some ignore files "(no-ignore-full --no-ignore-vcs)--no-ignore-vcs[don't respect .gitignore files]" "!(no-ignore-full --no-global-ignore-file)--no-global-ignore-file[don't respect the global ignore file]" + '(case)' # case-sensitivity {-s,--case-sensitive}'[perform a case-sensitive search]' {-i,--ignore-case}'[perform a case-insensitive search]' + '(regex-pattern)' # regex-based search pattern '(no-regex-pattern)--regex[perform a regex-based search (default)]' + '(no-regex-pattern)' # non-regex-based search pattern {-g,--glob}'[perform a glob-based search]' {-F,--fixed-strings}'[treat pattern as literal string instead of a regex]' + '(match-full)' # match against full path {-p,--full-path}'[match the pattern against the full path instead of the basename]' + '(follow)' # follow symlinks {-L,--follow}'[follow symbolic links to directories]' + '(abs-path)' # show absolute paths '(long-listing)'{-a,--absolute-path}'[show absolute paths instead of relative paths]' + '(null-sep)' # use null separator for output '(long-listing)'{-0,--print0}'[separate search results by the null character]' + '(long-listing)' # long-listing output '(abs-path null-sep max-results exec-cmds)'{-l,--list-details}'[use a long listing format with file metadata]' + '(max-results)' # max number of results '(long-listing exec-cmds)--max-results=[limit number of search results to given count and quit]:count' '(long-listing exec-cmds)-1[limit to a single search result and quit]' + '(fs-errors)' # file-system errors $no'--show-errors[enable the display of filesystem errors]' + '(fs-traversal)' # file-system traversal $no"--one-file-system[don't descend into directories on other file systems]" '!--mount' '!--xdev' + dir-depth # directory depth '(--exact-depth -d --max-depth)'{-d+,--max-depth=}'[set max directory depth to descend when searching]:depth' '!(--exact-depth -d --max-depth)--maxdepth:depth' '(--exact-depth --min-depth)--min-depth=[set directory depth to descend before start searching]:depth' '(--exact-depth -d --max-depth --maxdepth --min-depth)--exact-depth=[only search at the exact given directory depth]:depth' + filter-misc # filter search '*'{-t+,--type=}"[filter search by type]:type:(($fd_types))" '*'{-e+,--extension=}'[filter search by file extension]:extension' '*'{-E+,--exclude=}'[exclude files/directories that match the given glob pattern]:glob pattern' '*'{-S+,--size=}'[limit search by file size]:size limit:->size' '(-o --owner)'{-o+,--owner=}'[filter by owning user and/or group]:owner and/or group:->owner' + ignore-file # extra ignore files '*--ignore-file=[add a custom, low-precedence ignore-file with .gitignore format]: :_files' + '(filter-mtime-newer)' # filter by files modified after than '--changed-within=[limit search to files/directories modified within the given date/duration]:date or duration' '!--change-newer-than=:date/duration' '!--newer=:date/duration' + '(filter-mtime-older)' # filter by files modified before than '--changed-before=[limit search to files/directories modified before the given date/duration]:date or duration' '!--change-older-than=:date/duration' '!--older=:date/duration' + '(color)' # colorize output {-c+,--color=}'[declare when to colorize search results]:when to colorize:(( auto\:"show colors if the output goes to an interactive console (default)" never\:"do not use colorized output" always\:"always use colorized output" ))' + '(threads)' {-j+,--threads=}'[set the number of threads for searching and executing]:number of threads' + '(exec-cmds)' # execute command '(long-listing max-results)'{-x+,--exec=}'[execute command for each search result]:command: _command_names -e:*\;::program arguments: _normal' '(long-listing max-results)'{-X+,--exec-batch=}'[execute command for all search results at once]:command: _command_names -e:*\;::program arguments: _normal' + other '!(--max-buffer-time)--max-buffer-time=[set amount of time to buffer before showing output]:time (ms)' + '(about)' # about flags '(: * -)'{-h,--help}'[display help message]' '(: * -)'{-v,--version}'[display version information]' + path-sep # set path separator for output $no'(--path-separator)--path-separator=[set the path separator to use when printing file paths]:path separator' + search-path $no'(--base-directory)--base-directory=[change the current working directory to the given path]:directory:_files -/' $no'(*)*--search-path=[set search path (instead of positional arguments)]:directory:_files -/' + args # positional arguments '1: :_guard "^-*" pattern' '(--search-path)*:directory:_files -/' ) # Strip out argument groups where unsupported (see above) is-at-least 5.4 || fd_args=( ${(@)args:#(#i)(+|[a-z0-9][a-z0-9_-]#|\([a-z0-9][a-z0-9_-]#\))} ) _arguments $_arguments_options : $fd_args && ret=0 case ${state} in owner) compset -P '(\\|)\!' if compset -P '*:'; then _groups && ret=0 else if compset -S ':*' || # Do not add the colon suffix when completing "!user # (with a starting double-quote) otherwise pressing tab again # after the inserted colon "!user: will complete history modifiers [[ $IPREFIX == (\\|\!)* && ($QIPREFIX == \"* && -z $QISUFFIX) ]] then _users && ret=0 else local q # Since quotes are needed when using the negation prefix !, # automatically remove the colon suffix also when closing the quote if [[ $QIPREFIX == [\'\"]* ]]; then q=${QIPREFIX:0:1} fi _users -r ": \t\n\-$q" -S : && ret=0 fi fi ;; size) if compset -P '[-+][0-9]##'; then local -a suff=( 'B:bytes' 'K:kilobytes (10^3 = 1000 bytes)' 'M:megabytes (10^6 = 1000^2 bytes)' 'G:gigabytes (10^9 = 1000^3 bytes)' 'T:terabytes (10^12 = 1000^4 bytes)' 'Ki:kibibytes ( 2^10 = 1024 bytes)' 'Mi:mebibytes ( 2^20 = 1024^2 bytes)' 'Gi:gigibytes ( 2^30 = 1024^3 bytes)' 'Ti:tebibytes ( 2^40 = 1024^4 bytes)' ) _describe -t units 'size limit units' suff -V 'units' elif compset -P '[-+]'; then _message -e 'size limit number (full format: <+->)' else _values 'size limit prefix (full format: )' \ '\+[file size must be greater or equal to]'\ '-[file size must be less than or equal to]' && ret=0 fi ;; esac return ret } _fd "$@" # ------------------------------------------------------------------------------ # Copyright (c) 2011 Github zsh-users - http://github.com/zsh-users # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the zsh-users nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ------------------------------------------------------------------------------ # Description # ----------- # # Completion script for fd # # ------------------------------------------------------------------------------ # Authors # ------- # # * smancill (https://github.com/smancill) # # ------------------------------------------------------------------------------ # Local Variables: # mode: shell-script # coding: utf-8-unix # indent-tabs-mode: nil # sh-indentation: 2 # sh-basic-offset: 2 # End: # vim: ft=zsh sw=2 ts=2 et