#!/usr/bin/env ruby require 'open-uri' require 'yaml' require 'fileutils' require 'io/console' STORAGE = File.expand_path(ENV['NOTES_PATH'] || '~/.notes') FileUtils.mkdir_p STORAGE # ------------------------------------------ # HELPERS # ------------------------------------------ def edit(file_path) editor = ENV['EDITOR'] || 'vi'.freeze system "#{editor} #{file_path}" end def copy(file) case RUBY_PLATFORM when /darwin/ `cat #{file} | pbcopy` when /linux/ `cat #{file} | xsel --clipboard --input` end end def open_url(url) case RUBY_PLATFORM when /darwin/ system "open #{url}" when /linux/ system "xdg-open #{url}" end end # ------------------------------------------ # PRESENTATION METHODS # ------------------------------------------ def short_display(file) case File.extname(file) when '.bookmark' content = YAML.load_file(file) puts content['title'].to_s + ' (' + content['url'].to_s + ')' when '.snippet' content = File.read(file) puts content.tr("\n", ' ')[0..100] else puts File.open(file).read(100).to_s.lines.first end end def long_display(file) puts File.read(file) end def choose(files) if files.empty? exit 0 elsif files.one? long_display files.first operations(files.first) else files.each_with_index do |file, index| print "#{index + 1}. " short_display file end print '-> (1..9) or Q to exit: ' puts choice = $stdin.getch case choice when 'q' exit 0 when /\A[1-9]\z/ long_display files[choice.to_i - 1] operations(files[choice.to_i - 1]) end end end def operations(file) print '[E]dit [D]elete [O]pen [C]opy, Else to Quit: ' puts choice = $stdin.getch case choice when 'e' edit file when 'd' File.delete file when 'o' content = YAML.load_file(file) open_url content['url'] when 'c' copy file else exit 0 end end def create_snippet(text) print 'Do you want to save it as a snippet? [y/N]: ' puts choice = $stdin.getch return unless choice.casecmp 'y' file_path = File.join(STORAGE, Time.now.to_i.to_s + '.snippet') File.write(file_path, text) end # ----------------------------------------------------------- # TOP LEVEL COMMANDS # ----------------------------------------------------------- def help exec_name = File.basename(__FILE__) puts <<-EOT Snippets and bookmarks manager. Usage: #{exec_name} [command|inputs] Commands: #{exec_name} help, --help : print this message Input types: url: e.g "http://www.example.com", add URL as a bookmark file keyword: search bookmarks and perform action on it, a single word of multiple words or regex, it is passed to "ag silver searcher" snippet text: any multiword text, it will search first if no files contain this text you'll be asked if you want to create a snippet for it EOT end def bookmark url = ARGV.first content = begin open(url).read rescue "" end file_path = File.join(STORAGE, Time.now.to_i.to_s + '.bookmark') bookmark_object = { 'url' => url, 'title' => content.match(%r{(.+)<\/title>}im).to_a[1] } File.write(file_path, bookmark_object.to_yaml) edit file_path end def search keyword = ARGV.join ' ' files = `ag -l "#{keyword}" #{STORAGE}`.lines top_matches = files[0...9].map(&:chomp) if top_matches.empty? && keyword.include?(' ') create_snippet(keyword) else choose top_matches end end send case ARGV.first when /\Ahttp/ :bookmark when 'help', '--help' :help else :search end