#compdef mdfind # Author: W. G. Scott # Revised for 10.5 on Jan 22 2009 # July 5 2005 # for Mac OS X v. 10.4 and above # set -x # Use a new version for 10.5 and above: if [[ $(uname) == Darwin && $(sw_vers -productVersion) < 10.5 ]]; then # Old version of completion function for OS X 10.4: _mdfind () { ######################################################################################################## # These have to be put in the environment file to work the first time # zmodload zsh/complist 2>/dev/null zstyle ':completion:*' menu select=10 zstyle ':completion:*' list-prompt '%S -- more -- %s' zstyle ':completion:*' group-name '' ######################################################################################################### # SYNOPSIS mdfind [-0] [-live] [-onlyin directory] query # # -0 Prints an ASCII NUL character after each result path. This # is useful when used in conjunction with xargs -0. # # -live Causes the mdfind command to provide live-updates to the num- # ber of files matching the query. When an update causes the # query results to change the number of matches is updated. # The find can be cancelled by typing ctrl-C. # # -onlyin dir # Limit the scope of the search to the directory specified. # # example: # mdfind -onlyin /Applications -onlyin /Developer "kMDItemContentType == 'com.apple.application-*'" ######################################################################################################## _arguments -C \ '-gui[use GUI menu of completions]: :->usethegui'\ '-0[used in conjunction with xargs -0]'\ '-live[live updates in search]'\ '-onlyin[specify the Directory]: :->mdsearchpath'\ '*: :->mdsearchstring' #################################################################################### # These functions are for "mdsearchstring" # This function corresponds to simply entering any unrestricted string. # There isn't anything to complete, but we need to add a space to get it to # work right. (The _nothing fuction I would think should work, but it doesn't.) function _stringquery { compadd -X %B' i.e., type in your search string at the prompt, %b' " " #_message "Now type in your search string," } ######################################################################################## # This function generates a template for a search that is to be confined to a specified # metadata attribute. It uses mdimport -A to find the list of possibilities, and then # generates a template as the completion. It terminates with a single and double quote. # The quoting structure is important. function _querycomp { compadd -X %B' or select one of the metadata attributes for searching from the menu below %b' \ -Q -P \" -p kMDItem -S " == '*YourSearchStringGoesHere*'\"" $(/usr/bin/mdimport -A | awk '{print $1}' | \ perl -p -e "s;('|kMDItem);;g" ) } ######################################################################################## # If we want to add a second metadata search template, we have to first remove the # trailing double quote that follows the single quote generated by _querycomp function _chomp { BUFFER=${BUFFER/\'\"/\'} } #' ######################################################################################## # This function first calls _chomp to chomp off the double quote, and then it appends the # Boolean AND operator (&&) and then the second template, which closes with a single and # then double quote. Any number of these can be added recursively, thanks to putting the # _chomp function at the beginning. function _queryandcomp { # Boolean and to append a second query compadd -R _chomp -X %B'The metadata attributes, below, alternate Boolian AND and OR %b' \ -Q -P \&\&\ -p kMDItem -S \ " == '*YourSearchStringGoesHere*'\"" $(/usr/bin/mdimport -A | awk '{print $1}' | \ perl -p -e "s;('|kMDItem);;g" ) } ######################################################################################## # Same as _queryand, except uses the Boolean OR operator (||). function _queryorcomp { # Boolean or appends a second query compadd -R _chomp -X %B'The metadata attributes, below, alternate Boolian AND and OR %b' \ -Q -P \|\|\ -p kMDItem -S \ " == '*YourSearchStringGoesHere*'\"" $(/usr/bin/mdimport -A | awk '{print $1}' | \ perl -p -e "s;('|kMDItem);;g" ) } ######################################################################################## #################################################################################### #################################################################################### case "$state" in (usethegui) _message 'Using Pashua GUI menu: please select a completion category' _mdfind_pashua ;; (mdsearchstring) if [[ $words == *kMDItem* && $words != *gui* ]];then _message "Adding another searching criterion ..." _alternative _queryandcomp _queryorcomp elif [[ $words == *kMDItem* ]];then _message "Adding another searching criterion ..." _message 'Using Pashua GUI menu: please select a completion category' _mdfind_pashua else _message "Enter any string either by itself or by replacing \"YourStringGoesHere\" in the metadata search template." _alternative _stringquery _querycomp fi ;; (mdsearchpath) _directories _message 'possible search paths: prepend / for root-level directories' ;; esac } else # New version of completion function for OS X 10.5 and above: _mdfind () { ######################################################################################################## # These have to be put in the environment file to work the first time # zmodload zsh/complist 2>/dev/null zstyle ':completion:*' menu select=10 zstyle ':completion:*' list-prompt '%S -- more -- %s' zstyle ':completion:*' group-name '' ######################################################################################################### # # SYNOPSIS # mdfind [-live] [-count] [-onlyin directory] query # # DESCRIPTION # The mdfind command consults the central metadata store and returns a list of files that match the given # metadata query. The query can be a string or a query expression. # # The following options are available: # # -0 Prints an ASCII NUL character after each result path. This is useful when used in conjunc- # tion with xargs -0. # # -live Causes the mdfind command to provide live-updates to the number of files matching the # query. When an update causes the query results to change the number of matches is updated. # The find can be cancelled by typing ctrl-C. # # -count Causes the mdfind command to output the total number of matches, instead of the path to the # matching items. # # -onlyin dir # Limit the scope of the search to the directory specified. # # -literal Force the provided query string to be taken as a literal query string, without interpreta- # tion. # # -interpret Force the provided query string to be interpreted as if the user had typed the string into # the Spotlight menu. For example, the string "search" would produce the following query # string: # (* = search* cdw || kMDItemTextContent = search* cdw) # # EXAMPLES # The following examples are shown as given to the shell. # # This returns all files with any metadata attribute value matching the string "image": # # mdfind image # # This returns all files that contain "MyFavoriteAuthor" in the kMDItemAuthor metadata attribute: # # mdfind "kMDItemAuthor == '*MyFavoriteAuthor*'" # # This returns all files with any metadata attribute value matching the string "skateboard". The find # continues to run after gathering the initial results, providing a count of the number of files that # match the query. # # mdfind -live skateboard # # relevant example: # # mdfind -onlyin /Applications -onlyin /Developer "kMDItemContentType == 'com.apple.application-*'" ######################################################################################################## _arguments -C \ '-0[used in conjunction with xargs -0]: :->supply_pattern'\ '-s[show contents of smart folder ]: :->savedSearch'\ '-count[output total number of matches]: :->supply_pattern' \ '-interpret[user-friendly Spotlight string query]: :->supply_pattern'\ '-literal[force over-rides interpret]: :->mdsearchstring'\ '-live[live updates in search]: :->supply_pattern'\ '-onlyin[specify the Directory]: :->mdsearchpath'\ '*: :->supply_pattern_or_option' # '*:pattern: ' #################################################################################### # This function is for "savedSearch" function _SavedSearches { compadd \ "${(f)"$( command ls ~/Library/Saved\ Searches/**/*.savedSearch | perl -p -e "s|$HOME/Library/Saved\ Searches/||g",'s|.savedSearch||g' )"}" } #################################################################################### # These functions are for "mdsearchstring" # This function corresponds to simply entering any unrestricted string. # There isn't anything to complete, but we need to add a space to get it to # work right. (The _nothing fuction I would think should work, but it doesn't.) function _stringquery { compadd -X %B' i.e., type in your search string at the prompt, %b' " " #_message "Now type in your search string," } ######################################################################################## # This function generates a template for a search that is to be confined to a specified # metadata attribute. It uses mdimport -A to find the list of possibilities, and then # generates a template as the completion. It terminates with a single and double quote. # The quoting structure is important. function _querycomp { compadd -X %B' or select one of the metadata attributes for searching from the menu below %b' \ -Q -P \" -p kMDItem -S " == '*YourSearchStringGoesHere*'\"" $(/usr/bin/mdimport -A | awk '{print $1}' | \ perl -p -e "s;('|kMDItem);;g" ) } ######################################################################################## # If we want to add a second metadata search template, we have to first remove the # trailing double quote that follows the single quote generated by _querycomp function _chomp { BUFFER=${BUFFER/\'\"/\'} } #' ######################################################################################## # This function first calls _chomp to chomp off the double quote, and then it appends the # Boolean AND operator (&&) and then the second template, which closes with a single and # then double quote. Any number of these can be added recursively, thanks to putting the # _chomp function at the beginning. function _queryandcomp { # Boolean and to append a second query compadd -R _chomp -X %B'The metadata attributes, below, alternate Boolian AND and OR %b' \ -Q -P \&\&\ -p kMDItem -S \ " == '*YourSearchStringGoesHere*'\"" $(/usr/bin/mdimport -A | awk '{print $1}' | \ perl -p -e "s;('|kMDItem);;g" ) } ######################################################################################## # Same as _queryand, except uses the Boolean OR operator (||). function _queryorcomp { # Boolean or appends a second query compadd -R _chomp -X %B'The metadata attributes, below, alternate Boolian AND and OR %b' \ -Q -P \|\|\ -p kMDItem -S \ " == '*YourSearchStringGoesHere*'\"" $(/usr/bin/mdimport -A | awk '{print $1}' | \ perl -p -e "s;('|kMDItem);;g" ) } ######################################################################################## #################################################################################### #################################################################################### case "$state" in (mdsearchstring) if [[ $words == *kMDItem* && $words != *gui* ]];then _message "Adding another searching criterion ..." _alternative _queryandcomp _queryorcomp elif [[ $words == *kMDItem* ]];then _message "Adding another searching criterion ..." _message 'Using Pashua GUI menu: please select a completion category' _mdfind_pashua else _message "Enter any string either by itself or by replacing \"YourStringGoesHere\" in the metadata search template." _alternative _stringquery _querycomp fi ;; (mdsearchpath) _directories _message 'possible search paths: prepend / for root-level directories' ;; (savedSearch) _SavedSearches _message 'possible Saved Searches in $HOME/Library/Saved\ Searches' ;; (supply_pattern) _message "Enter any string you would supply to SpotLight." ;; (supply_pattern_or_option) _message "Enter \"-\" to choose an option, or simply type any string you would supply to SpotLight." ;; esac } fi # Test OS X 10.5 or above _mdfind "$@"