-
Notifications
You must be signed in to change notification settings - Fork 0
/
bookmark.sh
executable file
·139 lines (127 loc) · 3.67 KB
/
bookmark.sh
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
#!/bin/sh
#
# UNIVERSAL BOOKMARK MANAGER
#
##########
# CONFIG #
##########
# Menu cmd such that the first argument passed is taken as the prompt text.
alias menu="tofi --width 90% --height 90% --font-size 16 --prompt-text"
# Menu cmd such that the first argument passed is taken as the prompt text,
# and to be used as input field.
# Despite no match, the input is printed to stdout.
alias menu-input="tofi --require-match false --font-size 16 --padding-top 25 --padding-bottom 25 --padding-left 35 --padding-right 25 --prompt-text"
store_dir="${XDG_DATA_HOME:-$HOME/.local/share}/bookmarking"
store_file="$store_dir/bookmarks"
##########
usage() {
echo "Usage: $PROGRAM <add|remove|pick|git|edit>"
}
bookmark_to_pick() {
cat $store_file | menu "Pick: "
}
bookmark_to_remove() {
cat $store_file | menu "Remove: "
}
# Asks the user for tags recursively,
# listing what tags exist so far.
ask_tag() {
new_tag="$(printf "$existing_tags" | menu-input "Tag $n: " | tr ' ' '-')"
if [ -n "$new_tag" ]
then
new_tags="$(printf "$tags\n#$new_tag")"
# If the added tag is new
if [ -z "$(printf "$new_tags" | sort | uniq -D)" ]
then
existing_tags="$(printf "$existing_tags$new_tag" | sort -u)\n"
tags="$(printf "$new_tags" | sort -u)"
n="$((n+1))"
fi
ask_tag
fi
}
PROGRAM="${0##*/}"
COMMAND="$1"
# Create necessary dirs
mkdir -p "$(dirname $store_file)"
if [ "$#" -lt 1 ]
then
usage
exit 1
fi
if [ "$COMMAND" = "git" ]
then
# Forward arguments as if git was called from the store directory
shift
git -C "$store_dir" "$@"
elif [ "$COMMAND" = "edit" ]
then
# Open the preferred editor to edit the store file
"$EDITOR" "$store_file"
elif [ "$COMMAND" = "add" ]
then
# Add the current selection to the store_file
bookmark="$(wl-paste --primary 2> /dev/null)"
if [ -n "$bookmark" ]
then
# Verify correctness of bookmark
if printf "$bookmark" | grep " "
then
notify-send "Cannot copy invalid bookmark!" "Spaces are not allowed."
exit 1
fi
# Verify existence of bookmark, ignoring any tags
if grep -qP "^$bookmark(?= )" "$store_file"
then
notify-send "Already bookmarked!"
else
# Prompt for tags, listing existing tags
existing_tags="$(cat "$store_file" | grep -Po "(?<= #)[^ ]+" | sort -u)"
# `sort` does not append a newline to the last line when printing to stdout.
# Append the newline if the string is not empty.
if [ -n "$existing_tags" ]
then
existing_tags="$existing_tags\n"
fi
tags=''
n=1
ask_tag
bookmark_with_tags="$bookmark$(printf "$tags" | tr '\n' ' ')"
echo "$bookmark_with_tags" >> "$store_file"
notify-send "Bookmark added!" "$bookmark"
fi
else
notify-send "Clipboard is empty!" "Nothing to bookmark"
fi
elif [ "$COMMAND" = "remove" ]
then
# Remove the chosen bookmark from the store_file
bookmark_with_tags="$(bookmark_to_remove)"
if [ -n "$bookmark_with_tags" ]
then
if sed -i "\|^$bookmark_with_tags$|d" "$store_file"
then
notify-send "Bookmark removed!" "$bookmark_with_tags"
else
notify-send "Bookmark does not exist!" "$bookmark_with_tags"
fi
fi
elif [ "$COMMAND" = "pick" ]
then
# Let the user choose a bookmark and copy the chosen bookmark
bookmark_with_tags="$(bookmark_to_pick)"
if [ -n "$bookmark_with_tags" ]
then
if grep -q "^$bookmark_with_tags$" "$store_file"
then
# Copy the bookmark without the tags
printf "$bookmark_with_tags" | grep -Eo "^[^ ]+" | tr -d '\n' | wl-copy
notify-send "Bookmark copied!"
else
notify-send "Bookmark does not exist!" "$bookmark_with_tags"
fi
fi
else
echo "Unknown command!"
usage
fi