cnote 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +12 -2
- data/lib/cnote/commands.rb +338 -0
- data/lib/cnote/note.rb +17 -10
- data/lib/cnote/notes.rb +84 -258
- data/lib/cnote/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0cb671825ee5bcf1fc02e9eca33033b055e45408
|
4
|
+
data.tar.gz: 4da2dfeffde9b4a6017ea93dede22d0c64ec5ed2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9446558c52207ddf1924df5bff975142c1f00612d73af7156b8e02b9d5306dac3442b092bdbea08afbc6063477b1bf60de6ca56bdc1715f80c32addb1244c4d
|
7
|
+
data.tar.gz: 96a3ea4196c6859a7bfd59c2e48e010646c19957b27e9ff2c491bc35baedf9325a96c540e42eea521d591024f895f49f570e4554e3869e2a43dbf4ec4e7706e7
|
data/README.md
CHANGED
@@ -5,12 +5,22 @@ CNote is my personal system for managing notes. I wanted something snappy and li
|
|
5
5
|
|
6
6
|
## Changelog
|
7
7
|
|
8
|
-
### 0.
|
8
|
+
### `0.3.0`
|
9
|
+
> Sept. 23rd, 2017
|
10
|
+
- Added `tags` command to view all tags used in your notes.
|
11
|
+
- Note numbers are now consistent from program start to program close. No more confusing indices relative to the last listing.
|
12
|
+
- Note numbers also no longer correspond to array indices, so deleting multiple notes shouldn't cause problems anymore.
|
13
|
+
- Expanded the `delete` command to take a comma separated list of notes to delete.
|
14
|
+
|
15
|
+
### `0.2.0`
|
9
16
|
- Added `config` command to adjust configuration within CNote. Try: `config set prompt >>>` or `config get editor`, or even just `config` to edit the file directly. Current config properties are `prompt`, `editor`, and `note_path`.
|
10
17
|
|
11
|
-
### 0.1.
|
18
|
+
### `0.1.1 - 0.1.3`
|
12
19
|
- Trial and error gem publishing-related fixes.
|
13
20
|
|
21
|
+
### `0.1.0`
|
22
|
+
- First release
|
23
|
+
|
14
24
|
## Installation
|
15
25
|
|
16
26
|
First of all, make sure you have a recent version of Ruby installed (including RubyGems). I'm using 2.4.0. Then run:
|
@@ -0,0 +1,338 @@
|
|
1
|
+
module Commands
|
2
|
+
#/================================\#
|
3
|
+
# The Commands #
|
4
|
+
#\================================/#
|
5
|
+
|
6
|
+
def search(term)
|
7
|
+
term = term.downcase.strip # Search is case insensitive
|
8
|
+
matches = @notes
|
9
|
+
|
10
|
+
if term.include? "+t"
|
11
|
+
term, tags = term.split("+t")
|
12
|
+
if tags
|
13
|
+
tags = tags.split(" ")
|
14
|
+
matches = matches.select do |num, note|
|
15
|
+
note != nil && has_tags(note, tags)
|
16
|
+
end
|
17
|
+
else
|
18
|
+
# +t but no tags - return all results that have at least one tag
|
19
|
+
matches = matches.select do |num, note|
|
20
|
+
note != nil && note.tags.length > 0
|
21
|
+
end
|
22
|
+
end
|
23
|
+
elsif term.include? "-t"
|
24
|
+
term, tags = term.split("-t")
|
25
|
+
if tags
|
26
|
+
tags = tags.split(" ")
|
27
|
+
matches = matches.select do |num, note|
|
28
|
+
note != nil && does_not_have_tags(note, tags)
|
29
|
+
end
|
30
|
+
else
|
31
|
+
# Likewise, return all results with no tags
|
32
|
+
matches = matches.select do |num, note|
|
33
|
+
note != nil && note.tags.length == 0
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
if term && term != ""
|
39
|
+
matches = matches.select do |num, note|
|
40
|
+
note.title.downcase.include?(term) || note.content.downcase.include?(term)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
set_filtered(matches)
|
45
|
+
|
46
|
+
# TODO: Sort by most relevant
|
47
|
+
# TODO: Highlight keywords where found
|
48
|
+
len = matches.length
|
49
|
+
|
50
|
+
print_list("Found #{len} Match#{"es" if len != 1}", @filtered)
|
51
|
+
end
|
52
|
+
|
53
|
+
def create(params)
|
54
|
+
if params.first
|
55
|
+
dirname = File.dirname(params.first)
|
56
|
+
new_filename = File.basename(params.first, File.extname(params.first)) + ".md"
|
57
|
+
rel_path = ""
|
58
|
+
tags = []
|
59
|
+
|
60
|
+
if params.include? "+t"
|
61
|
+
tags = params.slice(params.index("+t") + 1, params.length)
|
62
|
+
puts "CREATING WITH TAGS: #{tags}"
|
63
|
+
end
|
64
|
+
|
65
|
+
if dirname != "."
|
66
|
+
rel_path = dirname
|
67
|
+
.gsub(@config.note_path, "")
|
68
|
+
.gsub(File.basename(params.first), "")
|
69
|
+
end
|
70
|
+
|
71
|
+
full_path = File.join(@config.note_path, rel_path, new_filename)
|
72
|
+
|
73
|
+
if File.exists?(full_path)
|
74
|
+
if confirm("#{"Whoa!".bold.red} That file already exists. Overwrite it?")
|
75
|
+
File.delete(full_path)
|
76
|
+
@notes.each do |num, note|
|
77
|
+
if note.path == full_path
|
78
|
+
@notes[num] = nil
|
79
|
+
puts "Removed!"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
else
|
83
|
+
return
|
84
|
+
end
|
85
|
+
else
|
86
|
+
# Make sure the directory actually exists.
|
87
|
+
FileUtils.mkdir_p(File.join(@config.note_path, rel_path))
|
88
|
+
end
|
89
|
+
|
90
|
+
system "#{@config.editor} '#{full_path}'"
|
91
|
+
|
92
|
+
if File.exists?(full_path)
|
93
|
+
note = Note.new(full_path)
|
94
|
+
note.add_tags(tags) if tags.length > 0
|
95
|
+
note.created = Time.new
|
96
|
+
note.update
|
97
|
+
|
98
|
+
note.index = @index
|
99
|
+
@notes[@index] = note
|
100
|
+
@index += 1
|
101
|
+
|
102
|
+
set_filtered([note])
|
103
|
+
print_list("Created", @filtered)
|
104
|
+
else
|
105
|
+
puts "Scrapped the blank note..."
|
106
|
+
end
|
107
|
+
else
|
108
|
+
puts "Please enter a filename as the first parameter"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def open(params)
|
113
|
+
num = params.first.to_i
|
114
|
+
note = @notes[num]
|
115
|
+
|
116
|
+
if note
|
117
|
+
system "#{@config.editor} '#{note.path}'"
|
118
|
+
note.update
|
119
|
+
else
|
120
|
+
puts "Hey! There is no note #{num}! Nice try."
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def delete(params)
|
125
|
+
notes = multi_note(params)
|
126
|
+
|
127
|
+
notes.each do |note|
|
128
|
+
if note and File.exists? note.path
|
129
|
+
num = note.index
|
130
|
+
if confirm("You're #{'sure'.italic} you want to delete note #{num.to_s.bold.white} with title #{note.title.bold.white}?")
|
131
|
+
FileUtils.rm(note.path)
|
132
|
+
@notes[num] = nil
|
133
|
+
@filtered[num] = nil
|
134
|
+
puts "Deleted!"
|
135
|
+
else
|
136
|
+
puts "Whew! That was close."
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def peek(params)
|
143
|
+
if params&.first&.downcase == 'config'
|
144
|
+
return @config.print
|
145
|
+
end
|
146
|
+
|
147
|
+
note = @notes[params.first.to_i]
|
148
|
+
if note
|
149
|
+
lines = note.content.lines
|
150
|
+
puts
|
151
|
+
puts "-" * 40
|
152
|
+
puts note.title.bold.white
|
153
|
+
puts lines.slice(0, 15)
|
154
|
+
if lines.length > 15
|
155
|
+
puts
|
156
|
+
puts "(#{lines.length - 15} more line#{'s' if lines.length != 16}...)".italic
|
157
|
+
end
|
158
|
+
puts "-" * 40
|
159
|
+
puts
|
160
|
+
else
|
161
|
+
puts "Note doesn't exist!"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def tag(params)
|
166
|
+
notes = multi_note(params)
|
167
|
+
|
168
|
+
notes.each do |note|
|
169
|
+
tags = params.slice(1, params.length)
|
170
|
+
note.add_tags(tags)
|
171
|
+
end
|
172
|
+
|
173
|
+
set_filtered(notes)
|
174
|
+
print_list("Changed", @filtered)
|
175
|
+
|
176
|
+
puts "Added #{params.length - 1} tag#{"s" if params.length != 2} to #{notes.length} note#{"s" if notes.length != 1}."
|
177
|
+
end
|
178
|
+
|
179
|
+
def untag(params)
|
180
|
+
notes = multi_note(params)
|
181
|
+
|
182
|
+
notes.each do |note|
|
183
|
+
tags = params.slice(1, params.length)
|
184
|
+
note.remove_tags(tags)
|
185
|
+
end
|
186
|
+
|
187
|
+
set_filtered(notes)
|
188
|
+
print_list("Changed", @filtered)
|
189
|
+
|
190
|
+
puts "Removed #{params.length - 1} tag#{"s" if params.length != 2} from #{notes.length} note#{"s" if notes.length != 1}."
|
191
|
+
end
|
192
|
+
|
193
|
+
def tags(params)
|
194
|
+
if params.empty?
|
195
|
+
list_tags
|
196
|
+
else
|
197
|
+
puts "NOT YET IMPLEMENTED"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def list_tags
|
202
|
+
tags = Hash.new(0)
|
203
|
+
longest = 0
|
204
|
+
sorted = []
|
205
|
+
|
206
|
+
@notes.each do |num, note|
|
207
|
+
note.tags.each do |tag|
|
208
|
+
tags[tag] += 1;
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
tags.each do |tag, count|
|
213
|
+
longest = tag.length if tag.length > longest
|
214
|
+
sorted << [tag, count]
|
215
|
+
end
|
216
|
+
|
217
|
+
# Sort alphabetically
|
218
|
+
sorted.sort_by! { |item| item[0] }
|
219
|
+
|
220
|
+
puts
|
221
|
+
puts "#{indent}All Tags".bold
|
222
|
+
puts "#{indent}--------"
|
223
|
+
puts
|
224
|
+
sorted.each do |entry|
|
225
|
+
tag, count = entry
|
226
|
+
puts "#{indent}#{tag.bold} #{"." * (longest + 3 - tag.length)} #{count} notes"
|
227
|
+
end
|
228
|
+
puts
|
229
|
+
end
|
230
|
+
|
231
|
+
def info(params)
|
232
|
+
# Shows metadata about a note or list of notes.
|
233
|
+
notes = multi_note(params)
|
234
|
+
set_filtered(notes)
|
235
|
+
print_list("Note Info", @filtered, true)
|
236
|
+
puts "Printed info for #{notes.length} notes."
|
237
|
+
end
|
238
|
+
|
239
|
+
def config(params = [])
|
240
|
+
if params.length == 0
|
241
|
+
system "#{@config.editor} #{@config.path}"
|
242
|
+
@config.load
|
243
|
+
return
|
244
|
+
end
|
245
|
+
|
246
|
+
action, key, *value = params
|
247
|
+
value = value.join(" ")
|
248
|
+
|
249
|
+
if action == "get"
|
250
|
+
if key
|
251
|
+
puts "#{key}: \"#{@config.get(key)}\""
|
252
|
+
else
|
253
|
+
@config.print
|
254
|
+
end
|
255
|
+
elsif action == "set"
|
256
|
+
if key
|
257
|
+
if value
|
258
|
+
puts "Config: #{key} changed from '#{@config.get(key)}' to '#{value}'"
|
259
|
+
@config.set(key, value)
|
260
|
+
else
|
261
|
+
puts "Can't set a key to a value if no value is given."
|
262
|
+
end
|
263
|
+
else
|
264
|
+
puts "Can't set a key if one wasn't given."
|
265
|
+
end
|
266
|
+
else
|
267
|
+
puts "Invalid action: #{action}"
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def help
|
272
|
+
puts
|
273
|
+
puts "Enter a command with the structure:"
|
274
|
+
puts " #{@config.prompt} action parameter(s)"
|
275
|
+
puts
|
276
|
+
puts "Actions:"
|
277
|
+
puts " - #{"new".bold.white} #{"filename".italic}"
|
278
|
+
puts " Create a new note.".italic
|
279
|
+
puts
|
280
|
+
puts " - #{"edit".bold.white} #{"note_number".italic}"
|
281
|
+
puts " Open a note for editing or reading.".italic
|
282
|
+
puts
|
283
|
+
puts " - #{"delete".bold.white} #{"note_number".italic}"
|
284
|
+
puts " Delete a note.".italic
|
285
|
+
puts
|
286
|
+
puts " - #{"peek".bold.white} #{"note_number".italic}"
|
287
|
+
puts " Print the first few lines of a note.".italic
|
288
|
+
puts
|
289
|
+
puts " - #{"tag".bold.white} #{"note_number".italic} #{"tag".italic} #{"tag".italic} #{"tag".italic} ..."
|
290
|
+
puts " Add the space-delimited list of tags to a given note.".italic
|
291
|
+
puts
|
292
|
+
puts " - #{"untag".bold.white} #{"note_number".italic} #{"tag".italic} #{"tag".italic} ..."
|
293
|
+
puts " Remove the space-delimited list of tags from a given note.".italic
|
294
|
+
puts
|
295
|
+
puts " - #{"tags".bold.white}"
|
296
|
+
puts " List all tags and the number of notes each one is applied to.".italic
|
297
|
+
puts
|
298
|
+
puts " - #{"search".bold.white} #{"search_term".italic} ( +t/-t #{"tag".italic} #{"tag".italic} ... )"
|
299
|
+
puts " Find notes that match the search term, or the specified tags.".italic
|
300
|
+
puts
|
301
|
+
puts " - #{"info".bold.white} #{"note_number(s)".italic}"
|
302
|
+
puts " Display detailed metadata for one or more (comma-delimited) note numbers.".italic
|
303
|
+
puts
|
304
|
+
puts " - #{"list".bold.white}"
|
305
|
+
puts " List every single note in your notes folder.".italic
|
306
|
+
puts
|
307
|
+
puts " - #{"config".bold.white} #{"(set/get)".italic} #{"key".italic} [#{"value".italic}]"
|
308
|
+
puts " Manage your CNote configuration, either by setting keys through commands,".italic
|
309
|
+
puts " or by just writing 'config' to open the file in your editor.".italic
|
310
|
+
puts
|
311
|
+
puts " - #{"exit".bold.white}"
|
312
|
+
puts " Leave CNote.".italic
|
313
|
+
puts
|
314
|
+
puts " - #{"help".bold.white}"
|
315
|
+
puts " You are here!".italic
|
316
|
+
puts
|
317
|
+
puts "Alternate actions:"
|
318
|
+
puts " Most actions also have aliases that do the same thing."
|
319
|
+
puts " These are listed for each command:"
|
320
|
+
puts " - new: create, c, n"
|
321
|
+
puts " - edit: e, open, o"
|
322
|
+
puts " - delete: d, rm"
|
323
|
+
puts " - peek: p"
|
324
|
+
puts " - tag: t"
|
325
|
+
puts " - untag: ut"
|
326
|
+
puts " - search: find, f, s"
|
327
|
+
puts " - info: i"
|
328
|
+
puts " - list: l, ls"
|
329
|
+
puts " - exit: quit, q, close"
|
330
|
+
puts " - help: h"
|
331
|
+
puts
|
332
|
+
end
|
333
|
+
|
334
|
+
def list
|
335
|
+
set_filtered(@notes)
|
336
|
+
print_list("All Notes", @filtered)
|
337
|
+
end
|
338
|
+
end
|
data/lib/cnote/note.rb
CHANGED
@@ -6,14 +6,12 @@ class Note
|
|
6
6
|
:tags,
|
7
7
|
:filename,
|
8
8
|
:path,
|
9
|
-
:modified
|
10
|
-
|
9
|
+
:modified
|
10
|
+
attr_accessor :index, :created
|
11
11
|
|
12
|
-
|
12
|
+
@@meta_regex = /^<!\-{3}(.*)\-{2}>/
|
13
13
|
|
14
14
|
def initialize(path)
|
15
|
-
@meta_regex = /^<!\-{3}(.*)\-{2}>/
|
16
|
-
|
17
15
|
@content = ""
|
18
16
|
@tags = []
|
19
17
|
@filename = File.basename(path)
|
@@ -35,16 +33,17 @@ class Note
|
|
35
33
|
|
36
34
|
contents.each_line do |line|
|
37
35
|
line = line.strip
|
38
|
-
if
|
36
|
+
if @@meta_regex =~ line
|
39
37
|
parse_meta($~[1])
|
40
|
-
elsif !@title
|
41
|
-
|
42
|
-
@title = line.gsub(/#|[^a-z0-9\s\.\-]/i, "").strip
|
43
|
-
end
|
38
|
+
elsif !@title && line[0] == '#'
|
39
|
+
@title = line.gsub(/#|[^a-z0-9\s\.\-]/i, "").strip
|
44
40
|
else
|
45
41
|
@content << line + "\n"
|
46
42
|
end
|
47
43
|
end
|
44
|
+
|
45
|
+
# If no Markdown header is found, name it by the file's name.
|
46
|
+
@title = File.basename(@filename, File.extname(@filename)) if !@title
|
48
47
|
end
|
49
48
|
|
50
49
|
def add_tags(tags)
|
@@ -59,6 +58,14 @@ class Note
|
|
59
58
|
write_meta
|
60
59
|
end
|
61
60
|
|
61
|
+
def title_limit(length)
|
62
|
+
if @title.length >= length
|
63
|
+
@title.strip.slice(0, length - 3) + "..."
|
64
|
+
else
|
65
|
+
@title
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
62
69
|
def excerpt
|
63
70
|
@content.gsub(/[#*\-~]/i, "").strip.slice(0, 80)
|
64
71
|
end
|
data/lib/cnote/notes.rb
CHANGED
@@ -2,13 +2,33 @@ require "colorize"
|
|
2
2
|
require "fileutils"
|
3
3
|
require "time"
|
4
4
|
require "ap"
|
5
|
+
require "cnote/commands"
|
5
6
|
require "cnote/note"
|
6
7
|
|
7
8
|
class Notes
|
9
|
+
include Commands
|
10
|
+
|
8
11
|
def initialize(config)
|
9
12
|
@config = config
|
10
|
-
@
|
11
|
-
@
|
13
|
+
@index = 1
|
14
|
+
@notes = Hash.new
|
15
|
+
|
16
|
+
notes = Dir[File.join(@config.note_path, "**/*")].select do |f|
|
17
|
+
[".txt", ".md"].include?(File.extname(f))
|
18
|
+
end
|
19
|
+
|
20
|
+
notes.each do |path|
|
21
|
+
note = Note.new(path)
|
22
|
+
note.index = @index
|
23
|
+
|
24
|
+
@notes[@index] = note
|
25
|
+
|
26
|
+
@index += 1
|
27
|
+
end
|
28
|
+
|
29
|
+
@indent = notes.length.to_s.length + 2
|
30
|
+
|
31
|
+
set_filtered(@notes)
|
12
32
|
end
|
13
33
|
|
14
34
|
#/================================\#
|
@@ -37,12 +57,16 @@ class Notes
|
|
37
57
|
peek(params)
|
38
58
|
when "tag", "t"
|
39
59
|
tag(params)
|
60
|
+
when "tags"
|
61
|
+
tags(params)
|
40
62
|
when "untag", "ut"
|
41
63
|
untag(params)
|
42
64
|
when "search", "find", "s", "f"
|
43
65
|
search(params.join(" "))
|
44
66
|
when "list", "l", "ls"
|
45
67
|
list
|
68
|
+
when "info", "i"
|
69
|
+
info(params)
|
46
70
|
when "help", "h"
|
47
71
|
help
|
48
72
|
when "config", "conf"
|
@@ -58,288 +82,88 @@ class Notes
|
|
58
82
|
end
|
59
83
|
|
60
84
|
#/================================\#
|
61
|
-
#
|
85
|
+
# Utilities #
|
62
86
|
#\================================/#
|
63
87
|
|
64
|
-
def
|
65
|
-
|
66
|
-
matches = @notes
|
67
|
-
|
68
|
-
if term.include? "+t "
|
69
|
-
term, tags = term.split("+t ")
|
70
|
-
tags = tags.split(" ")
|
71
|
-
puts "\n Searching: '#{term.strip}' with tags: #{tags}"
|
72
|
-
matches = matches.select do |note|
|
73
|
-
has_all_tags(note, tags)
|
74
|
-
end
|
75
|
-
elsif term.include? "-t "
|
76
|
-
term, tags = term.split("-t ")
|
77
|
-
tags = tags.split(" ")
|
78
|
-
puts "\n Searching: '#{term.strip}' without tags: #{tags}"
|
79
|
-
matches = matches.select do |note|
|
80
|
-
has_none_tags(note, tags)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
term.strip!
|
85
|
-
|
86
|
-
@filtered = matches.select do |note|
|
87
|
-
note.title.downcase.include?(term) || note.content.downcase.include?(term)
|
88
|
-
end
|
89
|
-
|
90
|
-
# TODO: Sort by most relevant
|
91
|
-
# TODO: Highlight keywords where found
|
92
|
-
len = @filtered.length
|
93
|
-
|
94
|
-
print_list("Found #{len} Match#{"es" if len != 1}", @filtered)
|
88
|
+
private def indent
|
89
|
+
" " * @indent
|
95
90
|
end
|
96
91
|
|
97
|
-
def
|
98
|
-
|
99
|
-
dirname = File.dirname(params.first)
|
100
|
-
new_filename = File.basename(params.first, File.extname(params.first)) + ".md"
|
101
|
-
rel_path = ""
|
102
|
-
tags = []
|
103
|
-
|
104
|
-
if params.include? "+t"
|
105
|
-
tags = params.slice(params.index("+t") + 1, params.length)
|
106
|
-
puts "CREATING WITH TAGS: #{tags}"
|
107
|
-
end
|
108
|
-
|
109
|
-
if dirname != "."
|
110
|
-
rel_path = dirname
|
111
|
-
.gsub(@config.note_path, "")
|
112
|
-
.gsub(File.basename(params.first), "")
|
113
|
-
end
|
92
|
+
private def set_filtered(notes)
|
93
|
+
@filtered = Hash.new
|
114
94
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
File.delete(full_path)
|
120
|
-
@notes.each do |note|
|
121
|
-
if note.path == full_path
|
122
|
-
@notes.delete(note)
|
123
|
-
puts "Removed!"
|
124
|
-
end
|
125
|
-
end
|
126
|
-
else
|
127
|
-
return
|
128
|
-
end
|
129
|
-
else
|
130
|
-
# Make sure the directory actually exists.
|
131
|
-
FileUtils.mkdir_p(File.join(@config.note_path, rel_path))
|
95
|
+
case notes.class.to_s
|
96
|
+
when "Array"
|
97
|
+
notes.each do |note|
|
98
|
+
@filtered[note.index] = note
|
132
99
|
end
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
if File.exists?(full_path)
|
137
|
-
note = Note.new(full_path)
|
138
|
-
note.add_tags(tags) if tags.length > 0
|
139
|
-
note.created = Time.new
|
140
|
-
note.update
|
141
|
-
|
142
|
-
@notes << Note.new(full_path)
|
143
|
-
|
144
|
-
print_list("Created", [note])
|
145
|
-
@filtered = [note]
|
146
|
-
else
|
147
|
-
puts "Scrapped the blank note..."
|
100
|
+
when "Hash"
|
101
|
+
notes.each do |num, note|
|
102
|
+
@filtered[num] = note
|
148
103
|
end
|
149
104
|
else
|
150
|
-
puts "
|
105
|
+
puts "Unrecognized notes format for set_filtered. Got #{notes.class}!"
|
151
106
|
end
|
107
|
+
|
108
|
+
@filtered
|
152
109
|
end
|
153
110
|
|
154
|
-
def
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
if note
|
159
|
-
system "#{@config.editor} '#{note.path}'"
|
160
|
-
note.update
|
161
|
-
else
|
162
|
-
puts "Hey! There is no note #{num}! Nice try."
|
163
|
-
end
|
164
|
-
end
|
111
|
+
private def print_list(title, notes, verbose = false)
|
112
|
+
path_length = @config.note_path.split("/").length
|
113
|
+
count = 0;
|
165
114
|
|
166
|
-
|
167
|
-
|
168
|
-
|
115
|
+
puts
|
116
|
+
puts "#{indent}#{title}".bold
|
117
|
+
puts "#{indent}#{"-" * title.length}"
|
118
|
+
puts
|
169
119
|
|
170
|
-
if
|
171
|
-
|
172
|
-
|
173
|
-
@notes.delete(note)
|
174
|
-
@filtered.delete(note)
|
175
|
-
puts "Deleted!"
|
176
|
-
else
|
177
|
-
puts "Whew! That was close."
|
178
|
-
end
|
179
|
-
else
|
180
|
-
puts "Looks like my job is done here, since note #{num} doesn't exist anyway!"
|
181
|
-
end
|
182
|
-
end
|
120
|
+
if verbose
|
121
|
+
notes.each do |num, note|
|
122
|
+
count += 1
|
183
123
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
124
|
+
if !note
|
125
|
+
puts "#{num}.".ljust(@indent) + " DELETED".italic
|
126
|
+
next
|
127
|
+
end
|
188
128
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
129
|
+
puts "#{num}.".ljust(4) + note.title_limit(70).bold
|
130
|
+
puts "#{indent}#{note.path.gsub(@config.note_path, "")}".italic.light_magenta
|
131
|
+
if note.tags.length > 0
|
132
|
+
tags = note.tags.map { |tag| tag.yellow }
|
133
|
+
puts "#{indent}tags: " + "[#{tags.join('] [')}]"
|
134
|
+
else
|
135
|
+
puts "#{indent}<no tags>"
|
136
|
+
end
|
137
|
+
puts "#{indent}modified: " + note.modified.strftime("%a, %b %e %Y, %l:%M%P").italic
|
138
|
+
puts "#{indent}created: " + note.created.strftime("%a, %b %e %Y, %l:%M%P").italic
|
197
139
|
puts
|
198
|
-
puts "(#{lines.length - 15} more line#{'s' if lines.length != 16}...)".italic
|
199
140
|
end
|
200
|
-
puts "-" * 40
|
201
|
-
puts
|
202
141
|
else
|
203
|
-
|
204
|
-
|
205
|
-
end
|
206
|
-
|
207
|
-
def tag(params)
|
208
|
-
notes = multi_note(params)
|
209
|
-
|
210
|
-
notes.each do |note|
|
211
|
-
tags = params.slice(1, params.length)
|
212
|
-
note.add_tags(tags)
|
213
|
-
end
|
214
|
-
|
215
|
-
print_list("Changed", notes)
|
216
|
-
|
217
|
-
@filtered = notes
|
218
|
-
|
219
|
-
puts "Added #{params.length - 1} tag#{"s" if params.length != 2} to #{notes.length} note#{"s" if notes.length != 1}."
|
220
|
-
end
|
221
|
-
|
222
|
-
def untag(params)
|
223
|
-
notes = multi_note(params)
|
224
|
-
|
225
|
-
notes.each do |note|
|
226
|
-
tags = params.slice(1, params.length)
|
227
|
-
note.remove_tags(tags)
|
228
|
-
end
|
229
|
-
|
230
|
-
print_list("Changed", notes)
|
231
|
-
|
232
|
-
@filtered = notes
|
233
|
-
|
234
|
-
puts "Removed #{params.length - 1} tag#{"s" if params.length != 2} from #{notes.length} note#{"s" if notes.length != 1}."
|
235
|
-
end
|
236
|
-
|
237
|
-
def config(params = [])
|
238
|
-
if params.length == 0
|
239
|
-
system "#{@config.editor} #{@config.path}"
|
240
|
-
@config.load
|
241
|
-
return
|
242
|
-
end
|
142
|
+
notes.each do |num, note|
|
143
|
+
count += 1
|
243
144
|
|
244
|
-
|
245
|
-
|
145
|
+
if !note
|
146
|
+
puts "#{num}.".ljust(@indent) + "DELETED".colorize(color: :white, background: :red).italic
|
147
|
+
next
|
148
|
+
end
|
246
149
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
@config.print
|
252
|
-
end
|
253
|
-
elsif action == "set"
|
254
|
-
if key
|
255
|
-
if value
|
256
|
-
puts "Config: #{key} changed from '#{@config.get(key)}' to '#{value}'"
|
257
|
-
@config.set(key, value)
|
258
|
-
else
|
259
|
-
puts "Can't set a key to a value if no value is given."
|
150
|
+
print "#{num}.".ljust(@indent) + note.title_limit(70).bold
|
151
|
+
if note.tags.length > 0
|
152
|
+
tags = note.tags.map { |tag| tag.yellow }
|
153
|
+
print " [#{tags.join('] [')}]"
|
260
154
|
end
|
261
|
-
|
262
|
-
puts "Can't set a key if one wasn't given."
|
155
|
+
print "\n"
|
263
156
|
end
|
264
|
-
else
|
265
|
-
puts "Invalid action: #{action}"
|
266
157
|
end
|
267
|
-
|
268
|
-
|
269
|
-
def help
|
270
|
-
puts
|
271
|
-
puts "Enter a command with the structure:"
|
272
|
-
puts " #{@config.prompt} action parameter(s)"
|
273
|
-
puts
|
274
|
-
puts "Actions:"
|
275
|
-
puts " - #{"new".bold.white} #{"filename".italic}"
|
276
|
-
puts " - #{"edit".bold.white} #{"note_number".italic}"
|
277
|
-
puts " - #{"delete".bold.white} #{"note_number".italic}"
|
278
|
-
puts " - #{"peek".bold.white} #{"note_number".italic}"
|
279
|
-
puts " - #{"tag".bold.white} #{"note_number".italic}"
|
280
|
-
puts " - #{"untag".bold.white} #{"note_number".italic}"
|
281
|
-
puts " - #{"search".bold.white} #{"search_term".italic}"
|
282
|
-
puts " - #{"list".bold.white}"
|
283
|
-
puts " - #{"config".bold.white} #{"(set/get)".italic} #{"key".italic} [#{"value".italic}]"
|
284
|
-
puts " - #{"exit".bold.white}"
|
285
|
-
puts " - #{"help".bold.white}"
|
286
|
-
puts
|
287
|
-
puts "Alternate actions:"
|
288
|
-
puts " Most actions also have aliases that do the same thing."
|
289
|
-
puts " These are listed for each command:"
|
290
|
-
puts " - new: create, c, n"
|
291
|
-
puts " - edit: e, open, o"
|
292
|
-
puts " - delete: d, rm"
|
293
|
-
puts " - peek: p"
|
294
|
-
puts " - tag: t"
|
295
|
-
puts " - untag: ut"
|
296
|
-
puts " - search: find, f, s"
|
297
|
-
puts " - list: l, ls"
|
298
|
-
puts " - exit: quit, q, close"
|
299
|
-
puts " - help: h"
|
300
|
-
puts
|
301
|
-
end
|
302
|
-
|
303
|
-
def list
|
304
|
-
@filtered = recently_edited_first(@notes)
|
305
|
-
print_list("All Notes", @filtered)
|
306
|
-
end
|
307
|
-
|
308
|
-
#/================================\#
|
309
|
-
# Utilities #
|
310
|
-
#\================================/#
|
311
|
-
|
312
|
-
private def print_list(title, notes)
|
313
|
-
path_length = @config.note_path.split("/").length
|
314
|
-
i = 0
|
315
|
-
|
316
|
-
puts
|
317
|
-
puts " #{title}".bold
|
318
|
-
puts " #{"-" * title.length}"
|
158
|
+
|
319
159
|
puts
|
320
|
-
|
321
|
-
notes.each do |note|
|
322
|
-
i += 1
|
323
|
-
puts "#{i}.".ljust(4) + note.title.bold
|
324
|
-
puts " #{note.path.gsub(@config.note_path, "")}".italic.light_magenta
|
325
|
-
if note.tags.length > 0
|
326
|
-
tags = note.tags.map { |tag| tag.yellow }
|
327
|
-
puts " tags: " + "[#{tags.join('] [')}]"
|
328
|
-
else
|
329
|
-
puts " <no tags>"
|
330
|
-
end
|
331
|
-
puts " modified: " + note.modified.strftime("%a, %b %e %Y, %l:%M%P").italic
|
332
|
-
puts " created: " + note.created.strftime("%a, %b %e %Y, %l:%M%P").italic
|
333
|
-
puts
|
334
|
-
end
|
335
|
-
|
336
|
-
puts " Listed #{i.to_s.bold} Notes"
|
160
|
+
puts "#{indent}Listed #{count.to_s.bold} Notes"
|
337
161
|
puts
|
338
162
|
end
|
339
163
|
|
340
164
|
private def confirm(message = "Confirm")
|
341
165
|
print "#{message} [y/n]: "
|
342
|
-
case gets
|
166
|
+
case gets&.chomp&.strip&.downcase
|
343
167
|
when "y", "yes", "yeah", "sure", "yep", "okay", "aye"
|
344
168
|
return true
|
345
169
|
when "n", "no", "nope", "nay"
|
@@ -353,7 +177,7 @@ class Notes
|
|
353
177
|
notes = []
|
354
178
|
|
355
179
|
params.first.split(",").each do |num|
|
356
|
-
note = @
|
180
|
+
note = @notes[num.to_i]
|
357
181
|
if note
|
358
182
|
notes << note
|
359
183
|
else
|
@@ -365,10 +189,12 @@ class Notes
|
|
365
189
|
end
|
366
190
|
|
367
191
|
private def recently_edited_first(notes)
|
192
|
+
ap notes
|
193
|
+
|
368
194
|
notes.sort_by { |note| note.modified }.reverse
|
369
195
|
end
|
370
196
|
|
371
|
-
private def
|
197
|
+
private def has_tags(note, tags)
|
372
198
|
has = true
|
373
199
|
note_tags = note.tags
|
374
200
|
tags.each do |tag|
|
@@ -380,7 +206,7 @@ class Notes
|
|
380
206
|
has
|
381
207
|
end
|
382
208
|
|
383
|
-
private def
|
209
|
+
private def does_not_have_tags(note, tags)
|
384
210
|
doesnt_have = true
|
385
211
|
note_tags = note.tags
|
386
212
|
tags.each do |tag|
|
data/lib/cnote/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cnote
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony McCoy
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -103,6 +103,7 @@ files:
|
|
103
103
|
- cnote.gemspec
|
104
104
|
- exe/cnote
|
105
105
|
- lib/cnote.rb
|
106
|
+
- lib/cnote/commands.rb
|
106
107
|
- lib/cnote/config.rb
|
107
108
|
- lib/cnote/note.rb
|
108
109
|
- lib/cnote/notes.rb
|