-
Notifications
You must be signed in to change notification settings - Fork 1
/
shortcuts.plugin.zsh
411 lines (378 loc) · 13.5 KB
/
shortcuts.plugin.zsh
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
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
# shortcuts.plugin.zsh
# Define file and directory paths
SHORTCUTS_FILE="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/shortcuts/shortcuts.zsh"
BACKUP_DIR="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/shortcuts/backups"
PROFILE_DIR="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/shortcuts/profiles"
LOG_FILE="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/shortcuts/log.txt"
LAST_ACTION_FILE="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/shortcuts/last_action.zsh"
LINKS_FILE="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/shortcuts/links.txt"
# Ensure the necessary directories and files exist
[[ ! -f "$SHORTCUTS_FILE" ]] && touch "$SHORTCUTS_FILE"
[[ ! -d "$BACKUP_DIR" ]] && mkdir -p "$BACKUP_DIR"
[[ ! -d "$PROFILE_DIR" ]] && mkdir -p "$PROFILE_DIR"
[[ ! -f "$LOG_FILE" ]] && touch "$LOG_FILE"
[[ ! -f "$LAST_ACTION_FILE" ]] && touch "$LAST_ACTION_FILE"
[[ ! -f "$LINKS_FILE" ]] && touch "$LINKS_FILE"
[[ ! -f "$PROFILE_DIR/default.zsh" ]] && touch "$PROFILE_DIR/default.zsh" && echo "alias default='echo Default profile'" > "$PROFILE_DIR/default.zsh"
# Function to log actions
log_action() {
echo "$(date "+%Y-%m-%d %H:%M:%S") - $1" >> "$LOG_FILE"
}
# Function to source the shortcuts file
function source_shortcuts_file() {
source "$SHORTCUTS_FILE"
echo "Shortcuts reloaded successfully."
}
# Function: Display help
function display_help() {
cat << EOF
Usage: shortcuts [OPTION] [ARGS...]
Manage command shortcuts with features including backup, restore, grouping, profiles, undo, search, toggle, import/export, logging, link management, and profile initialization.
Options:
-h Display help
-a <alias> <cmd> Add a new shortcut
-r <alias> Remove a shortcut
-l List all shortcuts
-e <alias> <cmd> Edit an existing shortcut
-b Backup current shortcuts
-s Restore shortcuts from the latest backup
-g <group> List shortcuts in a specific group
-p <profile> Switch to a specific profile
-u Undo last action
-f <search> Search shortcuts
-t <alias> Toggle shortcut activation/deactivation
-i <file> Import shortcuts from a file
-x <file> Export shortcuts to a file
-lp List all profiles
-dp <profile> Delete a specific profile
-source Source the shortcuts file
-la <link> Add a link to import shortcuts from
-rl <link> Remove a link
-ra Remove all shortcuts
-ap <profile> Add a new profile
-up Update shortcuts from links
Examples:
shortcuts -a g:ls 'ls -la' Add a new shortcut 'ls' in group 'g'
shortcuts -r g:ls Remove the 'g:ls' shortcut
shortcuts -l List all shortcuts
shortcuts -e g:ls 'ls -l' Edit the 'g:ls' shortcut to 'ls -l'
shortcuts -b Backup current shortcuts
shortcuts -s Restore shortcuts from the latest backup
shortcuts -g dev List all 'dev' group shortcuts
shortcuts -p work Switch to 'work' profile shortcuts
shortcuts -u Undo last change
shortcuts -f "pattern" Search shortcuts with "pattern"
shortcuts -t alias Toggle shortcut activation/deactivation
shortcuts -i /path/to/file Import shortcuts from a file
shortcuts -x /path/to/file Export shortcuts to a file
shortcuts -lp List all profiles
shortcuts -dp work Delete 'work' profile
shortcuts -source Source the shortcuts file
shortcuts -la http://link.com Add a link to import shortcuts from
shortcuts -rl http://link.com Remove a link
shortcuts -ra Remove all shortcuts
shortcuts -ap new_profile Add a new profile
shortcuts -up Update shortcuts from links
EOF
}
# Backup functions
function backup_shortcuts() {
local timestamp=$(date "+%Y%m%d%H%M%S")
cp "$SHORTCUTS_FILE" "$BACKUP_DIR/shortcuts_$timestamp.zsh"
echo "Backup created: shortcuts_$timestamp.zsh"
log_action "Backup created: shortcuts_$timestamp.zsh"
}
function restore_shortcuts() {
local latest_backup=$(ls -t "$BACKUP_DIR" | head -1)
if [[ -z "$latest_backup" ]]; then
echo "No backup found."
return 1
fi
cp "$BACKUP_DIR/$latest_backup" "$SHORTCUTS_FILE"
echo "Restored from backup: $latest_backup"
source_shortcuts_file
log_action "Restored from backup: $latest_backup"
}
# Undo functionality
function undo_last_change() {
local last_backup=$(cat "$LAST_ACTION_FILE")
if [[ -z "$last_backup" ]]; then
echo "No last action to undo."
return 1
fi
if [[ -f "$BACKUP_DIR/$last_backup.zsh" ]]; then
cp "$BACKUP_DIR/$last_backup.zsh" "$SHORTCUTS_FILE"
echo "Undo successful: restored $last_backup"
source_shortcuts_file
log_action "Undo successful: restored $last_backup"
else
echo "Undo failed: backup not found."
fi
}
# Add a new shortcut
function add_shortcut() {
pre_change_backup
if grep -q "^alias $1=" "$SHORTCUTS_FILE"; then
echo "Shortcut '$1' already exists."
return 1
fi
echo "alias $1='$2'" >> "$SHORTCUTS_FILE"
echo "Shortcut $1 added."
log_action "Shortcut $1 added."
source_shortcuts_file
}
# Remove an existing shortcut
function remove_shortcut() {
pre_change_backup
if grep -q "^alias $1=" "$SHORTCUTS_FILE"; then
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i "" "/^alias $1=/d" "$SHORTCUTS_FILE"
else
sed -i "/^alias $1=/d" "$SHORTCUTS_FILE"
fi
echo "Shortcut $1 removed."
log_action "Shortcut $1 removed."
echo "Attempting to unalias $1..."
alias $1 &>/dev/null && unalias $1 && echo "Unaliased $1 successfully."
source_shortcuts_file
else
echo "Shortcut '$1' does not exist."
fi
}
# Edit an existing shortcut
function edit_shortcut() {
pre_change_backup
if grep -q "^alias $1=" "$SHORTCUTS_FILE"; then
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i "" "/^alias $1=/c\alias $1='$2'" "$SHORTCUTS_FILE"
else
sed -i "/^alias $1=/c\alias $1='$2'" "$SHORTCUTS_FILE"
fi
echo "Shortcut $1 updated."
log_action "Shortcut $1 updated."
source_shortcuts_file
else
echo "Shortcut '$1' does not exist. Use -a to add it."
fi
}
# List all shortcuts
function list_shortcuts() {
echo "Shortcuts available:"
grep "^alias " "$SHORTCUTS_FILE"
}
# Search for shortcuts
function search_shortcuts() {
local pattern=$1
echo "Searching for shortcuts containing '$pattern':"
grep -E "alias .*${pattern}.*=" "$SHORTCUTS_FILE" | less
}
# Toggle shortcut activation/deactivation
function toggle_shortcut() {
pre_change_backup
local alias_name=$1
if grep -q "^alias $alias_name=" "$SHORTCUTS_FILE"; then
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i "" "s/^alias $alias_name=/#&/" "$SHORTCUTS_FILE"
else
sed -i "s/^alias $alias_name=/#&/" "$SHORTCUTS_FILE"
fi
echo "Shortcut $alias_name deactivated."
log_action "Shortcut $alias_name deactivated."
source_shortcuts_file
elif grep -q "^#alias $alias_name=" "$SHORTCUTS_FILE"; then
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i "" "s/^#alias $alias_name=/alias $alias_name=/" "$SHORTCUTS_FILE"
else
sed -i "s/^#alias $alias_name=/alias $alias_name=/" "$SHORTCUTS_FILE"
fi
echo "Shortcut $alias_name activated."
log_action "Shortcut $alias_name activated."
source_shortcuts_file
else
echo "Shortcut '$alias_name' does not exist."
fi
}
# Import and Export shortcuts
function import_shortcuts() {
pre_change_backup
local import_file=$1
if [[ -f "$import_file" ]]; then
cp "$import_file" "$SHORTCUTS_FILE"
echo "Imported shortcuts from $import_file."
log_action "Imported shortcuts from $import_file."
source_shortcuts_file
else
echo "Import file does not exist."
fi
}
function export_shortcuts() {
local export_file=$1
cp "$SHORTCUTS_FILE" "$export_file"
echo "Exported shortcuts to $export_file."
log_action "Exported shortcuts to $export_file."
}
# Switch profile
function switch_profile() {
pre_change_backup
local profile_path="$PROFILE_DIR/$1.zsh"
if [[ ! -f "$profile_path" ]]; then
echo "Profile '$1' does not exist."
return 1
fi
cp "$profile_path" "$SHORTCUTS_FILE"
echo "Switched to profile '$1'."
source_shortcuts_file
log_action "Switched to profile '$1'."
}
# Add a new profile
function add_profile() {
local profile=$1
local profile_path="$PROFILE_DIR/${profile}.zsh"
if [[ -f "$profile_path" ]]; then
echo "Profile '$profile' already exists."
return 1
fi
touch "$profile_path"
echo "Profile '$profile' created."
log_action "Profile '$profile' created."
}
# Pre-change backup
function pre_change_backup() {
local timestamp=$(date "+%Y%m%d%H%M%S")
cp "$SHORTCUTS_FILE" "$BACKUP_DIR/pre_change_$timestamp.zsh"
echo "pre_change_$timestamp" > "$LAST_ACTION_FILE"
}
# Autocompletion setup
function _shortcuts_autocomplete() {
local cur=${COMP_WORDS[COMP_CWORD]}
local prev=${COMP_WORDS[COMP_CWORD-1]}
local actions="-h -a -r -l -e -b -s -g -p -u -f -t -i -x -lp -dp -source -la -rl -ra -ap -up"
local aliases=$(grep "^alias " "$SHORTCUTS_FILE" | cut -d' ' -f2 | cut -d'=' -f1)
local profiles=$(ls "$PROFILE_DIR" | sed 's/\.zsh$//')
local links=$(cat "$LINKS_FILE")
case "$prev" in
-r|-e|-t)
COMPREPLY=($(compgen -W "${aliases}" -- "$cur"))
return 0;;
-p|-dp|-ap)
COMPREPLY=($(compgen -W "${profiles}" -- "$cur"))
return 0;;
-rl)
COMPREPLY=($(compgen -W "${links}" -- "$cur"))
return 0;;
esac
if [[ ${COMP_CWORD} == 1 ]]; then
COMPREPLY=($(compgen -W "${actions}" -- "$cur"))
fi
}
complete -F _shortcuts_autocomplete shortcuts
# List all profiles
function list_profiles() {
echo "Available profiles:"
local profiles=$(ls "$PROFILE_DIR" | sed 's/\.zsh$//')
echo "$profiles"
}
# Delete a specific profile
function delete_profile() {
local profile=$1
local profile_path="$PROFILE_DIR/${profile}.zsh"
if [[ -f "$profile_path" ]]; then
rm -f "$profile_path"
echo "Profile '$profile' deleted."
log_action "Profile '$profile' deleted."
# If the deleted profile was the default, also clear the shortcuts file
if [[ "$profile" == "default" ]]; then
> "$SHORTCUTS_FILE"
echo "All shortcuts removed."
log_action "All shortcuts removed."
source_shortcuts_file
fi
else
echo "Profile '$profile' does not exist."
fi
}
# Add a link to import shortcuts from
function add_link() {
local link=$1
if grep -q "^$link$" "$LINKS_FILE"; then
echo "Link '$link' already exists."
else
echo "$link" >> "$LINKS_FILE"
echo "Link '$link' added."
log_action "Link '$link' added."
fi
}
# Remove a link
function remove_link() {
local link=$1
if grep -q "^$link$" "$LINKS_FILE"; then
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i "" "/^$link$/d" "$LINKS_FILE"
else
sed -i "/^$link$/d" "$LINKS_FILE"
fi
echo "Link '$link' removed."
log_action "Link '$link' removed."
else
echo "Link '$link' does not exist."
fi
}
# Remove all shortcuts
function remove_all_shortcuts() {
pre_change_backup
> "$SHORTCUTS_FILE"
echo "All shortcuts removed."
log_action "All shortcuts removed."
# Explicitly unalias all current shortcuts to prevent any hanging
while IFS= read -r line; do
if [[ "$line" == alias* ]]; then
local alias_name=$(echo "$line" | cut -d' ' -f2 | cut -d'=' -f1)
unalias "$alias_name" 2>/dev/null
fi
done < "$SHORTCUTS_FILE"
source_shortcuts_file
}
# Function to update shortcuts from the provided links
function update_shortcuts() {
if [[ ! -s "$LINKS_FILE" ]]; then
echo "No links found to update shortcuts."
return 1
fi
pre_change_backup
while IFS= read -r link; do
curl -fsSL "$link" | sed 's/\r$//' >> "$SHORTCUTS_FILE"
done < "$LINKS_FILE"
echo "Shortcuts updated from links."
log_action "Shortcuts updated from links."
source_shortcuts_file
}
# Main function to manage shortcuts
function shortcuts() {
case "$1" in
-h) display_help ;;
-a) shift; add_shortcut "$@" ;;
-r) shift; remove_shortcut "$@" ;;
-l) list_shortcuts ;;
-e) shift; edit_shortcut "$@" ;;
-b) backup_shortcuts ;;
-s) restore_shortcuts ;;
-g) shift; list_group_shortcuts "$@" ;;
-p) shift; switch_profile "$@" ;;
-u) undo_last_change ;;
-f) shift; search_shortcuts "$@" ;;
-t) shift; toggle_shortcut "$@" ;;
-i) shift; import_shortcuts "$@" ;;
-x) shift; export_shortcuts "$@" ;;
-lp) list_profiles ;;
-dp) shift; delete_profile "$@" ;;
-source) source_shortcuts_file ;;
-la) shift; add_link "$@" ;;
-rl) shift; remove_link "$@" ;;
-ra) remove_all_shortcuts ;;
-ap) shift; add_profile "$@" ;;
-up) update_shortcuts ;;
*) echo "Invalid option. Use -h for help." ;;
esac
}
# Load existing shortcuts
source "$SHORTCUTS_FILE"