forked from bsmith89/quicknote
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib.sh
222 lines (185 loc) · 5.31 KB
/
lib.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
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
#!/usr/bin/env bash
# Library functions for quicknote
set -o errexit
# Config {{{1
# Environmental variables take precedence, but not if they're overriden in
# quicknote.cfg or $QN_USR_CFG
[ -z "$QN_USR_CFG" ] && export QN_USR_CFG=$HOME/.quicknote.cfg
[ -z "$QN_NOTE_DIR" ] && export QN_NOTE_DIR=$HOME/Documents/NOTES
[ -z "$QN_ADDON_DIR" ] && export QN_ADDON_DIR=$HOME/.quicknote.actions.d
[ -z "$QN_DEFAULT_ACTION" ] && export QN_DEFAULT_ACTION=list
[ -z "$QN_SORT" ] && export QN_SORT='sort -k2,3r'
[ -z "$QN_EXT" ] && export QN_EXT=md
[ -z "$QN_PATTERN" ] && export QN_PATTERN="XXXXXXXX.$QN_EXT"
# Default clipboard tool is defined for OSX
[ -z "$CLIPBOARD" ] && export CLIPBOARD=${CLIPBOARD-pbcopy}
# Find important paths
export QN_ACTION_DIR=$QN_DIR/actions
# Actions {{{1
# Echo the full path to an action if it exists, and is executible.
# Echo error msg and return non-zero exit-code if action does not exist.
get_action() {
if [ -x "$QN_ADDON_DIR/$1" ]; then
echo $QN_ADDON_DIR/$1
elif [ -x "$QN_ACTION_DIR/$1" ]; then
echo $QN_ACTION_DIR/$1
else
echo >&2 "'$1' does not appear to be an available action."
echo >&2 "Is it in '$QN_ADDON_DIR' and executible?"
echo >&2 $USAGE_MSG
return 1
fi
}
# Echo all of the available actions (full paths)
list_actions() {
local DIRS=$QN_ACTION_DIR
[ -d "$QN_ADDON_DIR" ] && DIRS="$DIRS $QN_ADDON_DIR"
for action in $(find $DIRS -mindepth 1); do
[ -x $action ] && echo $action
done
}
# Paths to Notes {{{1
# Given a complete reference (not prefix) to a note which may or may not exist,
# return the canonical path.
get_note() {
echo $QN_NOTE_DIR/${1%.${QN_EXT}}.${QN_EXT}
}
# Given one or more note references, echos all matching notes (full path).
find_all_notes() {
set -f
for prefix in "$@"; do
find $QN_NOTE_DIR -name ${prefix%.${QN_EXT}}*.${QN_EXT}
done
set +f
}
# Given a note reference, echo the full path to the note file.
find_note() {
ref=$1
candidates=$(find_all_notes $ref)
# $1, $2, etc. now equal each word in $candidates
set "$candidates"
if [ -z "$1" ]; then
echo >&2 "No files matching reference: '$ref'"
return 1
elif [ -z $2 ]; then
echo $1
else
echo >&2 "Multiple files matching reference: '$ref'"
echo >&2 $*
return 1
fi
}
# Make a new note file if it doesn't already exist, and echo the path
get_new_note() {
if ! [ -z $2 ]; then
echo >&2 "Too many arguments."
return 1
fi
if [ -z $1 ]; then
note=$(mktemp -p $QN_NOTE_DIR $QN_PATTERN)
echo $note
else
note=$(get_note $1)
touch $note
echo $note
fi
}
# Produces a full list of note files in the $QN_NOTE_DIR
# If arguments are given, lists only notes with filenames that can
# be found (recursively with find, so directories should work) in that list.
list_notes() {
set -f
if [ -z $1 ]; then
find $QN_NOTE_DIR -name "*.$QN_EXT"
else
find "$@" -name "*.$QN_EXT"
fi
set +f
}
# Testing Notes {{{1
# Confirm that note conforms to naming scheme.
note_valid_name() {
relpath=${1##$QN_NOTE_DIR/}
extension=${relpath##*.}
if ! [ $(basename $relpath) == $relpath ]; then # Note in a subdirectory
echo >&2 "$relpath is not in $QN_NOTE_DIR"
elif ! [ "$extension" == "$QN_EXT" ]; then
echo >&2 "'$extension' does not have extension $QN_EXT"
fi
}
# Confirm that note exists
note_exists() {
[ -f "$1" ]
return $?
}
# Check that note is usable
check_note() {
if note_valid_name $1 && note_exists $1 ; then
return 0
else
return 1
fi
}
# Parsing Notes {{{1
note_root() {
bn=$(basename $1)
echo ${bn/.$QN_EXT/}
}
# Echo the title of the note
note_title() {
awk 'NR==1' $1
}
# Echo the last modified time of the note (sortable)
note_date() {
stat -c '%y' $1 | cut -c 1-16
}
# Filtering Notes {{{1
# Echo all notes whose content (including title) match $pattern
list_matching() {
if [ -n "$*" ]; then
list_notes | xargs grep --ignore-case -l "$*"
else
list_notes
fi
}
# Echo empty (zero-byte) notes.
list_empty() {
find $(list_notes $*) -empty
}
# Summarizing Lists of Notes
# Echo notes and info.
# If given arguments (full paths), list only info for those notes.
list_infos_unsorted() {
if [ -z "$*" ]; then
local notes=$(list_notes)
else
local notes=$*
fi
for note in $notes; do
check_note $note
echo "$(note_root $note) $(note_date $note) $(note_title $note)"
done
}
# Echo notes and info; sorted with $QN_SORT
list_infos() {
list_infos_unsorted $* | $QN_SORT
}
# List info for all notes.
# If given an argument, only list info for matching notes.
# sorted with $QN_SORT
list_matching_infos() {
matching=$(list_matching $*)
if ! [ -n "$matching" ]; then
return 1
else
list_infos $(list_matching $*)
fi
}
# Export {{{1
export -f get_action list_actions \
get_note find_all_notes find_note \
get_new_note list_notes \
note_valid_name note_exists check_note \
note_root note_title note_date \
list_matching list_empty \
list_infos_unsorted list_infos list_matching_infos