-
Notifications
You must be signed in to change notification settings - Fork 1
/
ic
executable file
·376 lines (346 loc) · 14.7 KB
/
ic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
#!/bin/sh
# ___ ________ ________ ________ ___ ________
# |\ \|\ ____\|\ __ \|\ ___ \|\ \|\ ____\
# \ \ \ \ \___|\ \ \|\ \ \ \\ \ \ \ \ \ \___|
# \ \ \ \ \ \ \ \\\ \ \ \\ \ \ \ \ \ \
# \ \ \ \ \____\ \ \\\ \ \ \\ \ \ \ \ \ \____
# \ \__\ \_______\ \_______\ \__\\ \__\ \__\ \_______\
# \|__|\|_______|\|_______|\|__| \|__|\|__|\|_______|
# ________ ________ _____ ______ _____ ______ ________ ________ ________ ________
# |\ ____\|\ __ \|\ _ \ _ \|\ _ \ _ \|\ __ \|\ ___ \|\ ___ \|\ ____\
# \ \ \___|\ \ \|\ \ \ \\\__\ \ \ \ \\\__\ \ \ \ \|\ \ \ \\ \ \ \ \_|\ \ \ \___|_
# \ \ \ \ \ \\\ \ \ \\|__| \ \ \ \\|__| \ \ \ __ \ \ \\ \ \ \ \ \\ \ \_____ \
# \ \ \____\ \ \\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\ \ \ \ \_\\ \|____|\ \
# \ \_______\ \_______\ \__\ \ \__\ \__\ \ \__\ \__\ \__\ \__\\ \__\ \_______\____\_\ \
# \|_______|\|_______|\|__| \|__|\|__| \|__|\|__|\|__|\|__| \|__|\|_______|\_________\
# \|_________|
#
# Description:
# Command to change file/folder icons from over 1000 icon designs.
# You can also register your own icons.
#
# Repository:
# https://github.com/ogty/iconic-commands
#
# Usage:
# ╭─ Zsh ──────────────────────────────────────────────────────────────────────────────────╮
# │ $ ic [options] <command> [<arguments>] │
# ╰────────────────────────────────────────────────────────────────────────────────────────╯
#
# Commands:
# file <file-name[@<type>]>:
# Change the icon of the specified file
#
# dir <directory-name[@<type>]>:
# Change the icon of the specified directory
#
# make <type-name> <icon-path/icon-url>:
# Make your own file icon
#
# conv <directory/file-name>@<type>:
# Converte file or directory icon
# - file: type=file extension
# - dir: type=directory icon name
#
# replace <directory-name>:
# Replaces all files and directories,
# including the specified directory,
# with the appropriate icon from the extension or name.
#
# Options:
# -l, --list <f/d>:
# Show available icons
# -h, --help:
# Show usage
#
# Note:
# If brew and npm are not installed, they will be installed automatically.
# The external commands used in this process are also installed at the same time.
# You may also be asked to enter a password to change permissions.
#
# Example:
# ╭─ Zsh ──────────────────────────────────────────────────────────────────────────────────╮
# │ $ ic file command@sh │
# │ $ ic dir fundamentals_of_java@java │
# │ $ ic conv foo@tmp │
# │ $ ic make your-service-name your-service-log.svg │
# │ $ ic make gopher \ │
# │ https://raw.githubusercontent.com/devicons/devicon/master/icons/go/go-original.svg │
# │ $ ic -l f │
# │ $ ic -l d │
# │ $ ic -h │
# ╰────────────────────────────────────────────────────────────────────────────────────────╯
TOP_DIR=$(cd $(dirname $0);pwd)
DATA_DIR="$TOP_DIR/data"
ICONS_DIR="$TOP_DIR/icons"
IMAGES_DIR="$TOP_DIR/images"
IGNORE_IMAGE_EXTENSIONS=("svg" "png" "jpg" "jpeg" "gif" "bmp" "ico" "tiff" "tif" "webp")
# awk program to get matching icon names from fileIcons.json or folderIcons.json
main='
BEGIN {
FS = ":";
}
function all_replacer(before, after, data) {
split(data, splited_data, before);
splited_data_length = length(splited_data);
for (i = 0; i < splited_data_length; i += 1) {
sub(before, after, data);
}
return data;
}
{
key = all_replacer("\"", "", $1);
key = all_replacer("\n", "", key);
key = all_replacer("\x20", "", key);
key = all_replacer("\x20", "", key);
key = all_replacer("\x20", "", key);
key = all_replacer("\x20", "", key);
if (target == key) {
value = all_replacer("\"", "", $2);
value = all_replacer(",", "", value);
value = all_replacer(" ", "", value);
print(value);
}
}
'
# Function to display command usage and options
help() {
echo "\n\t\tic: Iconic Commands\n"
echo "Usage:"
echo "\tic [options] <command> [<arguments>]\n"
echo "Commands:"
echo "\tfile <file-name[@<type>]>:"
echo "\t\tChange the icon of the specified file"
echo "\tdir <directory-name[@<type>]>:"
echo "\t\tChange the icon of the specified directory"
echo "\tmake <type-name> <icon-path | icon-url>:"
echo "\t\tMake your own file icon"
echo "\tconv <directory/file-name>@<type>:"
echo "\t\tConverte file or directory icon"
echo "\treplace <directory-name>:"
echo "\t\tReplaces all files and directories, including the specified directory,"
echo "\t\twith the appropriate icon from the extension or name.\n"
echo "Options:"
echo "\t-a, --all:"
echo "\t\tCan be used with file, dir and make commands"
echo "\t-l, --list:"
echo "\t\tShow available icons"
echo "\t-h, --help:"
echo "\t\tShow usage\n"
}
# Optional processing
while [ $# -gt 0 ]; do
case $1 in
-a|--all)
all=true
;;
-l|--list)
type=$2
if [ "$type" = "f" ]; then
echo "Available file icons:"
echo "======================"
cat $DATA_DIR/fileIcons.txt | more
echo
elif [ "$type" = "d" ]; then
echo "Available directory icons:"
echo "==========================="
cat $DATA_DIR/folderIcons.txt | more
echo
else
echo "Unknown type: $type"
echo "Available types: f, d"
echo "Usage:"
echo "\tic -l <f/d>"
echo "Example:"
echo "\tic -l f"
echo
exit 1
fi
;;
-h|--help)
help
exit 0
;;
*)
break
;;
esac
shift
done
# Command Processing
case $1 in
file)
# Raises an error if no command argument is given
if [ $# -lt 2 ]; then
echo "Error: file command requires a file name"
exit 1
fi
file=$2
if [[ "$file" == *@* ]]; then
name=$(echo $file | cut -d '@' -f 1) # file path
type=$(echo $file | cut -d '@' -f 2) # specified icon type
# Obtains icon names matching the specified icon type from fileIcons.json
icon=$(cat $DATA_DIR/fileIcons.json | awk -v target="$type" "$main")
# If there is no matching icon data, create a normal file with the touch command
if [ -z "$icon" ]; then
touch ./$file
else
# If no icon image has been generated, generate a new icon image.
if [ ! -f $IMAGES_DIR/$icon.png ]; then
rsvg-convert -h 120 $ICONS_DIR/$icon.svg > $IMAGES_DIR/$icon.png
fi
# file and convert it from the default icon to a matching icon or to the icon you want to specify.
touch ./$name && fileicon -q set ./$name $IMAGES_DIR/$icon.png
fi
exit 0
else
# Processing when the @ mark is not included in the command argument
fileName=$(echo $file | awk -F . '{print $1}'| tr '[:upper:]' '[:lower:]') # lowercase a file name
fileExtension=$(echo $file | awk -F . '{print $2}') # Get file extension
fi
# What to do if a file does not have a file extension
if [ -z "$fileExtension" ]; then
icon=$(cat $DATA_DIR/fileIcons.json | awk -v target="$fileName" "$main")
if [ -z "$icon" ]; then
touch ./$file
else
if [ ! -f $IMAGES_DIR/$icon.png ]; then
rsvg-convert -h 120 $ICONS_DIR/$icon.svg > $IMAGES_DIR/$icon.png
fi
touch ./$file && fileicon -q set ./$file $IMAGES_DIR/$icon.png
fi
else
# Processing when extensions are present
icon=$(cat $DATA_DIR/fileIcons.json | awk -v target="$fileName.$fileExtension" "$main")
if [ -n "$icon" ]; then
if [ ! -f $IMAGES_DIR/$icon.png ]; then
rsvg-convert -h 120 $ICONS_DIR/$icon.svg > $IMAGES_DIR/$icon.png
fi
touch ./$file && fileicon -q set ./$file $IMAGES_DIR/$icon.png
exit 0
fi
icon=$(cat $DATA_DIR/fileIcons.json | awk -v target="$fileExtension" "$main")
if [ -n "$icon" ]; then
if [ ! -f $IMAGES_DIR/$icon.png ]; then
rsvg-convert -h 120 $ICONS_DIR/$icon.svg > $IMAGES_DIR/$icon.png
fi
touch ./$file && fileicon -q set ./$file $IMAGES_DIR/$icon.png
exit 0
fi
touch ./$file
fi
;;
dir)
# Raises an error if no command argument is given
if [ $# -lt 2 ]; then
echo "Error: dir command requires a directory name"
exit 1
fi
dir=$2
if [[ "$dir" == *@* ]]; then
type=$(echo $dir | cut -d '@' -f 2)
name=$(echo $dir | cut -d '@' -f 1)
icon=$(cat $DATA_DIR/folderIcons.json | awk -v target="$type" "$main")
else
name=$dir
icon=$(cat $DATA_DIR/folderIcons.json | awk -v target="$dir" "$main")
fi
if [ -z $icon ]; then
mkdir ./$dir
else
if [ ! -f $IMAGES_DIR/$icon.png ]; then
rsvg-convert -h 120 $ICONS_DIR/$icon.svg > $IMAGES_DIR/$icon.png
fi
mkdir ./$name && fileicon -q set ./$name $IMAGES_DIR/$icon.png
fi
;;
make)
# Raises an error if no command argument is given
if [ $# -lt 3 ]; then
echo "Error: make command requires a type name and an icon path or url"
exit 1
fi
type=$2
icon=$3
# Prompts the user for input until a unique icon type name is determined
while [ $(cat $DATA_DIR/fileIcons.json | awk -v target="$type" "$main") ]; do
echo "Type already exists. Please enter a new name:"
read newType
type=$newType
done
# Writes unique icon type names to both folderIcons.json and fileIcons.json
sed -i -e "s/{/{\n \"$type\": \"$type\",/" $DATA_DIR/fileIcons.json
sed -i -e "s/{/{\n \"$type\": \"$type\",/" $DATA_DIR/folderIcons.json
# Get icon extension
iconExtension=$(echo $icon | awk -F . '{print $NF}')
# Processing when the icon is a URL
if [[ "$icon" == http* ]]; then
# If it is an svg, download it to the icons directory, otherwise download it to the images directory
if [[ "$iconExtension" == *svg ]]; then
curl -s -o $ICONS_DIR/$type.svg $icon
else
curl -s -o $IMAGES_DIR/$type.png $icon
fi
else
# If it is not an svg, i.e., a path, copy the data to a directory under the same conditions as the URL
if [[ "$iconExtension" == *svg ]]; then
cp $icon $ICONS_DIR
else
cp $icon $IMAGES_DIR
fi
fi
;;
conv)
if [ $# -lt 2 ]; then
echo "Error: conv command requires a directory/file name and a type"
exit 1
fi
file=$2
if [[ "$file" == *@* ]]; then
type=$(echo $file | cut -d '@' -f 2)
name=$(echo $file | cut -d '@' -f 1)
else
name=$file
fi
if [ -d "$name" ]; then
icon=$(cat $DATA_DIR/folderIcons.json | awk -v target="$type" "$main")
else
icon=$(cat $DATA_DIR/fileIcons.json | awk -v target="$type" "$main")
fi
if [ -z $icon ]; then
echo "Error: icon not found"
exit 1
fi
if [ ! -f $IMAGES_DIR/$icon.png ]; then
rsvg-convert -h 120 $ICONS_DIR/$icon.svg > $IMAGES_DIR/$icon.png
fi
fileicon -q set $name $IMAGES_DIR/$icon.png
;;
replace)
# Convert file/folder icons using the conv command above
if [ $# -lt 2 ]; then
echo "Error: replace command requires a directory name"
exit 1
fi
dir=$2
if [ ! -d $dir ]; then
echo "Error: directory not found"
exit 1
fi
find $dir -type d | grep -v "\/\." | while read dir; do
type=$(echo $dir | sed 's/.*\///')
ic conv $dir@$type > /dev/null 2>&1
done
find $dir -type f | grep -v "\/\." | while read file; do
type=$(echo $file | sed 's/.*\///')
type=$(echo $file | sed 's/.*\.//')
if [[ ! "${IGNORE_IMAGE_EXTENSIONS[*]}" =~ "$type" ]]; then
ic conv $file@$type > /dev/null 2>&1
fi
done
;;
*)
echo "Error: invalid command"
exit 1
;;
esac