snipper 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/snipper +32 -0
- data/lib/snipper.rb +73 -0
- data/lib/snipper/command/delete.rb +21 -0
- data/lib/snipper/command/edit.rb +35 -0
- data/lib/snipper/command/new.rb +30 -0
- data/lib/snipper/command/search.rb +21 -0
- data/lib/snipper/command/view.rb +25 -0
- data/lib/snipper/config.rb +36 -0
- data/lib/snipper/output/pygments_output.rb +75 -0
- data/lib/snipper/snippet.rb +158 -0
- data/lib/snipper/version.rb +3 -0
- metadata +119 -0
data/bin/snipper
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'snipper'
|
4
|
+
|
5
|
+
@options = {:command => "new"}
|
6
|
+
|
7
|
+
OptionParser.new do |opts|
|
8
|
+
opts.on("--lang LANGUAGE", "-l", "Snippet Language") do |v|
|
9
|
+
@options[:syntax] = v
|
10
|
+
end
|
11
|
+
|
12
|
+
opts.on("-L","List Languages") do
|
13
|
+
@options[:list] = true
|
14
|
+
end
|
15
|
+
end.parse!
|
16
|
+
|
17
|
+
exec "pygmentize -L lexer" if @options[:list]
|
18
|
+
|
19
|
+
@options[:command] = ARGV[0] if ARGV.size >= 1
|
20
|
+
|
21
|
+
case @options[:command]
|
22
|
+
when "search", "s"
|
23
|
+
Snipper::Command::Search.new(@options)
|
24
|
+
when "delete", "d", "rm"
|
25
|
+
Snipper::Command::Delete.new(@options)
|
26
|
+
when "view", "v"
|
27
|
+
Snipper::Command::View.new(@options)
|
28
|
+
when "edit", "e"
|
29
|
+
puts Snipper::Command::Edit.new(@options).url
|
30
|
+
else
|
31
|
+
puts Snipper::Command::New.new(@options).url
|
32
|
+
end
|
data/lib/snipper.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'pygments.rb'
|
3
|
+
require 'optparse'
|
4
|
+
require 'etc'
|
5
|
+
require 'snipper/config'
|
6
|
+
require 'snipper/snippet'
|
7
|
+
require 'snipper/command/new'
|
8
|
+
require 'snipper/command/edit'
|
9
|
+
require 'snipper/command/delete'
|
10
|
+
require 'snipper/command/search'
|
11
|
+
require 'snipper/command/view'
|
12
|
+
require 'snipper/version'
|
13
|
+
require 'snipper/output/pygments_output.rb'
|
14
|
+
require 'yaml'
|
15
|
+
require 'fileutils'
|
16
|
+
|
17
|
+
class Snipper
|
18
|
+
def initialize
|
19
|
+
config = File.join(Etc.getpwuid.dir, ".snipper", "config.yml")
|
20
|
+
|
21
|
+
if File.exist?(config)
|
22
|
+
Config.load(config)
|
23
|
+
else
|
24
|
+
Config.load({:config_file => config})
|
25
|
+
end
|
26
|
+
|
27
|
+
setup
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup
|
31
|
+
FileUtils.mkdir_p(Config[:snippets_dir])
|
32
|
+
|
33
|
+
unless File.exist?(Config[:config_file])
|
34
|
+
File.open(Config[:config_file], "w") do |c|
|
35
|
+
c.print Config.to_yaml
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Array
|
42
|
+
def in_groups_of(chunk_size, padded_with=nil, &block)
|
43
|
+
arr = self.clone
|
44
|
+
|
45
|
+
# how many to add
|
46
|
+
padding = chunk_size - (arr.size % chunk_size)
|
47
|
+
|
48
|
+
# pad at the end
|
49
|
+
arr.concat([padded_with] * padding) unless padding == chunk_size
|
50
|
+
|
51
|
+
# how many chunks we'll make
|
52
|
+
count = arr.size / chunk_size
|
53
|
+
|
54
|
+
# make that many arrays
|
55
|
+
result = []
|
56
|
+
count.times {|s| result << arr[s * chunk_size, chunk_size]}
|
57
|
+
|
58
|
+
if block_given?
|
59
|
+
result.each_with_index do |a, i|
|
60
|
+
case block.arity
|
61
|
+
when 1
|
62
|
+
yield(a)
|
63
|
+
when 2
|
64
|
+
yield(a, (i == result.size - 1))
|
65
|
+
else
|
66
|
+
raise "Expected 1 or 2 arguments, got #{block.arity}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
else
|
70
|
+
result
|
71
|
+
end
|
72
|
+
end unless method_defined?(:in_groups_of)
|
73
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Snipper
|
2
|
+
class Command
|
3
|
+
class Delete
|
4
|
+
attr_reader :url, :snippet
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@options = options
|
8
|
+
|
9
|
+
snipper = Snipper.new
|
10
|
+
|
11
|
+
raise "Please specify a snippet number" unless ARGV[1] =~ /^\d+$/
|
12
|
+
|
13
|
+
options[:snippet] = ARGV[1]
|
14
|
+
|
15
|
+
snippet = Snippet.new(nil, @options)
|
16
|
+
|
17
|
+
snippet.delete!
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Snipper
|
2
|
+
class Command
|
3
|
+
class Edit
|
4
|
+
attr_reader :url, :snippet
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@options = options
|
8
|
+
|
9
|
+
snipper = Snipper.new
|
10
|
+
|
11
|
+
raise "Please specify a snippet number" unless ARGV[1] =~ /^\d+$/
|
12
|
+
|
13
|
+
options[:snippet] = ARGV[1]
|
14
|
+
|
15
|
+
snippet = Snippet.new(nil, @options)
|
16
|
+
@url = snippet.url_for_snippet
|
17
|
+
|
18
|
+
files = snippet.files.map {|file| File.join(snippet.snippet_path, file)}
|
19
|
+
|
20
|
+
editor = ENV["EDITOR"] || "vi"
|
21
|
+
|
22
|
+
system "%s %s" % [editor, files.join(" ")]
|
23
|
+
|
24
|
+
files.each do |file|
|
25
|
+
unless File.size?(file)
|
26
|
+
puts "Removing #{file} from the snippet"
|
27
|
+
File.unlink(file)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
snippet.update_html
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Snipper
|
2
|
+
class Command
|
3
|
+
class New
|
4
|
+
attr_reader :url, :snippet
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@options = options
|
8
|
+
|
9
|
+
@snipper = Snipper.new
|
10
|
+
|
11
|
+
# if the first arg is a number and it isnt a file path
|
12
|
+
# then assume this is a snippet id we want to append to
|
13
|
+
if ARGV.first =~ /^\d+$/ && !File.exist?(ARGV.first)
|
14
|
+
options[:snippet] = ARGV.shift
|
15
|
+
end
|
16
|
+
|
17
|
+
if STDIN.tty?
|
18
|
+
abort "Please specify a filename or provide one on STDIN" if ARGV.empty?
|
19
|
+
|
20
|
+
txt = ARGV
|
21
|
+
else
|
22
|
+
txt = STDIN.read
|
23
|
+
end
|
24
|
+
|
25
|
+
@snippet = Snippet.new(txt, @options)
|
26
|
+
@url = @snippet.url_for_snippet
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Snipper
|
2
|
+
class Command
|
3
|
+
class Search
|
4
|
+
attr_reader :url, :snippet
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@options = options
|
8
|
+
|
9
|
+
snipper = Snipper.new
|
10
|
+
|
11
|
+
raise "Please specify a search string" unless ARGV[1]
|
12
|
+
|
13
|
+
Dir.chdir(Config[:snippets_dir]) do
|
14
|
+
grep = Config[:grep].gsub("%Q%", ARGV[1].gsub("'", "\\'"))
|
15
|
+
|
16
|
+
system grep
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Snipper
|
2
|
+
class Command
|
3
|
+
class View
|
4
|
+
attr_reader :url, :snippet
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@options = options
|
8
|
+
|
9
|
+
snipper = Snipper.new
|
10
|
+
|
11
|
+
raise "Please specify a snippet number" unless ARGV[1] =~ /^\d+$/
|
12
|
+
|
13
|
+
options[:snippet] = ARGV[1]
|
14
|
+
|
15
|
+
snippet = Snippet.new(nil, @options)
|
16
|
+
|
17
|
+
files = snippet.files.map {|file| File.join(snippet.snippet_path, file)}
|
18
|
+
|
19
|
+
pager = ENV["PAGER"] || "less"
|
20
|
+
|
21
|
+
system "cat %s|%s" % [files.join(" "), pager]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
## description: shitty config class
|
2
|
+
class Snipper
|
3
|
+
class Config
|
4
|
+
class << self
|
5
|
+
def load(source)
|
6
|
+
@config = {:renderer => "ultraviolet",
|
7
|
+
:grep => "grep --color=auto -riHn -C 2 '%Q%' *",
|
8
|
+
:snipper_dir => File.join(Etc.getpwuid.dir, ".snipper"),
|
9
|
+
:snippets_dir => File.join(Etc.getpwuid.dir, ".snipper", "snippets"),
|
10
|
+
:config_file => File.join(Etc.getpwuid.dir, ".snipper", "config.yml")}
|
11
|
+
|
12
|
+
if source.is_a?(String)
|
13
|
+
raise "Config file #{source} not found" unless File.exist?(source)
|
14
|
+
|
15
|
+
config = YAML.load_file(source)
|
16
|
+
@config.merge! config if config
|
17
|
+
|
18
|
+
elsif source.is_a?(Hash)
|
19
|
+
@config.merge! source
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def include?(key)
|
24
|
+
@config.include?(key)
|
25
|
+
end
|
26
|
+
|
27
|
+
def [](key)
|
28
|
+
@config[key]
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_yaml
|
32
|
+
@config.to_yaml
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
class Snipper
|
2
|
+
class Output
|
3
|
+
class Pygments_Output
|
4
|
+
def initialize(snippet)
|
5
|
+
@snippet = snippet
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.list_langs
|
9
|
+
Pygments.lexers.map{|l| l[1][:aliases]}.flatten.sort
|
10
|
+
end
|
11
|
+
|
12
|
+
def save
|
13
|
+
theme = Config[:theme] || "default"
|
14
|
+
|
15
|
+
raise "Please set the :public_target_dir setting" unless Config[:public_target_dir]
|
16
|
+
|
17
|
+
path = @snippet.snippet_html_path
|
18
|
+
|
19
|
+
FileUtils.mkdir_p(path)
|
20
|
+
|
21
|
+
File.open(File.join(path, "index.html"), "w") do |html|
|
22
|
+
html.puts "<head>"
|
23
|
+
html.puts "<link rel='stylesheet' type='text/css' href='../css/#{theme}.css' media='all' />"
|
24
|
+
html.puts "<style type='text/css'>"
|
25
|
+
html.puts ".highlighttable { background-color: #253B76; width: 100%;}"
|
26
|
+
html.puts ".content { width: 100%;}"
|
27
|
+
html.puts ".linenos { text-align: right; color: white; width: 30px; }"
|
28
|
+
|
29
|
+
if Config[:dark_theme]
|
30
|
+
html.puts ".highlight { background-color: #0C1000 }"
|
31
|
+
else
|
32
|
+
html.puts ".highlight { background-color: white }"
|
33
|
+
end
|
34
|
+
|
35
|
+
html.puts "</style>"
|
36
|
+
html.puts "</head>"
|
37
|
+
html.puts "<body>"
|
38
|
+
|
39
|
+
html.puts "<table class='content'>"
|
40
|
+
html.puts "<tr><td>"
|
41
|
+
|
42
|
+
@snippet.each_file do |file, text, headers|
|
43
|
+
File.open(File.join(path, "#{File.basename(file)}.raw"), "w") do |f|
|
44
|
+
f.puts text
|
45
|
+
end
|
46
|
+
|
47
|
+
syntax = @snippet.options[:syntax]
|
48
|
+
|
49
|
+
unless syntax
|
50
|
+
lexer = Pygments::Lexer.find_by_extname(File.extname(file))
|
51
|
+
|
52
|
+
if lexer
|
53
|
+
syntax = lexer.name
|
54
|
+
else
|
55
|
+
syntax = Config[:default_syntax] || "ruby"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
raise "Unknown syntax #{syntax}" unless self.class.list_langs.include?(syntax)
|
60
|
+
|
61
|
+
html.puts "<H2>%s</H2>" % [ headers["description"] ] if headers["description"]
|
62
|
+
html.puts Pygments.highlight(text, :lexer => syntax, :options => {:linenos => "table", :style => theme})
|
63
|
+
html.puts "syntax: %s download: <a href='%s.raw'>raw</a>" % [ syntax, File.basename(file) ]
|
64
|
+
html.puts "<br /><br />"
|
65
|
+
end
|
66
|
+
|
67
|
+
html.puts "</td></tr>"
|
68
|
+
html.puts "<tr align='right'><td><a href='%s'>Snipper</a></td></tr>" % [ "http://github.com/ripienaar/snipper" ]
|
69
|
+
html.puts "</table>"
|
70
|
+
html.puts "</body>"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
class Snipper
|
2
|
+
class Snippet
|
3
|
+
attr_reader :options
|
4
|
+
|
5
|
+
def initialize(snippet, options = {:snippet => nil})
|
6
|
+
@options = options
|
7
|
+
|
8
|
+
if options[:snippet]
|
9
|
+
raise "Snippets ids must be numerical" unless options[:snippet] == options[:snippet].to_i.to_s
|
10
|
+
raise "Unknown snippet %s" % [ options[:snippet] ] unless File.exist?(snippet_path)
|
11
|
+
end
|
12
|
+
|
13
|
+
if snippet
|
14
|
+
# new snippet
|
15
|
+
begin
|
16
|
+
unless @options[:snippet]
|
17
|
+
@options[:snippet] = next_snippet_id
|
18
|
+
|
19
|
+
create_snippet_dir
|
20
|
+
|
21
|
+
append_snippet(snippet)
|
22
|
+
|
23
|
+
update_html
|
24
|
+
else # add to existing snippet
|
25
|
+
append_snippet(snippet)
|
26
|
+
|
27
|
+
update_html
|
28
|
+
end
|
29
|
+
rescue Exception => e
|
30
|
+
STDERR.puts "Could not save snippet: #{e.class}: #{e}"
|
31
|
+
# TODO: clear up half baked snippets
|
32
|
+
|
33
|
+
raise
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def delete!
|
39
|
+
raise "Refusing to remove all snippets" if File.expand_path(snippet_path) == File.expand_path(Config[:public_target_dir])
|
40
|
+
raise "Snippet path #{snippet_path} looks suspect, refusing to delete" unless snippet_path.match(/\d+$/)
|
41
|
+
|
42
|
+
raise "Refusing to remove all snippets" if File.expand_path(snippet_html_path) == File.expand_path(Config[:public_target_dir])
|
43
|
+
raise "Snippet path #{snippet_html_path} looks suspect, refusing to delete" unless snippet_html_path.match(/\d+$/)
|
44
|
+
|
45
|
+
if File.directory?(snippet_path)
|
46
|
+
puts "Removing #{snippet_path}"
|
47
|
+
FileUtils.remove_entry_secure(snippet_path)
|
48
|
+
end
|
49
|
+
|
50
|
+
if File.directory?(snippet_html_path)
|
51
|
+
puts "Removing #{snippet_html_path}"
|
52
|
+
FileUtils.remove_entry_secure(snippet_html_path)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def append_snippet(snippet)
|
57
|
+
if snippet.is_a?(Array)
|
58
|
+
[snippet].flatten.each do |file|
|
59
|
+
save_next_file(snippet_file(File.read(file)))
|
60
|
+
end
|
61
|
+
else
|
62
|
+
save_next_file(snippet_file(snippet))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def update_html
|
67
|
+
Output::Pygments_Output.new(self).save
|
68
|
+
end
|
69
|
+
|
70
|
+
def url_for_snippet
|
71
|
+
"%s/%s" % [ Config[:baseurl], @options[:snippet] ]
|
72
|
+
end
|
73
|
+
|
74
|
+
def save_next_file(text)
|
75
|
+
file_name = File.join(snippet_path, next_file_id.to_s)
|
76
|
+
|
77
|
+
File.open(file_name, "w") do |file|
|
78
|
+
file.puts text
|
79
|
+
end
|
80
|
+
|
81
|
+
return file_name
|
82
|
+
end
|
83
|
+
|
84
|
+
def files
|
85
|
+
Dir.entries(snippet_path).grep(/^\d+$/).sort_by{|i| Integer(i)}
|
86
|
+
end
|
87
|
+
|
88
|
+
def each_file
|
89
|
+
files.each do |file|
|
90
|
+
headers, text = parse_file(File.read(File.join(snippet_path, file)))
|
91
|
+
|
92
|
+
yield File.join(snippet_path, file), text, headers
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def parse_file(file)
|
97
|
+
headers = {}
|
98
|
+
text = ""
|
99
|
+
inheader = true
|
100
|
+
|
101
|
+
file.each_line do |line|
|
102
|
+
# skips the first blank line
|
103
|
+
if line == "\n" && inheader
|
104
|
+
inheader = false
|
105
|
+
next
|
106
|
+
end
|
107
|
+
|
108
|
+
if line.start_with?("##") && inheader
|
109
|
+
if line =~ /^## (\S+): (.+)/
|
110
|
+
headers[$1] = $2
|
111
|
+
elsif line =~ /## (.+)/
|
112
|
+
headers["description"] = $1
|
113
|
+
end
|
114
|
+
else
|
115
|
+
inheader = false
|
116
|
+
text += line
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
return headers, text
|
121
|
+
end
|
122
|
+
|
123
|
+
def snippet_html_path
|
124
|
+
File.expand_path(File.join(Config[:public_target_dir], @options[:snippet].to_s))
|
125
|
+
end
|
126
|
+
|
127
|
+
def snippet_path
|
128
|
+
File.join(Config[:snippets_dir], @options[:snippet].to_s)
|
129
|
+
end
|
130
|
+
|
131
|
+
def create_snippet_dir
|
132
|
+
FileUtils.mkdir(snippet_path)
|
133
|
+
end
|
134
|
+
|
135
|
+
def next_file_id
|
136
|
+
Integer(files[-1]) + 1
|
137
|
+
end
|
138
|
+
|
139
|
+
def next_snippet_id
|
140
|
+
snippets = Dir.entries(Config[:snippets_dir]).grep(/^\d+$/)
|
141
|
+
Integer(snippets.map{|s| s.to_i}.sort.max) + 1
|
142
|
+
end
|
143
|
+
|
144
|
+
def snippet_file(text)
|
145
|
+
snippet = StringIO.new
|
146
|
+
|
147
|
+
unless text.start_with?("##")
|
148
|
+
snippet.puts "## description: %s" % [ @options[:description] ] if @options[:description]
|
149
|
+
snippet.puts "## syntax: %s" % [ @options[:syntax] ] if @options[:syntax]
|
150
|
+
snippet.puts
|
151
|
+
end
|
152
|
+
|
153
|
+
snippet.puts text
|
154
|
+
|
155
|
+
snippet.string
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: snipper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- R.I.Pienaar
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-04-26 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rake
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rdoc
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: pygments.rb
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :runtime
|
62
|
+
version_requirements: *id003
|
63
|
+
description: A Unix CLI centric snippet manager that produces static files
|
64
|
+
email: rip@devco.net
|
65
|
+
executables:
|
66
|
+
- snipper
|
67
|
+
extensions: []
|
68
|
+
|
69
|
+
extra_rdoc_files: []
|
70
|
+
|
71
|
+
files:
|
72
|
+
- bin/snipper
|
73
|
+
- lib/snipper/snippet.rb
|
74
|
+
- lib/snipper/config.rb
|
75
|
+
- lib/snipper/output/pygments_output.rb
|
76
|
+
- lib/snipper/version.rb
|
77
|
+
- lib/snipper/command/delete.rb
|
78
|
+
- lib/snipper/command/edit.rb
|
79
|
+
- lib/snipper/command/new.rb
|
80
|
+
- lib/snipper/command/search.rb
|
81
|
+
- lib/snipper/command/view.rb
|
82
|
+
- lib/snipper.rb
|
83
|
+
has_rdoc: true
|
84
|
+
homepage: http://devco.net/
|
85
|
+
licenses: []
|
86
|
+
|
87
|
+
post_install_message:
|
88
|
+
rdoc_options: []
|
89
|
+
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
hash: 3
|
99
|
+
segments:
|
100
|
+
- 0
|
101
|
+
version: "0"
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
hash: 3
|
108
|
+
segments:
|
109
|
+
- 0
|
110
|
+
version: "0"
|
111
|
+
requirements: []
|
112
|
+
|
113
|
+
rubyforge_project:
|
114
|
+
rubygems_version: 1.3.7
|
115
|
+
signing_key:
|
116
|
+
specification_version: 3
|
117
|
+
summary: Snipper
|
118
|
+
test_files: []
|
119
|
+
|