lib/cnote/notes.rb in cnote-0.2.0 vs lib/cnote/notes.rb in cnote-0.3.0
- old
+ new
@@ -1,16 +1,36 @@
require "colorize"
require "fileutils"
require "time"
require "ap"
+require "cnote/commands"
require "cnote/note"
class Notes
+ include Commands
+
def initialize(config)
@config = config
- @notes = Dir[File.join(@config.note_path, "**/*.md")].map { |f| Note.new(f) }
- @filtered = @notes
+ @index = 1
+ @notes = Hash.new
+
+ notes = Dir[File.join(@config.note_path, "**/*")].select do |f|
+ [".txt", ".md"].include?(File.extname(f))
+ end
+
+ notes.each do |path|
+ note = Note.new(path)
+ note.index = @index
+
+ @notes[@index] = note
+
+ @index += 1
+ end
+
+ @indent = notes.length.to_s.length + 2
+
+ set_filtered(@notes)
end
#/================================\#
# REPL type thing #
#\================================/#
@@ -35,16 +55,20 @@
delete(params)
when "peek", "p"
peek(params)
when "tag", "t"
tag(params)
+ when "tags"
+ tags(params)
when "untag", "ut"
untag(params)
when "search", "find", "s", "f"
search(params.join(" "))
when "list", "l", "ls"
list
+ when "info", "i"
+ info(params)
when "help", "h"
help
when "config", "conf"
config(params)
when "quit", "exit", "close", "q"
@@ -56,292 +80,92 @@
await_command # Drop back to REPL
end
#/================================\#
- # The Commands #
+ # Utilities #
#\================================/#
- def search(term)
- term = term.downcase # Search is case insensitive
- matches = @notes
-
- if term.include? "+t "
- term, tags = term.split("+t ")
- tags = tags.split(" ")
- puts "\n Searching: '#{term.strip}' with tags: #{tags}"
- matches = matches.select do |note|
- has_all_tags(note, tags)
- end
- elsif term.include? "-t "
- term, tags = term.split("-t ")
- tags = tags.split(" ")
- puts "\n Searching: '#{term.strip}' without tags: #{tags}"
- matches = matches.select do |note|
- has_none_tags(note, tags)
- end
- end
-
- term.strip!
-
- @filtered = matches.select do |note|
- note.title.downcase.include?(term) || note.content.downcase.include?(term)
- end
-
- # TODO: Sort by most relevant
- # TODO: Highlight keywords where found
- len = @filtered.length
-
- print_list("Found #{len} Match#{"es" if len != 1}", @filtered)
+ private def indent
+ " " * @indent
end
- def create(params)
- if params.first
- dirname = File.dirname(params.first)
- new_filename = File.basename(params.first, File.extname(params.first)) + ".md"
- rel_path = ""
- tags = []
+ private def set_filtered(notes)
+ @filtered = Hash.new
- if params.include? "+t"
- tags = params.slice(params.index("+t") + 1, params.length)
- puts "CREATING WITH TAGS: #{tags}"
+ case notes.class.to_s
+ when "Array"
+ notes.each do |note|
+ @filtered[note.index] = note
end
-
- if dirname != "."
- rel_path = dirname
- .gsub(@config.note_path, "")
- .gsub(File.basename(params.first), "")
+ when "Hash"
+ notes.each do |num, note|
+ @filtered[num] = note
end
-
- full_path = File.join(@config.note_path, rel_path, new_filename)
-
- if File.exists?(full_path)
- if confirm("#{"Whoa!".bold.red} That file already exists. Overwrite it?")
- File.delete(full_path)
- @notes.each do |note|
- if note.path == full_path
- @notes.delete(note)
- puts "Removed!"
- end
- end
- else
- return
- end
- else
- # Make sure the directory actually exists.
- FileUtils.mkdir_p(File.join(@config.note_path, rel_path))
- end
-
- system "#{@config.editor} '#{full_path}'"
-
- if File.exists?(full_path)
- note = Note.new(full_path)
- note.add_tags(tags) if tags.length > 0
- note.created = Time.new
- note.update
-
- @notes << Note.new(full_path)
-
- print_list("Created", [note])
- @filtered = [note]
- else
- puts "Scrapped the blank note..."
- end
else
- puts "Please enter a filename as the first parameter"
+ puts "Unrecognized notes format for set_filtered. Got #{notes.class}!"
end
+
+ @filtered
end
- def open(params)
- num = params.first.to_i
- note = @filtered[num - 1]
+ private def print_list(title, notes, verbose = false)
+ path_length = @config.note_path.split("/").length
+ count = 0;
- if note
- system "#{@config.editor} '#{note.path}'"
- note.update
- else
- puts "Hey! There is no note #{num}! Nice try."
- end
- end
+ puts
+ puts "#{indent}#{title}".bold
+ puts "#{indent}#{"-" * title.length}"
+ puts
- def delete(params)
- num = params.first.to_i
- note = @filtered[num - 1]
+ if verbose
+ notes.each do |num, note|
+ count += 1
- if note and File.exists? note.path
- if confirm("You're #{'sure'.italic} you want to delete note #{num.to_s.bold.white} with title #{note.title.bold.white}?")
- FileUtils.rm(note.path)
- @notes.delete(note)
- @filtered.delete(note)
- puts "Deleted!"
- else
- puts "Whew! That was close."
- end
- else
- puts "Looks like my job is done here, since note #{num} doesn't exist anyway!"
- end
- end
+ if !note
+ puts "#{num}.".ljust(@indent) + " DELETED".italic
+ next
+ end
- def peek(params)
- if params&.first&.downcase == 'config'
- return @config.print
- end
-
- note = @filtered[params.first.to_i - 1]
- if note
- lines = note.content.lines
- puts
- puts "-" * 40
- puts note.title.bold.white
- puts lines.slice(0, 15)
- if lines.length > 15
+ puts "#{num}.".ljust(4) + note.title_limit(70).bold
+ puts "#{indent}#{note.path.gsub(@config.note_path, "")}".italic.light_magenta
+ if note.tags.length > 0
+ tags = note.tags.map { |tag| tag.yellow }
+ puts "#{indent}tags: " + "[#{tags.join('] [')}]"
+ else
+ puts "#{indent}<no tags>"
+ end
+ puts "#{indent}modified: " + note.modified.strftime("%a, %b %e %Y, %l:%M%P").italic
+ puts "#{indent}created: " + note.created.strftime("%a, %b %e %Y, %l:%M%P").italic
puts
- puts "(#{lines.length - 15} more line#{'s' if lines.length != 16}...)".italic
end
- puts "-" * 40
- puts
else
- puts "Note doesn't exist!"
- end
- end
+ notes.each do |num, note|
+ count += 1
- def tag(params)
- notes = multi_note(params)
+ if !note
+ puts "#{num}.".ljust(@indent) + "DELETED".colorize(color: :white, background: :red).italic
+ next
+ end
- notes.each do |note|
- tags = params.slice(1, params.length)
- note.add_tags(tags)
- end
-
- print_list("Changed", notes)
-
- @filtered = notes
-
- puts "Added #{params.length - 1} tag#{"s" if params.length != 2} to #{notes.length} note#{"s" if notes.length != 1}."
- end
-
- def untag(params)
- notes = multi_note(params)
-
- notes.each do |note|
- tags = params.slice(1, params.length)
- note.remove_tags(tags)
- end
-
- print_list("Changed", notes)
-
- @filtered = notes
-
- puts "Removed #{params.length - 1} tag#{"s" if params.length != 2} from #{notes.length} note#{"s" if notes.length != 1}."
- end
-
- def config(params = [])
- if params.length == 0
- system "#{@config.editor} #{@config.path}"
- @config.load
- return
- end
-
- action, key, *value = params
- value = value.join(" ")
-
- if action == "get"
- if key
- puts "#{key}: \"#{@config.get(key)}\""
- else
- @config.print
- end
- elsif action == "set"
- if key
- if value
- puts "Config: #{key} changed from '#{@config.get(key)}' to '#{value}'"
- @config.set(key, value)
- else
- puts "Can't set a key to a value if no value is given."
+ print "#{num}.".ljust(@indent) + note.title_limit(70).bold
+ if note.tags.length > 0
+ tags = note.tags.map { |tag| tag.yellow }
+ print " [#{tags.join('] [')}]"
end
- else
- puts "Can't set a key if one wasn't given."
+ print "\n"
end
- else
- puts "Invalid action: #{action}"
end
- end
-
- def help
+
puts
- puts "Enter a command with the structure:"
- puts " #{@config.prompt} action parameter(s)"
+ puts "#{indent}Listed #{count.to_s.bold} Notes"
puts
- puts "Actions:"
- puts " - #{"new".bold.white} #{"filename".italic}"
- puts " - #{"edit".bold.white} #{"note_number".italic}"
- puts " - #{"delete".bold.white} #{"note_number".italic}"
- puts " - #{"peek".bold.white} #{"note_number".italic}"
- puts " - #{"tag".bold.white} #{"note_number".italic}"
- puts " - #{"untag".bold.white} #{"note_number".italic}"
- puts " - #{"search".bold.white} #{"search_term".italic}"
- puts " - #{"list".bold.white}"
- puts " - #{"config".bold.white} #{"(set/get)".italic} #{"key".italic} [#{"value".italic}]"
- puts " - #{"exit".bold.white}"
- puts " - #{"help".bold.white}"
- puts
- puts "Alternate actions:"
- puts " Most actions also have aliases that do the same thing."
- puts " These are listed for each command:"
- puts " - new: create, c, n"
- puts " - edit: e, open, o"
- puts " - delete: d, rm"
- puts " - peek: p"
- puts " - tag: t"
- puts " - untag: ut"
- puts " - search: find, f, s"
- puts " - list: l, ls"
- puts " - exit: quit, q, close"
- puts " - help: h"
- puts
end
- def list
- @filtered = recently_edited_first(@notes)
- print_list("All Notes", @filtered)
- end
-
- #/================================\#
- # Utilities #
- #\================================/#
-
- private def print_list(title, notes)
- path_length = @config.note_path.split("/").length
- i = 0
-
- puts
- puts " #{title}".bold
- puts " #{"-" * title.length}"
- puts
-
- notes.each do |note|
- i += 1
- puts "#{i}.".ljust(4) + note.title.bold
- puts " #{note.path.gsub(@config.note_path, "")}".italic.light_magenta
- if note.tags.length > 0
- tags = note.tags.map { |tag| tag.yellow }
- puts " tags: " + "[#{tags.join('] [')}]"
- else
- puts " <no tags>"
- end
- puts " modified: " + note.modified.strftime("%a, %b %e %Y, %l:%M%P").italic
- puts " created: " + note.created.strftime("%a, %b %e %Y, %l:%M%P").italic
- puts
- end
-
- puts " Listed #{i.to_s.bold} Notes"
- puts
- end
-
private def confirm(message = "Confirm")
print "#{message} [y/n]: "
- case gets.chomp.strip.downcase
+ case gets&.chomp&.strip&.downcase
when "y", "yes", "yeah", "sure", "yep", "okay", "aye"
return true
when "n", "no", "nope", "nay"
return false
else
@@ -351,11 +175,11 @@
private def multi_note(params)
notes = []
params.first.split(",").each do |num|
- note = @filtered[num.to_i - 1]
+ note = @notes[num.to_i]
if note
notes << note
else
puts "Note #{num} doesn't exist!"
end
@@ -363,14 +187,16 @@
notes
end
private def recently_edited_first(notes)
+ ap notes
+
notes.sort_by { |note| note.modified }.reverse
end
- private def has_all_tags(note, tags)
+ private def has_tags(note, tags)
has = true
note_tags = note.tags
tags.each do |tag|
if !note_tags.include? tag
has = false
@@ -378,10 +204,10 @@
end
end
has
end
- private def has_none_tags(note, tags)
+ private def does_not_have_tags(note, tags)
doesnt_have = true
note_tags = note.tags
tags.each do |tag|
if note_tags.include? tag
doesnt_have = false
\ No newline at end of file