1function zsh_stats() {
2  fc -l 1 \
3    | awk '{ CMD[$2]++; count++; } END { for (a in CMD) print CMD[a] " " CMD[a]*100/count "% " a }' \
4    | grep -v "./" | sort -nr | head -n 20 | column -c3 -s " " -t | nl
5}
6
7function uninstall_oh_my_zsh() {
8  env ZSH="$ZSH" sh "$ZSH/tools/uninstall.sh"
9}
10
11function upgrade_oh_my_zsh() {
12  echo >&2 "${fg[yellow]}Note: \`$0\` is deprecated. Use \`omz update\` instead.$reset_color"
13  omz update
14}
15
16function open_command() {
17  local open_cmd
18
19  # define the open command
20  case "$OSTYPE" in
21    darwin*)  open_cmd='open' ;;
22    cygwin*)  open_cmd='cygstart' ;;
23    linux*)   [[ "$(uname -r)" != *icrosoft* ]] && open_cmd='nohup xdg-open' || {
24                open_cmd='cmd.exe /c start ""'
25                [[ -e "$1" ]] && { 1="$(wslpath -w "${1:a}")" || return 1 }
26              } ;;
27    msys*)    open_cmd='start ""' ;;
28    *)        echo "Platform $OSTYPE not supported"
29              return 1
30              ;;
31  esac
32
33  ${=open_cmd} "$@" &>/dev/null
34}
35
36# take functions
37
38# mkcd is equivalent to takedir
39function mkcd takedir() {
40  mkdir -p $@ && cd ${@:$#}
41}
42
43function takeurl() {
44  local data thedir
45  data="$(mktemp)"
46  curl -L "$1" > "$data"
47  tar xf "$data"
48  thedir="$(tar tf "$data" | head -n 1)"
49  rm "$data"
50  cd "$thedir"
51}
52
53function takegit() {
54  git clone "$1"
55  cd "$(basename ${1%%.git})"
56}
57
58function take() {
59  if [[ $1 =~ ^(https?|ftp).*\.tar\.(gz|bz2|xz)$ ]]; then
60    takeurl "$1"
61  elif [[ $1 =~ ^([A-Za-z0-9]\+@|https?|git|ssh|ftps?|rsync).*\.git/?$ ]]; then
62    takegit "$1"
63  else
64    takedir "$@"
65  fi
66}
67
68#
69# Get the value of an alias.
70#
71# Arguments:
72#    1. alias - The alias to get its value from
73# STDOUT:
74#    The value of alias $1 (if it has one).
75# Return value:
76#    0 if the alias was found,
77#    1 if it does not exist
78#
79function alias_value() {
80    (( $+aliases[$1] )) && echo $aliases[$1]
81}
82
83#
84# Try to get the value of an alias,
85# otherwise return the input.
86#
87# Arguments:
88#    1. alias - The alias to get its value from
89# STDOUT:
90#    The value of alias $1, or $1 if there is no alias $1.
91# Return value:
92#    Always 0
93#
94function try_alias_value() {
95    alias_value "$1" || echo "$1"
96}
97
98#
99# Set variable "$1" to default value "$2" if "$1" is not yet defined.
100#
101# Arguments:
102#    1. name - The variable to set
103#    2. val  - The default value
104# Return value:
105#    0 if the variable exists, 3 if it was set
106#
107function default() {
108    (( $+parameters[$1] )) && return 0
109    typeset -g "$1"="$2"   && return 3
110}
111
112#
113# Set environment variable "$1" to default value "$2" if "$1" is not yet defined.
114#
115# Arguments:
116#    1. name - The env variable to set
117#    2. val  - The default value
118# Return value:
119#    0 if the env variable exists, 3 if it was set
120#
121function env_default() {
122    [[ ${parameters[$1]} = *-export* ]] && return 0
123    export "$1=$2" && return 3
124}
125
126
127# Required for $langinfo
128zmodload zsh/langinfo
129
130# URL-encode a string
131#
132# Encodes a string using RFC 2396 URL-encoding (%-escaped).
133# See: https://www.ietf.org/rfc/rfc2396.txt
134#
135# By default, reserved characters and unreserved "mark" characters are
136# not escaped by this function. This allows the common usage of passing
137# an entire URL in, and encoding just special characters in it, with
138# the expectation that reserved and mark characters are used appropriately.
139# The -r and -m options turn on escaping of the reserved and mark characters,
140# respectively, which allows arbitrary strings to be fully escaped for
141# embedding inside URLs, where reserved characters might be misinterpreted.
142#
143# Prints the encoded string on stdout.
144# Returns nonzero if encoding failed.
145#
146# Usage:
147#  omz_urlencode [-r] [-m] [-P] <string>
148#
149#    -r causes reserved characters (;/?:@&=+$,) to be escaped
150#
151#    -m causes "mark" characters (_.!~*''()-) to be escaped
152#
153#    -P causes spaces to be encoded as '%20' instead of '+'
154function omz_urlencode() {
155  emulate -L zsh
156  local -a opts
157  zparseopts -D -E -a opts r m P
158
159  local in_str=$1
160  local url_str=""
161  local spaces_as_plus
162  if [[ -z $opts[(r)-P] ]]; then spaces_as_plus=1; fi
163  local str="$in_str"
164
165  # URLs must use UTF-8 encoding; convert str to UTF-8 if required
166  local encoding=$langinfo[CODESET]
167  local safe_encodings
168  safe_encodings=(UTF-8 utf8 US-ASCII)
169  if [[ -z ${safe_encodings[(r)$encoding]} ]]; then
170    str=$(echo -E "$str" | iconv -f $encoding -t UTF-8)
171    if [[ $? != 0 ]]; then
172      echo "Error converting string from $encoding to UTF-8" >&2
173      return 1
174    fi
175  fi
176
177  # Use LC_CTYPE=C to process text byte-by-byte
178  local i byte ord LC_ALL=C
179  export LC_ALL
180  local reserved=';/?:@&=+$,'
181  local mark='_.!~*''()-'
182  local dont_escape="[A-Za-z0-9"
183  if [[ -z $opts[(r)-r] ]]; then
184    dont_escape+=$reserved
185  fi
186  # $mark must be last because of the "-"
187  if [[ -z $opts[(r)-m] ]]; then
188    dont_escape+=$mark
189  fi
190  dont_escape+="]"
191
192  # Implemented to use a single printf call and avoid subshells in the loop,
193  # for performance (primarily on Windows).
194  local url_str=""
195  for (( i = 1; i <= ${#str}; ++i )); do
196    byte="$str[i]"
197    if [[ "$byte" =~ "$dont_escape" ]]; then
198      url_str+="$byte"
199    else
200      if [[ "$byte" == " " && -n $spaces_as_plus ]]; then
201        url_str+="+"
202      else
203        ord=$(( [##16] #byte ))
204        url_str+="%$ord"
205      fi
206    fi
207  done
208  echo -E "$url_str"
209}
210
211# URL-decode a string
212#
213# Decodes a RFC 2396 URL-encoded (%-escaped) string.
214# This decodes the '+' and '%' escapes in the input string, and leaves
215# other characters unchanged. Does not enforce that the input is a
216# valid URL-encoded string. This is a convenience to allow callers to
217# pass in a full URL or similar strings and decode them for human
218# presentation.
219#
220# Outputs the encoded string on stdout.
221# Returns nonzero if encoding failed.
222#
223# Usage:
224#   omz_urldecode <urlstring>  - prints decoded string followed by a newline
225function omz_urldecode {
226  emulate -L zsh
227  local encoded_url=$1
228
229  # Work bytewise, since URLs escape UTF-8 octets
230  local caller_encoding=$langinfo[CODESET]
231  local LC_ALL=C
232  export LC_ALL
233
234  # Change + back to ' '
235  local tmp=${encoded_url:gs/+/ /}
236  # Protect other escapes to pass through the printf unchanged
237  tmp=${tmp:gs/\\/\\\\/}
238  # Handle %-escapes by turning them into `\xXX` printf escapes
239  tmp=${tmp:gs/%/\\x/}
240  local decoded="$(printf -- "$tmp")"
241
242  # Now we have a UTF-8 encoded string in the variable. We need to re-encode
243  # it if caller is in a non-UTF-8 locale.
244  local -a safe_encodings
245  safe_encodings=(UTF-8 utf8 US-ASCII)
246  if [[ -z ${safe_encodings[(r)$caller_encoding]} ]]; then
247    decoded=$(echo -E "$decoded" | iconv -f UTF-8 -t $caller_encoding)
248    if [[ $? != 0 ]]; then
249      echo "Error converting string from UTF-8 to $caller_encoding" >&2
250      return 1
251    fi
252  fi
253
254  echo -E "$decoded"
255}
256