pry-note 0.2.1 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +12 -2
- data/lib/pry-note.rb +16 -211
- data/lib/pry-note/commands.rb +242 -0
- data/lib/pry-note/hooks.rb +31 -0
- data/lib/pry-note/version.rb +1 -1
- data/pry-note.gemspec +30 -0
- data/test/helper.rb +26 -0
- data/test/test_pry_note.rb +240 -0
- metadata +10 -3
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ direc = File.dirname(__FILE__)
|
|
6
6
|
PROJECT_NAME = "pry-note"
|
7
7
|
|
8
8
|
require 'rake/clean'
|
9
|
-
require '
|
9
|
+
require 'rubygems/package_task'
|
10
10
|
require "#{PROJECT_NAME}/version"
|
11
11
|
|
12
12
|
CLOBBER.include("**/*~", "**/*#*", "**/*.log")
|
@@ -28,11 +28,21 @@ def apply_spec_defaults(s)
|
|
28
28
|
s.test_files = `git ls-files -- test/*`.split("\n")
|
29
29
|
end
|
30
30
|
|
31
|
+
desc "Set up and run tests"
|
32
|
+
task :default => [:test]
|
33
|
+
|
34
|
+
|
31
35
|
desc "run pry with plugin enabled"
|
32
36
|
task :pry do
|
33
37
|
exec("pry -rubygems -I#{direc}/lib/ -r #{direc}/lib/#{PROJECT_NAME}")
|
34
38
|
end
|
35
39
|
|
40
|
+
desc "Run tests"
|
41
|
+
task :test do
|
42
|
+
sh "bacon -Itest -rubygems -a -q"
|
43
|
+
end
|
44
|
+
task :spec => :test
|
45
|
+
|
36
46
|
desc "Show version"
|
37
47
|
task :version do
|
38
48
|
puts "Pry-note version: #{PryNote::VERSION}"
|
@@ -47,7 +57,7 @@ namespace :ruby do
|
|
47
57
|
s.platform = Gem::Platform::RUBY
|
48
58
|
end
|
49
59
|
|
50
|
-
|
60
|
+
Gem::PackageTask.new(spec) do |pkg|
|
51
61
|
pkg.need_zip = false
|
52
62
|
pkg.need_tar = false
|
53
63
|
end
|
data/lib/pry-note.rb
CHANGED
@@ -1,222 +1,27 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
banner <<-USAGE
|
7
|
-
Usage: note [OPTIONS]
|
8
|
-
Add notes to classes and methods.
|
9
|
-
|
10
|
-
e.g note -a Pry#repl "this is my note" #=> add a note without opening editor
|
11
|
-
e.g note -a Pry#repl #=> add a note (with editor) to Pry#repl method
|
12
|
-
e.g note -d Pry#repl:1 #=> delete the 1st note from Pry#repl
|
13
|
-
e.g note -d Pry#repl #=> delete all notes from Pry#repl
|
14
|
-
e.g note -l #=> list all notes
|
15
|
-
USAGE
|
16
|
-
|
17
|
-
def options(opt)
|
18
|
-
opt.on :a, :add, "Add a note to a method or class.", :argument => true
|
19
|
-
opt.on :s, :show, "Show any notes associated with the given method or class.", :argument => true
|
20
|
-
opt.on :d, :delete, "Delete notes for a method or class.", :argument => true
|
21
|
-
opt.on "delete-all", "Delete all notes."
|
22
|
-
opt.on :e, :export, "Export notes to a file.", :argument => :optional
|
23
|
-
opt.on :load, "Load notes from a file.", :argument => :optional
|
24
|
-
opt.on :l, :list, "List all notes."
|
25
|
-
opt.on "list-all", "List all notes with content."
|
26
|
-
end
|
27
|
-
|
28
|
-
def setup
|
29
|
-
if !state.initial_setup_complete
|
30
|
-
add_reminders
|
31
|
-
load_notes
|
32
|
-
state.initial_setup_complete = true
|
33
|
-
_pry_.hooks.add_hook(:after_session, :export_notes) { export_notes }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def notes
|
38
|
-
state.notes ||= {}
|
39
|
-
end
|
40
|
-
|
41
|
-
# edit a note in a temporary file and return note content
|
42
|
-
def edit_note(obj_name)
|
43
|
-
temp_file do |f|
|
44
|
-
f.puts("Enter note content here for #{obj_name} (and erase this line)")
|
45
|
-
f.flush
|
46
|
-
f.close(false)
|
47
|
-
invoke_editor(f.path, 1, false)
|
48
|
-
File.read(f.path)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def process
|
53
|
-
if opts.present?(:add)
|
54
|
-
add_note(opts[:a])
|
55
|
-
elsif opts.present?(:show)
|
56
|
-
show_note(opts[:s])
|
57
|
-
elsif opts.present?(:list)
|
58
|
-
list_notes
|
59
|
-
elsif opts.present?(:export)
|
60
|
-
export_notes(opts[:e])
|
61
|
-
elsif opts.present?(:delete)
|
62
|
-
delete_note(opts[:d])
|
63
|
-
elsif opts.present?(:"delete-all")
|
64
|
-
notes.replace({})
|
65
|
-
elsif opts.present?(:"list-all")
|
66
|
-
list_all
|
67
|
-
elsif opts.present?(:load)
|
68
|
-
load_notes(opts[:load])
|
69
|
-
else
|
70
|
-
meth = Pry::Method.from_binding(target)
|
71
|
-
if internal_binding?(target) || !meth
|
72
|
-
obj = target.eval("self")
|
73
|
-
obj_name = obj.is_a?(Module) ? obj.name : obj.class.name
|
74
|
-
add_note(obj_name)
|
75
|
-
else
|
76
|
-
add_note(meth.name_with_owner)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def retrieve_code_object_safely(name)
|
82
|
-
code_object = retrieve_code_object_from_string(name, target)
|
83
|
-
|
84
|
-
if !code_object
|
85
|
-
raise Pry::CommandError, "No code object found named #{name}"
|
86
|
-
elsif code_object.name.to_s == ""
|
87
|
-
raise Pry::CommandError, "Object #{name} doesn't have a proper name, can't create note"
|
88
|
-
end
|
89
|
-
|
90
|
-
code_object
|
91
|
-
end
|
92
|
-
|
93
|
-
def code_object_name(co)
|
94
|
-
co.is_a?(Pry::Method) ? co.name_with_owner : co.name
|
95
|
-
end
|
96
|
-
|
97
|
-
def add_note(name)
|
98
|
-
co_name = code_object_name(retrieve_code_object_safely(name))
|
99
|
-
|
100
|
-
if args.any?
|
101
|
-
note = args.join(" ")
|
102
|
-
else
|
103
|
-
note = edit_note(co_name)
|
104
|
-
end
|
105
|
-
|
106
|
-
notes[co_name] ||= []
|
107
|
-
notes[co_name] << note
|
108
|
-
|
109
|
-
output.puts "Added note to #{co_name}!"
|
110
|
-
end
|
111
|
-
|
112
|
-
def delete_note(name)
|
113
|
-
name, note_number = name.split(":")
|
114
|
-
co_name = code_object_name(retrieve_code_object_safely(name))
|
1
|
+
require 'yaml'
|
2
|
+
require 'pry-note/version'
|
3
|
+
require 'pry-note/hooks'
|
4
|
+
require 'pry-note/commands'
|
115
5
|
|
116
|
-
|
117
|
-
output.puts "No notes to delete for #{co_name}!"
|
118
|
-
elsif note_number
|
119
|
-
notes[co_name].delete_at(note_number.to_i - 1)
|
120
|
-
notes.delete(co_name) if notes[co_name].empty?
|
121
|
-
output.puts "Deleted note #{note_number} for #{co_name}!"
|
122
|
-
else
|
123
|
-
notes.delete(co_name)
|
124
|
-
output.puts "Deleted all notes for #{text.bold(co_name)}!"
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def show_note(name)
|
129
|
-
code_object = retrieve_code_object_safely(name)
|
130
|
-
|
131
|
-
co_name = code_object_name(code_object)
|
132
|
-
|
133
|
-
if !notes.has_key?(co_name)
|
134
|
-
output.puts "No notes saved for #{text.bold(co_name)}"
|
135
|
-
return
|
136
|
-
end
|
137
|
-
|
138
|
-
output.puts text.bold("#{co_name}:\n--")
|
139
|
-
|
140
|
-
notes[code_object_name(code_object)].each_with_index do |note, index|
|
141
|
-
output.puts "\nNote #{text.bold((index + 1).to_s)}: #{note}"
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
def export_notes(file_name=nil)
|
146
|
-
require 'yaml'
|
147
|
-
file_name ||= Pry.config.notes_file
|
6
|
+
Pry.config.notes_file = "./notes.yml"
|
148
7
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
end
|
8
|
+
module PryNote
|
9
|
+
def self.notes() @notes ||= {}; end
|
10
|
+
def self.notes=(o) @notes = o; end
|
153
11
|
|
154
|
-
def load_notes(file_name=nil)
|
155
|
-
|
12
|
+
def self.load_notes(file_name=nil)
|
13
|
+
return if !file_name && !Pry.config.notes_file
|
156
14
|
file_name ||= Pry.config.notes_file
|
157
|
-
|
158
15
|
expanded_path = File.expand_path(file_name)
|
159
16
|
if File.exists?(expanded_path)
|
160
|
-
notes
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
def list_all
|
165
|
-
if notes.any?
|
166
|
-
output.puts text.bold("Showing all available notes:\n\n")
|
167
|
-
notes.each do |key, content|
|
168
|
-
begin
|
169
|
-
show_note(key)
|
170
|
-
output.puts "\n"
|
171
|
-
rescue
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
output.puts "\nTo view notes for an item type, e.g: `note -s Klass#method`"
|
176
|
-
else
|
177
|
-
output.puts "No notes available."
|
17
|
+
PryNote.notes = YAML.load File.read(expanded_path)
|
178
18
|
end
|
179
19
|
end
|
180
20
|
|
181
|
-
def
|
182
|
-
if
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
output.puts "#{text.bold(key)} has #{content.count} notes"
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
output.puts "\nTo view notes for an item type, e.g: `note -s Klass#method`"
|
191
|
-
else
|
192
|
-
output.puts "No notes available."
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
def add_reminders
|
197
|
-
me = self
|
198
|
-
reminder = proc do
|
199
|
-
begin
|
200
|
-
code_object = retrieve_code_object_from_string(args.first.to_s, target)
|
201
|
-
if me.notes.keys.include?(me.code_object_name(code_object))
|
202
|
-
co_name = me.code_object_name(code_object)
|
203
|
-
output.puts "\n\n#{text.bold("Notes:")}\n--\n\n"
|
204
|
-
|
205
|
-
me.notes[me.code_object_name(code_object)].each_with_index do |note, index|
|
206
|
-
clipped_note = note.lines.count < 3 ? note : note.lines.to_a[0..2].join +
|
207
|
-
text.bold("<...clipped...>") + " Use `note -s #{co_name}` to view unelided notes."
|
208
|
-
amended_note = clipped_note.lines.each_with_index.map do |line, idx|
|
209
|
-
idx > 0 ? "#{' ' * ((index + 1).to_s.size + 2)}#{line}" : line
|
210
|
-
end.join
|
211
|
-
output.puts "#{text.bold((index + 1).to_s)}. #{amended_note}"
|
212
|
-
end
|
213
|
-
|
214
|
-
end
|
215
|
-
rescue
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
_pry_.commands.after_command("show-source", &reminder)
|
220
|
-
_pry_.commands.after_command("show-doc", &reminder)
|
21
|
+
def self.export_notes(file_name=nil)
|
22
|
+
return if !file_name && !Pry.config.notes_file
|
23
|
+
file_name ||= Pry.config.notes_file
|
24
|
+
expanded_path = File.expand_path(file_name)
|
25
|
+
File.open(expanded_path, "w") { |f| f.puts YAML.dump(PryNote.notes) }
|
221
26
|
end
|
222
27
|
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
Pry::Commands.create_command "note" do
|
2
|
+
description "Note stuff."
|
3
|
+
|
4
|
+
banner <<-USAGE
|
5
|
+
Usage: note [OPTIONS]
|
6
|
+
Add notes to classes and methods.
|
7
|
+
|
8
|
+
e.g note -a Pry#repl "this is my note" #=> add a note without opening editor
|
9
|
+
e.g note -a Pry#repl #=> add a note (with editor) to Pry#repl method
|
10
|
+
e.g note -d Pry#repl:1 #=> delete the 1st note from Pry#repl
|
11
|
+
e.g note -d Pry#repl #=> delete all notes from Pry#repl
|
12
|
+
e.g note -l #=> list all notes
|
13
|
+
USAGE
|
14
|
+
|
15
|
+
def subcommands(cmd)
|
16
|
+
cmd.on :add do |opt|
|
17
|
+
opt.on :m, "message", "Provide the note inline (without opening an editor).", :argument => true
|
18
|
+
end
|
19
|
+
|
20
|
+
cmd.on :show do |opt|
|
21
|
+
opt.on :v, :verbose, "Show all notes together with source code."
|
22
|
+
end
|
23
|
+
|
24
|
+
cmd.on :list do |opt|
|
25
|
+
opt.on :v, :verbose, "List all notes and content with source code."
|
26
|
+
end
|
27
|
+
cmd.on :export
|
28
|
+
cmd.on :load
|
29
|
+
cmd.on :delete do |opt|
|
30
|
+
opt.on :all, "Delete all notes."
|
31
|
+
end
|
32
|
+
|
33
|
+
cmd.on :edit do |opt|
|
34
|
+
opt.on :m, "message", "Update the note inline (without opening an editor).", :argument => true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def notes() PryNote.notes ||= {} end
|
39
|
+
def notes=(o) PryNote.notes = o; end
|
40
|
+
|
41
|
+
# edit a note in a temporary file and return note content
|
42
|
+
def edit_note(obj_name, initial_content=nil)
|
43
|
+
initial_content ||= "Enter note content here for #{obj_name} (and erase this line)"
|
44
|
+
temp_file do |f|
|
45
|
+
f.puts(initial_content)
|
46
|
+
f.flush
|
47
|
+
f.close(false)
|
48
|
+
invoke_editor(f.path, 1, false)
|
49
|
+
File.read(f.path)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def process
|
54
|
+
if opts.command?(:add)
|
55
|
+
cmd_opts = opts[:add]
|
56
|
+
add_note(opts.arguments.first, cmd_opts[:message])
|
57
|
+
elsif opts.command?(:show)
|
58
|
+
cmd_opts = opts[:show]
|
59
|
+
stagger_output create_note_output(opts.arguments.first, cmd_opts[:verbose])
|
60
|
+
elsif opts.command?(:list)
|
61
|
+
cmd_opts = opts[:list]
|
62
|
+
if cmd_opts.present?(:verbose)
|
63
|
+
list_all
|
64
|
+
else
|
65
|
+
list_notes
|
66
|
+
end
|
67
|
+
elsif opts.command?(:edit)
|
68
|
+
cmd_opts = opts[:edit]
|
69
|
+
reedit_note(opts.arguments.first, cmd_opts[:message])
|
70
|
+
elsif opts.command?(:export)
|
71
|
+
f = opts.arguments.first
|
72
|
+
PryNote.export_notes(f)
|
73
|
+
output.puts "Exported notes to #{f}"
|
74
|
+
elsif opts.command?(:delete)
|
75
|
+
cmd_opts = opts[:delete]
|
76
|
+
if cmd_opts.present?(:all)
|
77
|
+
notes.replace({})
|
78
|
+
output.puts "Deleted all notes!"
|
79
|
+
else
|
80
|
+
delete_note(opts.arguments.first)
|
81
|
+
end
|
82
|
+
elsif opts.command?(:load)
|
83
|
+
PryNote.load_notes(opts.arguments.first)
|
84
|
+
else
|
85
|
+
output.puts opts.to_s
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def retrieve_code_object_safely(name)
|
90
|
+
code_object = retrieve_code_object_from_string(name, target)
|
91
|
+
|
92
|
+
if !code_object
|
93
|
+
raise Pry::CommandError, "No code object found named #{name}"
|
94
|
+
elsif code_object.name.to_s == ""
|
95
|
+
raise Pry::CommandError, "Object #{name} doesn't have a proper name, can't create note"
|
96
|
+
end
|
97
|
+
|
98
|
+
code_object
|
99
|
+
end
|
100
|
+
|
101
|
+
def default_object_name
|
102
|
+
meth = Pry::Method.from_binding(target)
|
103
|
+
if internal_binding?(target) || !meth
|
104
|
+
obj = target.eval("self")
|
105
|
+
obj_name = obj.is_a?(Module) ? obj.name : obj.class.name
|
106
|
+
obj_name
|
107
|
+
else
|
108
|
+
meth.name_with_owner
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def code_object_name(co)
|
113
|
+
co.is_a?(Pry::Method) ? co.name_with_owner : co.name
|
114
|
+
end
|
115
|
+
|
116
|
+
def add_note(name, message=nil)
|
117
|
+
name ||= default_object_name
|
118
|
+
co_name = code_object_name(retrieve_code_object_safely(name))
|
119
|
+
|
120
|
+
if message
|
121
|
+
note = message
|
122
|
+
else
|
123
|
+
note = edit_note(co_name)
|
124
|
+
end
|
125
|
+
|
126
|
+
notes[co_name] ||= []
|
127
|
+
notes[co_name] << note
|
128
|
+
|
129
|
+
output.puts "Added note to #{co_name}!"
|
130
|
+
end
|
131
|
+
|
132
|
+
def reedit_note(name, message=nil)
|
133
|
+
name, note_number_s = name.split(/:(\d+)$/)
|
134
|
+
co_name = code_object_name(retrieve_code_object_safely(name))
|
135
|
+
raise Pry::CommandError, "No notes to edit!" if !notes[co_name]
|
136
|
+
|
137
|
+
total_notes = notes[co_name].count
|
138
|
+
note_number = note_number_s.to_i
|
139
|
+
|
140
|
+
out = ""
|
141
|
+
if !notes[co_name]
|
142
|
+
out << "No notes to edit for #{co_name}!\n"
|
143
|
+
elsif !note_number_s
|
144
|
+
raise Pry::CommandError, "Must specify a note number. Allowable range is 1-#{total_notes}."
|
145
|
+
elsif note_number < 1 || note_number > total_notes
|
146
|
+
raise Pry::CommandError, "Invalid note number (#{note_number}). Allowable range is 1-#{total_notes}."
|
147
|
+
else
|
148
|
+
if message
|
149
|
+
new_content = message
|
150
|
+
else
|
151
|
+
old_content = notes[co_name][note_number.to_i - 1]
|
152
|
+
new_content = edit_note(co_name, old_content.to_s)
|
153
|
+
end
|
154
|
+
|
155
|
+
notes[co_name][note_number.to_i - 1] = new_content
|
156
|
+
out << "Updated note #{note_number} for #{co_name}!\n"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def delete_note(name)
|
161
|
+
name, note_number = name.split(/:(\d+)$/)
|
162
|
+
co_name = code_object_name(retrieve_code_object_safely(name))
|
163
|
+
|
164
|
+
out = ""
|
165
|
+
if !notes[co_name]
|
166
|
+
out << "No notes to delete for #{co_name}!\n"
|
167
|
+
elsif note_number
|
168
|
+
notes[co_name].delete_at(note_number.to_i - 1)
|
169
|
+
notes.delete(co_name) if notes[co_name].empty?
|
170
|
+
out << "Deleted note #{note_number} for #{co_name}!\n"
|
171
|
+
else
|
172
|
+
notes.delete(co_name)
|
173
|
+
out << "Deleted all notes for #{text.bold(co_name)}!\n"
|
174
|
+
end
|
175
|
+
|
176
|
+
stagger_output out
|
177
|
+
end
|
178
|
+
|
179
|
+
def create_note_output(name, verbose=false)
|
180
|
+
name ||= default_object_name
|
181
|
+
name, _ = name.split(/:(\d+)$/)
|
182
|
+
code_object = retrieve_code_object_safely(name)
|
183
|
+
co_name = code_object_name(code_object)
|
184
|
+
|
185
|
+
raise Pry::CommandError, "Please specify the name of a method or class." if !name
|
186
|
+
|
187
|
+
if !notes.has_key?(co_name)
|
188
|
+
raise Pry::CommandError, "No notes saved for #{text.bold(co_name)}"
|
189
|
+
end
|
190
|
+
|
191
|
+
out = ""
|
192
|
+
out << text.bold("#{co_name}:\n--\n")
|
193
|
+
|
194
|
+
if verbose
|
195
|
+
out << Pry::Code.new(code_object.source, code_object.source_line).with_line_numbers.to_s + "\n"
|
196
|
+
end
|
197
|
+
notes[code_object_name(code_object)].each_with_index do |note, index|
|
198
|
+
out << "\nNote #{text.bold((index + 1).to_s)}: #{note}"
|
199
|
+
end
|
200
|
+
|
201
|
+
out
|
202
|
+
end
|
203
|
+
|
204
|
+
def list_all
|
205
|
+
if notes.any?
|
206
|
+
out = ""
|
207
|
+
out << text.bold("Showing all available notes:\n\n")
|
208
|
+
notes.each do |key, content|
|
209
|
+
begin
|
210
|
+
out << create_note_output(key, true) << "\n"
|
211
|
+
rescue
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
else
|
216
|
+
out << "No notes available.\n"
|
217
|
+
end
|
218
|
+
|
219
|
+
stagger_output out
|
220
|
+
end
|
221
|
+
|
222
|
+
def list_notes
|
223
|
+
if notes.any?
|
224
|
+
out = ""
|
225
|
+
out << text.bold("Showing all available notes:\n\n")
|
226
|
+
notes.each do |key, content|
|
227
|
+
begin
|
228
|
+
if retrieve_code_object_from_string(key, target)
|
229
|
+
out << "#{text.bold(key)} has #{content.count} notes\n"
|
230
|
+
end
|
231
|
+
rescue
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
out << "\nTo view notes for a specific item, e.g: `note show Klass#method`\n"
|
236
|
+
else
|
237
|
+
out << "No notes available.\n"
|
238
|
+
end
|
239
|
+
|
240
|
+
stagger_output out
|
241
|
+
end
|
242
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
reminder = proc do
|
2
|
+
begin
|
3
|
+
co = Pry::Helpers::CommandHelpers.retrieve_code_object_from_string(args.first.to_s, target)
|
4
|
+
co_name = co.is_a?(Pry::Method) ? co.name_with_owner : co.name
|
5
|
+
if PryNote.notes.keys.include?(co_name)
|
6
|
+
output.puts "\n\n#{text.bold("Notes:")}\n--\n\n"
|
7
|
+
|
8
|
+
PryNote.notes[co_name].each_with_index do |note, index|
|
9
|
+
clipped_note = note.lines.count < 3 ? note : note.lines.to_a[0..2].join +
|
10
|
+
text.bold("<...clipped...>") + " Use `note show #{co_name}` to view unelided notes."
|
11
|
+
amended_note = clipped_note.lines.each_with_index.map do |line, idx|
|
12
|
+
idx > 0 ? "#{' ' * ((index + 1).to_s.size + 2)}#{line}" : line
|
13
|
+
end.join
|
14
|
+
output.puts "#{text.bold((index + 1).to_s)}. #{amended_note}"
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
rescue
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Pry.commands.after_command("show-source", &reminder)
|
23
|
+
Pry.commands.after_command("show-doc", &reminder)
|
24
|
+
|
25
|
+
Pry.config.hooks.add_hook(:when_started, :load_notes) do
|
26
|
+
PryNote.load_notes if PryNote.notes.empty?
|
27
|
+
end
|
28
|
+
|
29
|
+
Pry.config.hooks.add_hook(:after_session, :export_notes) do
|
30
|
+
PryNote.export_notes
|
31
|
+
end
|
data/lib/pry-note/version.rb
CHANGED
data/pry-note.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "pry-note"
|
5
|
+
s.version = "0.2.3"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["John Mair (banisterfiend)"]
|
9
|
+
s.date = "2012-12-01"
|
10
|
+
s.description = "Ease refactoring and exploration by attaching notes to methods and classes in Pry"
|
11
|
+
s.email = "jrmair@gmail.com"
|
12
|
+
s.files = ["Rakefile", "lib/pry-note.rb", "lib/pry-note/commands.rb", "lib/pry-note/hooks.rb", "lib/pry-note/version.rb", "pry-note.gemspec", "test/helper.rb", "test/test_pry_note.rb"]
|
13
|
+
s.homepage = "https://github.com/banister"
|
14
|
+
s.require_paths = ["lib"]
|
15
|
+
s.rubygems_version = "1.8.23"
|
16
|
+
s.summary = "Ease refactoring and exploration by attaching notes to methods and classes in Pry"
|
17
|
+
s.test_files = ["test/helper.rb", "test/test_pry_note.rb"]
|
18
|
+
|
19
|
+
if s.respond_to? :specification_version then
|
20
|
+
s.specification_version = 3
|
21
|
+
|
22
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
23
|
+
s.add_development_dependency(%q<rake>, ["~> 0.9"])
|
24
|
+
else
|
25
|
+
s.add_dependency(%q<rake>, ["~> 0.9"])
|
26
|
+
end
|
27
|
+
else
|
28
|
+
s.add_dependency(%q<rake>, ["~> 0.9"])
|
29
|
+
end
|
30
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'pry/test/helper'
|
2
|
+
|
3
|
+
unless Object.const_defined? 'PryNote'
|
4
|
+
$:.unshift File.expand_path '../../lib', __FILE__
|
5
|
+
require 'pry-note'
|
6
|
+
end
|
7
|
+
|
8
|
+
# Ensure file is deleted before and after block
|
9
|
+
def cleanup_file(file_name)
|
10
|
+
f = File.expand_path(file_name)
|
11
|
+
File.unlink(f) if File.exists?(f)
|
12
|
+
yield
|
13
|
+
ensure
|
14
|
+
File.unlink(f) if File.exists?(f)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Return any raised exceptino objects inside the block
|
18
|
+
def capture_exception
|
19
|
+
ex = nil
|
20
|
+
begin
|
21
|
+
yield
|
22
|
+
rescue Exception => e
|
23
|
+
ex = e
|
24
|
+
end
|
25
|
+
ex
|
26
|
+
end
|
@@ -0,0 +1,240 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
# useful test class
|
4
|
+
class PryNote::TestClass
|
5
|
+
def ping
|
6
|
+
binding
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe PryNote do
|
11
|
+
before do
|
12
|
+
Pad.obj = PryNote::TestClass.new
|
13
|
+
@t = pry_tester
|
14
|
+
PryNote.notes = {}
|
15
|
+
Pry.config.notes_file = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
after do
|
19
|
+
Pad.clear
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "note add" do
|
23
|
+
describe "opens an editor when -m flag not provided" do
|
24
|
+
it 'should open the editor' do
|
25
|
+
used_editor = nil
|
26
|
+
Pry.config.editor = proc { used_editor = true; nil }
|
27
|
+
@t.process_command "note add PryNote::TestClass"
|
28
|
+
used_editor.should == true
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should save the note' do
|
32
|
+
Pry.config.editor = proc { nil }
|
33
|
+
@t.process_command "note add PryNote::TestClass"
|
34
|
+
PryNote.notes["PryNote::TestClass"].count.should == 1
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should put default note content in file' do
|
38
|
+
Pry.config.editor = proc { nil }
|
39
|
+
@t.process_command "note add PryNote::TestClass"
|
40
|
+
PryNote.notes["PryNote::TestClass"].first.should =~ /Enter note content here/
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "explicit object" do
|
45
|
+
it 'should add a new note for a method (bound method)' do
|
46
|
+
@t.process_command "note add Pad.obj.ping -m 'my note'"
|
47
|
+
@t.last_output.should =~ /Added note to PryNote::TestClass#ping/
|
48
|
+
PryNote.notes["PryNote::TestClass#ping"].first.should =~ /my note/
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should add a new note for a method (unbound method)' do
|
52
|
+
@t.process_command "note add PryNote::TestClass#ping -m 'my note'"
|
53
|
+
@t.last_output.should =~ /Added note to PryNote::TestClass#ping/
|
54
|
+
PryNote.notes["PryNote::TestClass#ping"].first.should =~ /my note/
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should add a new note for a class' do
|
58
|
+
@t.process_command "note add PryNote::TestClass -m 'my note'"
|
59
|
+
@t.last_output.should =~ /Added note to PryNote::TestClass/
|
60
|
+
PryNote.notes["PryNote::TestClass"].first.should =~ /my note/
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "implicit object" do
|
65
|
+
it 'should add a new note for class of object implicitly (without specifying object)' do
|
66
|
+
@t.process_command "cd 0"
|
67
|
+
@t.process_command "note add -m 'my note'"
|
68
|
+
@t.last_output.should =~ /Added note to Fixnum/
|
69
|
+
PryNote.notes["Fixnum"].first.should =~ /my note/
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should add a new note for a method implicitly (without specifying object)' do
|
73
|
+
o = PryNote::TestClass.new
|
74
|
+
t = pry_tester(o.ping)
|
75
|
+
t.process_command "note add -m 'my note'"
|
76
|
+
t.last_output.should =~ /Added note to PryNote::TestClass#ping/
|
77
|
+
PryNote.notes["PryNote::TestClass#ping"].first.should =~ /my note/
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "multiple notes can be added" do
|
82
|
+
it 'should add multiple notes' do
|
83
|
+
@t.process_command "note add PryNote::TestClass -m 'my note1'"
|
84
|
+
@t.process_command "note add PryNote::TestClass -m 'my note2'"
|
85
|
+
PryNote.notes["PryNote::TestClass"].count.should == 2
|
86
|
+
PryNote.notes["PryNote::TestClass"].first.should =~ /my note1/
|
87
|
+
PryNote.notes["PryNote::TestClass"].last.should =~ /my note2/
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "note delete" do
|
93
|
+
it 'should delete all notes for an object' do
|
94
|
+
@t.process_command "note add PryNote::TestClass -m 'my note'"
|
95
|
+
PryNote.notes["PryNote::TestClass"].count.should == 1
|
96
|
+
@t.process_command "note delete PryNote::TestClass"
|
97
|
+
@t.last_output.should =~ /Deleted all notes for PryNote::TestClass/
|
98
|
+
PryNote.notes["PryNote::TestClass"].should == nil
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should NOT delete notes for unspecified object' do
|
102
|
+
@t.process_command "note add PryNote::TestClass -m 'my note'"
|
103
|
+
@t.process_command "note add PryNote::TestClass#ping -m 'my note'"
|
104
|
+
@t.process_command "note delete PryNote::TestClass"
|
105
|
+
PryNote.notes["PryNote::TestClass#ping"].count.should == 1
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should delete all notes for all objects' do
|
109
|
+
@t.process_command "note add PryNote::TestClass -m 'my note'"
|
110
|
+
@t.process_command "note add PryNote::TestClass#ping -m 'my note'"
|
111
|
+
PryNote.notes.keys.count.should == 2
|
112
|
+
@t.process_command "note delete --all"
|
113
|
+
@t.last_output.should =~ /Deleted all notes/
|
114
|
+
PryNote.notes.empty?.should == true
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "deleting specific notes for an object" do
|
118
|
+
it 'should delete first note for an object' do
|
119
|
+
@t.process_command "note add PryNote::TestClass -m 'my note1'"
|
120
|
+
@t.process_command "note add PryNote::TestClass -m 'my note2'"
|
121
|
+
PryNote.notes["PryNote::TestClass"].count.should == 2
|
122
|
+
@t.process_command "note delete PryNote::TestClass:1"
|
123
|
+
@t.last_output.should =~ /Deleted note 1 for PryNote::TestClass/
|
124
|
+
PryNote.notes["PryNote::TestClass"].count.should == 1
|
125
|
+
PryNote.notes["PryNote::TestClass"].first.should =~ /my note2/
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should delete middle note for an object' do
|
129
|
+
@t.process_command "note add PryNote::TestClass -m 'my note1'"
|
130
|
+
@t.process_command "note add PryNote::TestClass -m 'my note2'"
|
131
|
+
@t.process_command "note add PryNote::TestClass -m 'my note3'"
|
132
|
+
PryNote.notes["PryNote::TestClass"].count.should == 3
|
133
|
+
@t.process_command "note delete PryNote::TestClass:2"
|
134
|
+
@t.last_output.should =~ /Deleted note 2 for PryNote::TestClass/
|
135
|
+
PryNote.notes["PryNote::TestClass"].count.should == 2
|
136
|
+
PryNote.notes["PryNote::TestClass"].first.should =~ /my note1/
|
137
|
+
PryNote.notes["PryNote::TestClass"].last.should =~ /my note3/
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "note edit" do
|
143
|
+
describe "errors" do
|
144
|
+
it 'should error when not given a note number' do
|
145
|
+
@t.process_command "note add PryNote::TestClass -m 'my note1'"
|
146
|
+
|
147
|
+
capture_exception do
|
148
|
+
@t.process_command "note edit PryNote::TestClass -m 'bing'"
|
149
|
+
end.message.should =~ /Must specify a note number/
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should error when given out of range note number' do
|
153
|
+
@t.process_command "note add PryNote::TestClass -m 'my note1'"
|
154
|
+
|
155
|
+
capture_exception do
|
156
|
+
@t.process_command "note edit PryNote::TestClass:2 -m 'bing'"
|
157
|
+
end.message.should =~ /Invalid note number/
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should error when editing object with no notes' do
|
161
|
+
capture_exception do
|
162
|
+
@t.process_command "note edit PryNote::TestClass:2 -m 'bing'"
|
163
|
+
end.message.should =~ /No notes to edit/
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe "-m switch" do
|
168
|
+
it 'should amend the content of a note' do
|
169
|
+
@t.process_command "note add PryNote::TestClass -m 'my note1'"
|
170
|
+
@t.process_command "note edit PryNote::TestClass:1 -m 'bing'"
|
171
|
+
PryNote.notes["PryNote::TestClass"].count.should == 1
|
172
|
+
PryNote.notes["PryNote::TestClass"].first.should =~ /bing/
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "note show" do
|
178
|
+
it 'should display method source when -v flag is used' do
|
179
|
+
@t.process_command "note add PryNote::TestClass -m 'my note1'"
|
180
|
+
@t.process_command "note show PryNote::TestClass -v"
|
181
|
+
@t.last_output.should =~ /ping/
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'should just display number of notes by default' do
|
185
|
+
@t.process_command "note add PryNote::TestClass -m 'my note1'"
|
186
|
+
@t.process_command "note add PryNote::TestClass -m 'my note2'"
|
187
|
+
@t.process_command "note show PryNote::TestClass"
|
188
|
+
@t.last_output.should =~ /2/
|
189
|
+
@t.last_output.should.not =~ /ping/
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'should ignore :number suffix (as used in edit and delete)' do
|
193
|
+
@t.process_command "note add PryNote::TestClass -m 'my note2'"
|
194
|
+
@t.process_command "note show PryNote::TestClass:99"
|
195
|
+
@t.last_output.should =~ /1/
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should implicitly display notes for current object (class)' do
|
199
|
+
@t.process_command "note add PryNote::TestClass -m 'my note1'"
|
200
|
+
@t.process_command "note add PryNote::TestClass -m 'my note2'"
|
201
|
+
@t.process_command "cd PryNote::TestClass"
|
202
|
+
@t.process_command "note show -v"
|
203
|
+
@t.last_output.should =~ /ping/
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'should implicitly display notes for current object (method)' do
|
207
|
+
t = pry_tester(Pad.obj.ping)
|
208
|
+
t.process_command "note add PryNote::TestClass#ping -m 'my note1'"
|
209
|
+
t.process_command "note add PryNote::TestClass#ping -m 'my note2'"
|
210
|
+
t.process_command "note show -v"
|
211
|
+
t.last_output.should =~ /binding/
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe "note export" do
|
216
|
+
it 'should export to Pry.config.notes_file by default' do
|
217
|
+
cleanup_file("bing.yml") do
|
218
|
+
Pry.config.notes_file = "bing.yml"
|
219
|
+
@t.process_command "note add PryNote::TestClass -m 'my note1'"
|
220
|
+
@t.process_command "note add PryNote::TestClass -m 'my note2'"
|
221
|
+
@t.process_command "note export"
|
222
|
+
|
223
|
+
o = YAML.load(File.read("bing.yml"))
|
224
|
+
o["PryNote::TestClass"].should == ['my note1', 'my note2']
|
225
|
+
|
226
|
+
Pry.config.notes_file = nil
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'should export to specified file' do
|
231
|
+
cleanup_file("blah.yml") do
|
232
|
+
@t.process_command "note add PryNote::TestClass -m 'my note1'"
|
233
|
+
@t.process_command "note add PryNote::TestClass -m 'my note2'"
|
234
|
+
@t.process_command "note export blah.yml"
|
235
|
+
o = YAML.load(File.read("blah.yml"))
|
236
|
+
o["PryNote::TestClass"].should == ['my note1', 'my note2']
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pry-note
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -36,7 +36,12 @@ extra_rdoc_files: []
|
|
36
36
|
files:
|
37
37
|
- Rakefile
|
38
38
|
- lib/pry-note.rb
|
39
|
+
- lib/pry-note/commands.rb
|
40
|
+
- lib/pry-note/hooks.rb
|
39
41
|
- lib/pry-note/version.rb
|
42
|
+
- pry-note.gemspec
|
43
|
+
- test/helper.rb
|
44
|
+
- test/test_pry_note.rb
|
40
45
|
homepage: https://github.com/banister
|
41
46
|
licenses: []
|
42
47
|
post_install_message:
|
@@ -62,4 +67,6 @@ signing_key:
|
|
62
67
|
specification_version: 3
|
63
68
|
summary: Ease refactoring and exploration by attaching notes to methods and classes
|
64
69
|
in Pry
|
65
|
-
test_files:
|
70
|
+
test_files:
|
71
|
+
- test/helper.rb
|
72
|
+
- test/test_pry_note.rb
|