diff options
Diffstat (limited to 'plugins/xcode/xcode.plugin.zsh')
-rw-r--r-- | plugins/xcode/xcode.plugin.zsh | 151 |
1 files changed, 138 insertions, 13 deletions
diff --git a/plugins/xcode/xcode.plugin.zsh b/plugins/xcode/xcode.plugin.zsh index 1f547470d..b63a857a7 100644 --- a/plugins/xcode/xcode.plugin.zsh +++ b/plugins/xcode/xcode.plugin.zsh @@ -22,28 +22,153 @@ function xc { # Uses naming convention: # - different versions of Xcode are named Xcode-<version>.app or stored # in a folder named Xcode-<version> -# - the special version name "-" refers to the "default" Xcode.app with no suffix +# - the special version name "default" refers to the "default" Xcode.app with no suffix function xcselv { emulate -L zsh + if [[ $# == 0 ]]; then + echo "xcselv: error: no option or argument given" >&2 + echo "xcselv: see 'xcselv -h' for help" >&2 + return 1 + elif [[ $1 == "-p" ]]; then + _omz_xcode_print_active_version + return + elif [[ $1 == "-l" ]]; then + _omz_xcode_list_versions + return + elif [[ $1 == "-L" ]]; then + _omz_xcode_list_versions short + return + elif [[ $1 == "-h" ]]; then + _omz_xcode_print_xcselv_usage + return 0 + elif [[ $1 == -* && $1 != "-" ]]; then + echo "xcselv: error: unrecognized option: $1" >&2 + echo "xcselv: see 'xcselv -h' for help" >&2 + return 1 + fi + # Main case: "xcselv <version>" to select a version local version=$1 - local apps_dirs apps_dir apps app - apps_dirs=( $HOME/Applications /Applications ) - for apps_dir ($apps_dirs); do - if [[ $version == "-" ]]; then - apps=( $apps_dir/Xcode.app $apps_dir/Xcode/Xcode.app ) + local -A xcode_versions + _omz_xcode_locate_versions + if [[ -z ${xcode_versions[$version]} ]]; then + echo "xcselv: error: Xcode version '$version' not found" >&2 + return 1 + fi + app="${xcode_versions[$version]}" + echo "selecting Xcode $version: $app" + xcsel "$app" +} + +function _omz_xcode_print_xcselv_usage { + cat << EOF >&2 +Usage: + xcselv <version> + xcselv [options] + +Options: + <version> set the active Xcode version + -h print this help message and exit + -p print the active Xcode version + -l list installed Xcode versions (long human-readable form) + -L list installed Xcode versions (short form, version names only) +EOF +} + +# Parses the Xcode version from a filename based on our conventions +# Only meaningful when called from other _omz_xcode functions +function _omz_xcode_parse_versioned_file { + local file=$1 + local basename=${app:t} + local dir=${app:h} + local parent=${dir:t} + #echo "parent=$parent basename=$basename verstr=$verstr ver=$ver" >&2 + local verstr + if [[ $parent == Xcode* ]]; then + if [[ $basename == "Xcode.app" ]]; then + # "Xcode-<version>/Xcode.app" format + verstr=$parent else - apps=( $apps_dir/Xcode-$version.app $apps_dir/Xcode-$version/Xcode.app ) + # Both file and parent dir are versioned. Reject. + return 1; fi + elif [[ $basename == Xcode*.app ]]; then + # "Xcode-<version>.app" format + verstr=${basename:r} + else + # Invalid naming pattern + return 1; + fi + + local ver=${verstr#Xcode} + ver=${ver#[- ]} + if [[ -z $ver ]]; then + # Unversioned "default" installation location + ver="default" + fi + print -- "$ver" +} + +# Print the active version, using xcselv's notion of versions +function _omz_xcode_print_active_version { + emulate -L zsh + local -A xcode_versions + local versions version active_path + _omz_xcode_locate_versions + active_path=$(xcode-select -p) + active_path=${active_path%%/Contents/Developer*} + versions=(${(kni)xcode_versions}) + for version ($versions); do + if [[ "${xcode_versions[$version]}" == $active_path ]]; then + printf "%s (%s)\n" $version $active_path + return + fi + done + printf "%s (%s)\n" "<unknown>" $active_path +} + +# Locates all the installed versions of Xcode on this system, for this +# plugin's internal use. +# Populates the $xcode_versions associative array variable +# Caller should local-ize $xcode_versions with `local -A xcode_versions` +function _omz_xcode_locate_versions { + emulate -L zsh + local -a app_dirs + local app_dir apps app xcode_ver + # In increasing precedence order: + app_dirs=(/Applications $HOME/Applications) + for app_dir ($app_dirs); do + apps=( $app_dir/Xcode*.app(N) $app_dir/Xcode*/Xcode.app(N) ) for app ($apps); do - if [[ -e "$app" ]]; then - echo "selecting Xcode $version: $app" - xcsel "$app" - return + xcode_ver=$(_omz_xcode_parse_versioned_file $app) + if [[ $? != 0 ]]; then + continue fi + xcode_versions[$xcode_ver]=$app done done - echo "xcselv: Xcode version $version not found" - return 1 +} + +function _omz_xcode_list_versions { + emulate -L zsh + local -A xcode_versions + _omz_xcode_locate_versions + local width=1 width_i versions do_short=0 + if [[ $1 == "short" ]]; then + do_short=1 + fi + versions=(${(kni)xcode_versions}) + for version ($versions); do + if [[ $#version > $width ]]; then + width=$#version; + fi + done + for version ($versions); do + if [[ $do_short == 1 ]]; then + printf "%s\n" $version + else + printf "%-${width}s -> %s\n" "$version" "${xcode_versions[$version]}" + fi + done } function simulator { |