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