byebug 2.7.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -6
- data/.travis.yml +1 -0
- data/CHANGELOG.md +23 -0
- data/Gemfile +9 -0
- data/README.md +35 -32
- data/Rakefile +1 -3
- data/byebug.gemspec +0 -6
- data/ext/byebug/byebug.c +64 -51
- data/ext/byebug/byebug.h +12 -13
- data/ext/byebug/context.c +28 -43
- data/ext/byebug/extconf.rb +6 -6
- data/lib/byebug.rb +34 -38
- data/lib/byebug/command.rb +4 -2
- data/lib/byebug/commands/continue.rb +0 -1
- data/lib/byebug/commands/control.rb +0 -1
- data/lib/byebug/commands/edit.rb +1 -1
- data/lib/byebug/commands/finish.rb +10 -16
- data/lib/byebug/commands/help.rb +1 -1
- data/lib/byebug/commands/kill.rb +1 -1
- data/lib/byebug/commands/quit.rb +1 -1
- data/lib/byebug/commands/repl.rb +3 -3
- data/lib/byebug/commands/set.rb +24 -39
- data/lib/byebug/commands/show.rb +39 -112
- data/lib/byebug/commands/stepping.rb +0 -2
- data/lib/byebug/commands/threads.rb +0 -5
- data/lib/byebug/commands/trace.rb +1 -1
- data/lib/byebug/commands/variables.rb +1 -1
- data/lib/byebug/context.rb +8 -12
- data/lib/byebug/helper.rb +1 -1
- data/lib/byebug/history.rb +46 -0
- data/lib/byebug/interface.rb +5 -5
- data/lib/byebug/interfaces/local_interface.rb +11 -62
- data/lib/byebug/interfaces/remote_interface.rb +6 -22
- data/lib/byebug/interfaces/script_interface.rb +2 -17
- data/lib/byebug/processor.rb +4 -4
- data/lib/byebug/{command_processor.rb → processors/command_processor.rb} +7 -14
- data/lib/byebug/{control_command_processor.rb → processors/control_command_processor.rb} +3 -7
- data/lib/byebug/version.rb +1 -1
- data/test/edit_test.rb +6 -6
- data/test/examples/breakpoint_deep.rb +1 -1
- data/test/finish_test.rb +6 -6
- data/test/help_test.rb +1 -1
- data/test/info_test.rb +0 -1
- data/test/kill_test.rb +2 -2
- data/test/post_mortem_test.rb +35 -219
- data/test/quit_test.rb +2 -2
- data/test/restart_test.rb +12 -33
- data/test/set_test.rb +80 -107
- data/test/show_test.rb +42 -77
- data/test/stepping_test.rb +1 -1
- data/test/support/test_dsl.rb +4 -25
- data/test/support/test_interface.rb +40 -48
- data/test/test_helper.rb +1 -3
- data/test/timeout_test.rb +9 -0
- metadata +8 -75
data/lib/byebug/commands/set.rb
CHANGED
@@ -23,41 +23,29 @@ module Byebug
|
|
23
23
|
end
|
24
24
|
when /^verbose$/
|
25
25
|
Byebug.verbose = setting_value
|
26
|
-
when /^
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
sub_sub_cmd = setting_args[1]
|
33
|
-
iface = @state.interface
|
34
|
-
case subcmd.name
|
35
|
-
when /^save$/
|
36
|
-
iface.history_save = sub_sub_cmd ? get_onoff(sub_sub_cmd) : true
|
37
|
-
when /^size$/
|
38
|
-
return print 'You need to specify the history size' unless sub_sub_cmd
|
39
|
-
iface.history_length = get_int(sub_sub_cmd, "Set history size")
|
40
|
-
when /^filename$/
|
41
|
-
return print 'You need to specify a filename' unless sub_sub_cmd
|
42
|
-
iface.histfile = File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", sub_sub_cmd)
|
43
|
-
end
|
26
|
+
when /^histfile$/
|
27
|
+
return print 'You need to specify a filename' unless setting_args[0]
|
28
|
+
Byebug::History.file = File.expand_path(setting_args[0])
|
29
|
+
when /^histsize$/
|
30
|
+
return print 'You need to specify the history size' unless setting_args[0]
|
31
|
+
Byebug::History.max_size = get_int(setting_args[0], "Set histsize")
|
44
32
|
when /^linetrace$/
|
45
33
|
Byebug.tracing = setting_value
|
46
34
|
when /^listsize$/
|
47
|
-
listsize = get_int(setting_args[0],
|
35
|
+
listsize = get_int(setting_args[0], 'Set listsize', 1, nil, 10)
|
48
36
|
return unless listsize
|
49
37
|
Command.settings[:listsize] = listsize
|
50
38
|
when /^width$/
|
51
|
-
return unless width = get_int(setting_args[0],
|
39
|
+
return unless width = get_int(setting_args[0], 'Set width', 10, nil, 80)
|
52
40
|
Command.settings[:width] = width
|
53
41
|
when /^post_mortem$/
|
54
42
|
if setting_value == true
|
55
43
|
Byebug.post_mortem
|
56
44
|
else
|
57
|
-
|
45
|
+
Byebug.post_mortem = false
|
58
46
|
end
|
59
|
-
when /^autoeval|autoreload|basename|forcestep|fullpath|
|
60
|
-
testing|stack_on_error$/x
|
47
|
+
when /^autoeval|autoreload|autosave|basename|forcestep|fullpath|
|
48
|
+
linetrace_plus|testing|stack_on_error$/x
|
61
49
|
Command.settings[setting_name.to_sym] = setting_value
|
62
50
|
else
|
63
51
|
return print "Unknown setting #{@match[1]}.\n"
|
@@ -72,21 +60,25 @@ module Byebug
|
|
72
60
|
Subcommands = [
|
73
61
|
['args' , 2 , false, 'Set argument list to the program ' \
|
74
62
|
'being debugged when it is started' ],
|
75
|
-
['autoeval' ,
|
76
|
-
['autolist' ,
|
63
|
+
['autoeval' , 5 , true , 'Evaluate every unrecognized command' ],
|
64
|
+
['autolist' , 5 , true , 'Execute "list" command on every ' \
|
77
65
|
'breakpoint' ],
|
78
|
-
['autoirb' ,
|
79
|
-
['autoreload' ,
|
66
|
+
['autoirb' , 5 , true , 'Invoke IRB on every stop' ],
|
67
|
+
['autoreload' , 5 , true , 'Reload source code when changed' ],
|
68
|
+
['autosave' , 5 , true , 'Automatically save command history ' \
|
69
|
+
'record on exit' ],
|
80
70
|
['basename' , 1 , true , 'Set filename display style' ],
|
81
71
|
['callstyle' , 2 , false, 'Set how you want call parameters ' \
|
82
72
|
'displayed' ],
|
83
|
-
['testing' , 2 , false, 'Used when testing byebug' ],
|
84
73
|
['forcestep' , 2 , true , 'Make sure "next/step" commands always' \
|
85
74
|
'move to a new line' ],
|
86
75
|
['fullpath' , 2 , true , 'Display full file names in frames' ],
|
87
|
-
['
|
88
|
-
'
|
89
|
-
'
|
76
|
+
['histfile' , 5 , false, 'Customize file where history is ' \
|
77
|
+
'loaded from and saved to. By ' \
|
78
|
+
'default, .byebug_hist' ],
|
79
|
+
['histsize' , 5 , false, 'Customize maximum number of commands ' \
|
80
|
+
'that are stored in byebug history ' \
|
81
|
+
'record. By default, 256' ],
|
90
82
|
['linetrace' , 3 , true , 'Enable line execution tracing' ],
|
91
83
|
['linetrace_plus', 10, true , 'Set line execution tracing to show' \
|
92
84
|
'different lines' ],
|
@@ -95,6 +87,7 @@ module Byebug
|
|
95
87
|
['post_mortem' , 2 , true , 'Enable post-mortem mode' ],
|
96
88
|
['stack_on_error', 1 , true , 'Display stack trace when "eval" ' \
|
97
89
|
'raises exception' ],
|
90
|
+
['testing' , 2 , false, 'Used when testing byebug' ],
|
98
91
|
['verbose' , 1 , true , 'Enable verbose output of TracePoint ' \
|
99
92
|
'API events is enabled' ],
|
100
93
|
['width' , 1 , false, 'Number of characters per line for ' \
|
@@ -103,14 +96,6 @@ module Byebug
|
|
103
96
|
Subcmd2.new(name, min, is_bool, help)
|
104
97
|
end unless defined?(Subcommands)
|
105
98
|
|
106
|
-
SetHistorySubcommands = [
|
107
|
-
['filename', 1, 'Set the filename in which to record command history'],
|
108
|
-
['save' , 1, 'Set saving of the history record on exit' ],
|
109
|
-
['size' , 1, 'Set the size of the command history' ]
|
110
|
-
].map do |name, min, help|
|
111
|
-
Subcmd.new(name, min, help)
|
112
|
-
end unless defined?(SetHistorySubcommands)
|
113
|
-
|
114
99
|
self.allow_in_control = true
|
115
100
|
|
116
101
|
def regexp
|
data/lib/byebug/commands/show.rb
CHANGED
@@ -17,129 +17,60 @@ module Byebug
|
|
17
17
|
else
|
18
18
|
args = ''
|
19
19
|
end
|
20
|
-
|
20
|
+
"Argument list to give program being debugged when it is started is \"#{args}\"."
|
21
21
|
when /^autolist$/
|
22
|
-
|
23
|
-
return "autolist is #{show_onoff(on_off)}."
|
24
|
-
when /^autoeval$/
|
25
|
-
on_off = Command.settings[:autoeval]
|
26
|
-
return "autoeval is #{show_onoff(on_off)}."
|
27
|
-
when /^autoreload$/
|
28
|
-
on_off = Command.settings[:autoreload]
|
29
|
-
return "autoreload is #{show_onoff(on_off)}."
|
22
|
+
"autolist is #{show_onoff(Command.settings[:autolist] > 0)}."
|
30
23
|
when /^autoirb$/
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
on_off = Command.settings[:basename]
|
35
|
-
return "basename is #{show_onoff(on_off)}."
|
24
|
+
"autoirb is #{show_onoff(Command.settings[:autoirb] > 0)}."
|
25
|
+
when /^autosave$/
|
26
|
+
"Saving history is #{show_onoff(Command.settings[:autosave])}."
|
36
27
|
when /^callstyle$/
|
37
|
-
style
|
38
|
-
return "Frame call-display style is #{style}."
|
28
|
+
"Frame call-display style is #{Command.settings[:callstyle]}."
|
39
29
|
when /^commands(:?\s+(\d+))?$/
|
40
|
-
if
|
41
|
-
|
30
|
+
if Command.settings[:autosave]
|
31
|
+
history = Byebug::History
|
42
32
|
args = @match[1].split
|
43
33
|
if args[1]
|
44
|
-
|
45
|
-
last_line = first_line + 10 - 1
|
46
|
-
if first_line > Readline::HISTORY.length
|
47
|
-
first_line = last_line = Readline::HISTORY.length
|
48
|
-
elsif first_line <= 0
|
49
|
-
first_line = 1
|
50
|
-
end
|
51
|
-
if last_line > Readline::HISTORY.length
|
52
|
-
last_line = Readline::HISTORY.length
|
53
|
-
end
|
54
|
-
i = first_line
|
55
|
-
commands = Readline::HISTORY.to_a[first_line..last_line]
|
56
|
-
else
|
57
|
-
if Readline::HISTORY.length > 10
|
58
|
-
commands = Readline::HISTORY.to_a[-10..-1]
|
59
|
-
i = Readline::HISTORY.length - 10
|
60
|
-
else
|
61
|
-
commands = Readline::HISTORY.to_a
|
62
|
-
i = 1
|
63
|
-
end
|
64
|
-
end
|
65
|
-
commands.each do |cmd|
|
66
|
-
s += ("%5d %s\n" % [i, cmd])
|
67
|
-
i += 1
|
34
|
+
size = get_int(args[1], 'show commands', 1, history.max_size)
|
68
35
|
end
|
36
|
+
size ? history.to_s(size) : history.to_s
|
69
37
|
else
|
70
|
-
|
38
|
+
'Not currently saving history. Enable it with "set autosave"'
|
71
39
|
end
|
72
|
-
return s
|
73
40
|
when /^testing$/
|
74
|
-
|
75
|
-
return "Currently testing byebug is #{show_onoff(on_off)}."
|
41
|
+
"Currently testing byebug is #{show_onoff(Command.settings[:testing])}."
|
76
42
|
when /^forcestep$/
|
77
|
-
|
78
|
-
return "force-stepping is #{show_onoff(on_off)}."
|
43
|
+
"force-stepping is #{show_onoff(Command.settings[:forcestep])}."
|
79
44
|
when /^fullpath$/
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
if args[1]
|
86
|
-
show_save = show_size = show_filename = false
|
87
|
-
prefix = false
|
88
|
-
if args[1] == "save"
|
89
|
-
show_save = true
|
90
|
-
elsif args[1] == "size"
|
91
|
-
show_size = true
|
92
|
-
elsif args[1] == "filename"
|
93
|
-
show_filename = true
|
94
|
-
end
|
95
|
-
else
|
96
|
-
show_save = show_size = show_filename = true
|
97
|
-
prefix = true
|
98
|
-
end
|
99
|
-
s = []
|
100
|
-
if show_filename
|
101
|
-
msg = "#{prefix ? 'filename:' : ''} The command history file is " \
|
102
|
-
"#{interface.histfile.inspect}"
|
103
|
-
s << msg
|
104
|
-
end
|
105
|
-
if show_save
|
106
|
-
msg = (prefix ? "save: " : "") +
|
107
|
-
"Saving of history save is #{show_onoff(interface.history_save)}."
|
108
|
-
s << msg
|
109
|
-
end
|
110
|
-
if show_size
|
111
|
-
msg = (prefix ? "size: " : "") +
|
112
|
-
"Byebug history size is #{interface.history_length}"
|
113
|
-
s << msg
|
114
|
-
end
|
115
|
-
return s.join("\n")
|
45
|
+
"Displaying frame's full file names is #{show_onoff(Command.settings[:fullpath])}."
|
46
|
+
when /^histfile$/
|
47
|
+
"The command history file is \"#{Byebug::History.file}\""
|
48
|
+
when /^histsize$/
|
49
|
+
"Byebug history's maximum size is #{Byebug::History.max_size}"
|
116
50
|
when /^linetrace$/
|
117
|
-
|
118
|
-
return "line tracing is #{show_onoff(on_off)}."
|
51
|
+
"line tracing is #{show_onoff(Byebug.tracing?)}."
|
119
52
|
when /^linetrace_plus$/
|
120
53
|
if Command.settings[:linetrace_plus]
|
121
|
-
|
54
|
+
'line tracing style is every line.'
|
122
55
|
else
|
123
|
-
|
56
|
+
'line tracing style is different consecutive lines.'
|
124
57
|
end
|
125
58
|
when /^listsize$/
|
126
|
-
|
127
|
-
return "Number of source lines to list is #{listlines}."
|
59
|
+
"Number of source lines to list is #{Command.settings[:listsize]}."
|
128
60
|
when /^post_mortem$/
|
129
|
-
|
130
|
-
return "post-mortem mode is #{show_onoff(on_off)}"
|
61
|
+
"Post-mortem mode is #{show_onoff(Byebug.post_mortem?)}"
|
131
62
|
when /^stack_on_error$/
|
132
|
-
|
133
|
-
return "Displaying stack trace is #{show_onoff(on_off)}."
|
63
|
+
"Displaying stack trace is #{show_onoff(Command.settings[:stack_on_error])}."
|
134
64
|
when /^verbose$/
|
135
|
-
|
136
|
-
return "Verbose output of TracePoint API events is #{show_onoff(on_off)}."
|
65
|
+
"Verbose output of TracePoint API events is #{show_onoff(Byebug.verbose)}."
|
137
66
|
when /^version$/
|
138
|
-
|
67
|
+
"Byebug #{Byebug::VERSION}"
|
139
68
|
when /^width$/
|
140
|
-
|
69
|
+
"Width is #{Command.settings[:width]}."
|
70
|
+
when /^autoeval|autoreload|basename$/x
|
71
|
+
"#{setting_name} is #{show_onoff(Command.settings[setting_name.to_sym])}."
|
141
72
|
else
|
142
|
-
|
73
|
+
"Unknown show subcommand #{setting_name}."
|
143
74
|
end
|
144
75
|
end
|
145
76
|
end
|
@@ -150,12 +81,14 @@ module Byebug
|
|
150
81
|
Subcommands = [
|
151
82
|
['args' , 2 , 'Show argument list to the program being ' \
|
152
83
|
'debugged when it is started' ],
|
153
|
-
['autoeval' ,
|
84
|
+
['autoeval' , 5 , 'Show whether unrecognized commands are ' \
|
154
85
|
'evaluated' ],
|
155
|
-
['autolist' ,
|
156
|
-
['autoirb' ,
|
157
|
-
['autoreload' ,
|
86
|
+
['autolist' , 5 , 'Show whether "list" command is run on stopping' ],
|
87
|
+
['autoirb' , 5 , 'Show whether IRB is invoked on stopping' ],
|
88
|
+
['autoreload' , 5 , 'Show whether source code is reloaded when ' \
|
158
89
|
'changed' ],
|
90
|
+
['autosave' , 5 , 'Show whether command history is ' \
|
91
|
+
'automatically saved on exit' ],
|
159
92
|
['basename' , 1 , 'Show whether basename is used when reporting' \
|
160
93
|
' files' ],
|
161
94
|
['callstyle' , 2 , 'Show parameter style used when showing call' \
|
@@ -165,7 +98,9 @@ module Byebug
|
|
165
98
|
['forcestep' , 1 , 'Show whether "next/step" commands are set to' \
|
166
99
|
' always move to a line' ],
|
167
100
|
['fullpath' , 2 , 'Show whether full paths are displayed in frames'],
|
168
|
-
['
|
101
|
+
['histfile' , 5 , 'File where byebug save history of commands' ],
|
102
|
+
['histsize' , 5 , 'Maximum number of commands stored in ' \
|
103
|
+
'byebug\'s history' ],
|
169
104
|
['linetrace' , 3 , 'Show line execution tracing status' ],
|
170
105
|
['linetrace_plus', 10, 'Show whether different consecutive lines are' \
|
171
106
|
' shown in tracing' ],
|
@@ -183,14 +118,6 @@ module Byebug
|
|
183
118
|
Subcmd.new(name, min, help)
|
184
119
|
end unless defined?(Subcommands)
|
185
120
|
|
186
|
-
ShowHistorySubcommands = [
|
187
|
-
['filename', 1, 'Show the filename in which to record command history' ],
|
188
|
-
['save' , 1, 'Show whether history record should be saved on exit' ],
|
189
|
-
['size' , 1, 'Show the size of the command history' ]
|
190
|
-
].map do |name, min, help|
|
191
|
-
Subcmd.new(name, min, help)
|
192
|
-
end unless defined?(SetHistorySubcommands)
|
193
|
-
|
194
121
|
self.allow_in_control = true
|
195
122
|
|
196
123
|
def regexp
|
@@ -18,7 +18,6 @@ module Byebug
|
|
18
18
|
# Implements byebug "next" command.
|
19
19
|
class NextCommand < Command
|
20
20
|
self.allow_in_post_mortem = false
|
21
|
-
self.need_context = true
|
22
21
|
|
23
22
|
def regexp
|
24
23
|
/^\s* n(?:ext)?([+-])? (?:\s+(\S+))? \s*$/x
|
@@ -48,7 +47,6 @@ module Byebug
|
|
48
47
|
# Implements byebug "step" command.
|
49
48
|
class StepCommand < Command
|
50
49
|
self.allow_in_post_mortem = false
|
51
|
-
self.need_context = true
|
52
50
|
|
53
51
|
def regexp
|
54
52
|
/^\s* s(?:tep)?([+-]) ?(?:\s+(\S+))? \s*$/x
|
@@ -90,8 +90,6 @@ module Byebug
|
|
90
90
|
end
|
91
91
|
|
92
92
|
class ThreadCurrentCommand < Command
|
93
|
-
self.need_context = true
|
94
|
-
|
95
93
|
def regexp
|
96
94
|
/^\s* th(?:read)? \s+ (?:cur(?:rent)?)? \s*$/x
|
97
95
|
end
|
@@ -114,7 +112,6 @@ module Byebug
|
|
114
112
|
class ThreadStopCommand < Command
|
115
113
|
self.allow_in_control = true
|
116
114
|
self.allow_in_post_mortem = false
|
117
|
-
self.need_context = true
|
118
115
|
|
119
116
|
def regexp
|
120
117
|
/^\s* th(?:read)? \s+ stop \s* (\S*) \s*$/x
|
@@ -141,7 +138,6 @@ module Byebug
|
|
141
138
|
class ThreadResumeCommand < Command
|
142
139
|
self.allow_in_control = true
|
143
140
|
self.allow_in_post_mortem = false
|
144
|
-
self.need_context = true
|
145
141
|
|
146
142
|
def regexp
|
147
143
|
/^\s* th(?:read)? \s+ resume \s* (\S*) \s*$/x
|
@@ -172,7 +168,6 @@ module Byebug
|
|
172
168
|
class ThreadSwitchCommand < Command
|
173
169
|
self.allow_in_control = true
|
174
170
|
self.allow_in_post_mortem = false
|
175
|
-
self.need_context = true
|
176
171
|
|
177
172
|
def regexp
|
178
173
|
/^\s* th(?:read)? \s+ (?:sw(?:itch)?\s+)? (\S+) \s*$/x
|
@@ -19,7 +19,7 @@ module Byebug
|
|
19
19
|
if @match[3] && @match[3] !~ /(:?no)?stop/
|
20
20
|
errmsg "expecting \"stop\" or \"nostop\"; got \"#{@match[3]}\"\n"
|
21
21
|
else
|
22
|
-
dbg_cmd = (@match[3] && @match[3] !~ /nostop/) ? 'byebug(1,
|
22
|
+
dbg_cmd = (@match[3] && @match[3] !~ /nostop/) ? 'byebug(1, false)' : ''
|
23
23
|
end
|
24
24
|
eval("trace_var(:\"\$#{varname}\") do |val|
|
25
25
|
print \"traced global variable '#{varname}' has value '\#{val}'\"\n
|
data/lib/byebug/context.rb
CHANGED
@@ -3,24 +3,20 @@ module Byebug
|
|
3
3
|
class Context
|
4
4
|
|
5
5
|
class << self
|
6
|
-
def stack_size
|
6
|
+
def stack_size(byebug_frames = false)
|
7
7
|
if backtrace = Thread.current.backtrace_locations(0)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
unless byebug_frames
|
9
|
+
backtrace = backtrace.drop_while { |l| !ignored(l.path) }
|
10
|
+
.drop_while { |l| ignored(l.path) }
|
11
|
+
.take_while { |l| !ignored(l.path) }
|
12
|
+
end
|
13
|
+
backtrace.size
|
12
14
|
else
|
13
|
-
print 'No backtrace available!!'
|
15
|
+
print 'WARNING: No backtrace available!!'
|
14
16
|
0
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
18
|
-
def real_stack_size
|
19
|
-
if backtrace = Thread.current.backtrace_locations(0)
|
20
|
-
backtrace.size
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
20
|
def ignored(path)
|
25
21
|
IGNORED_FILES.include?(path)
|
26
22
|
end
|
data/lib/byebug/helper.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'readline'
|
2
|
+
|
3
|
+
module Byebug
|
4
|
+
class History
|
5
|
+
DEFAULT_FILE = File.expand_path("#{ENV['HOME']||'.'}/.byebug_hist")
|
6
|
+
DEFAULT_MAX_SIZE = 256
|
7
|
+
|
8
|
+
@file = DEFAULT_FILE
|
9
|
+
@max_size = DEFAULT_MAX_SIZE
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_accessor :file, :max_size
|
13
|
+
|
14
|
+
def load
|
15
|
+
open(@file, 'r') do |file|
|
16
|
+
file.each do |line|
|
17
|
+
line.chomp!
|
18
|
+
Readline::HISTORY << line
|
19
|
+
end
|
20
|
+
end if File.exist?(@file)
|
21
|
+
end
|
22
|
+
|
23
|
+
def save
|
24
|
+
open(@file, 'w') do |file|
|
25
|
+
Readline::HISTORY.to_a.last(@max_size).each do |line|
|
26
|
+
file.puts line unless line.strip.empty?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s(size = @max_size)
|
32
|
+
n_entries = Readline::HISTORY.length < size ? Readline::HISTORY.length : size
|
33
|
+
|
34
|
+
first = Readline::HISTORY.length - n_entries
|
35
|
+
commands = Readline::HISTORY.to_a.last(n_entries)
|
36
|
+
|
37
|
+
s = ''
|
38
|
+
commands.each_with_index do |command, index|
|
39
|
+
s += ("%5d %s\n" % [first + index + 1, command])
|
40
|
+
end
|
41
|
+
|
42
|
+
return s
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|