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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4b85c6a02284c2120ce8daaf4582f3bcba9b54bc
4
- data.tar.gz: 7b0c3e88353e7f46e295f6232253eb98d0b6008a
3
+ metadata.gz: 0cb671825ee5bcf1fc02e9eca33033b055e45408
4
+ data.tar.gz: 4da2dfeffde9b4a6017ea93dede22d0c64ec5ed2
5
5
  SHA512:
6
- metadata.gz: 98bda843720a6789a57e1c0d075f4e29e9aace16f8ea97a0572999f58ad0db28d52f6bf110cec241bd629d13f367b31a1049b7c6c7e42f57a28bd5f097c8ec5f
7
- data.tar.gz: f3eea2df867c25f9414ad2dbd7ac7f8a4d40ed5bba9aa2251e914092eb25d89b0110ce51659cd4d8983b001dcf9dd53eed12c6defcca25f03d820577814b37f3
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.2.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.3 and lower
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
- :created
9
+ :modified
10
+ attr_accessor :index, :created
11
11
 
12
- attr_writer :created
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 @meta_regex =~ line
36
+ if @@meta_regex =~ line
39
37
  parse_meta($~[1])
40
- elsif !@title
41
- if line != ""
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
- @notes = Dir[File.join(@config.note_path, "**/*.md")].map { |f| Note.new(f) }
11
- @filtered = @notes
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
- # The Commands #
85
+ # Utilities #
62
86
  #\================================/#
63
87
 
64
- def search(term)
65
- term = term.downcase # Search is case insensitive
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 create(params)
98
- if params.first
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
- full_path = File.join(@config.note_path, rel_path, new_filename)
116
-
117
- if File.exists?(full_path)
118
- if confirm("#{"Whoa!".bold.red} That file already exists. Overwrite it?")
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
- system "#{@config.editor} '#{full_path}'"
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 "Please enter a filename as the first parameter"
105
+ puts "Unrecognized notes format for set_filtered. Got #{notes.class}!"
151
106
  end
107
+
108
+ @filtered
152
109
  end
153
110
 
154
- def open(params)
155
- num = params.first.to_i
156
- note = @filtered[num - 1]
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
- def delete(params)
167
- num = params.first.to_i
168
- note = @filtered[num - 1]
115
+ puts
116
+ puts "#{indent}#{title}".bold
117
+ puts "#{indent}#{"-" * title.length}"
118
+ puts
169
119
 
170
- if note and File.exists? note.path
171
- if confirm("You're #{'sure'.italic} you want to delete note #{num.to_s.bold.white} with title #{note.title.bold.white}?")
172
- FileUtils.rm(note.path)
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
- def peek(params)
185
- if params&.first&.downcase == 'config'
186
- return @config.print
187
- end
124
+ if !note
125
+ puts "#{num}.".ljust(@indent) + " DELETED".italic
126
+ next
127
+ end
188
128
 
189
- note = @filtered[params.first.to_i - 1]
190
- if note
191
- lines = note.content.lines
192
- puts
193
- puts "-" * 40
194
- puts note.title.bold.white
195
- puts lines.slice(0, 15)
196
- if lines.length > 15
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
- puts "Note doesn't exist!"
204
- end
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
- action, key, *value = params
245
- value = value.join(" ")
145
+ if !note
146
+ puts "#{num}.".ljust(@indent) + "DELETED".colorize(color: :white, background: :red).italic
147
+ next
148
+ end
246
149
 
247
- if action == "get"
248
- if key
249
- puts "#{key}: \"#{@config.get(key)}\""
250
- else
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
- else
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
- end
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.chomp.strip.downcase
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 = @filtered[num.to_i - 1]
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 has_all_tags(note, tags)
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 has_none_tags(note, tags)
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
@@ -1,3 +1,3 @@
1
1
  module Cnote
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
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.2.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-18 00:00:00.000000000 Z
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