diff --git a/lib/pry/commands/exit_program.rb b/lib/pry/commands/exit_program.rb index 50731b05..2e8fc47f 100644 --- a/lib/pry/commands/exit_program.rb +++ b/lib/pry/commands/exit_program.rb @@ -5,7 +5,6 @@ class Pry description 'End the current program. Aliases: quit-program, !!!' def process - Pry.save_history if Pry.config.history.should_save Kernel.exit target.eval(arg_string).to_i end end diff --git a/lib/pry/history.rb b/lib/pry/history.rb index df50df21..f8d0020e 100644 --- a/lib/pry/history.rb +++ b/lib/pry/history.rb @@ -7,17 +7,16 @@ class Pry # @return [Fixnum] Number of lines in history when Pry first loaded. attr_reader :original_lines - def initialize + def initialize(options={}) @history = [] - @saved_lines = 0 @original_lines = 0 + @file_path = options[:file_path] restore_default_behavior end # Assign the default methods for loading, saving, pushing, and clearing. def restore_default_behavior @loader = method(:read_from_file) - @saver = method(:write_to_file) @pusher = method(:push_to_readline) @clearer = method(:clear_readline) end @@ -26,19 +25,9 @@ class Pry # @return [Integer] The number of lines loaded def load @loader.call do |line| - @pusher.call(line.chomp) + Readline::HISTORY << line.chomp @history << line.chomp end - @saved_lines = @original_lines = @history.length - end - - # Write this session's history using `History.saver`. - # @return [Integer] The number of lines saved - def save - history_to_save = @history[@saved_lines..-1] - @saver.call(history_to_save) - @saved_lines = @history.length - history_to_save.length end # Add a line to the input history, ignoring blank and duplicate lines. @@ -48,6 +37,7 @@ class Pry unless line.empty? || (@history.last && line == @history.last) @pusher.call(line) @history << line + @history_file.puts line if save_history? end line end @@ -59,7 +49,6 @@ class Pry def clear @clearer.call @history = [] - @saved_lines = 0 end # @return [Fixnum] The number of lines in history. @@ -96,15 +85,9 @@ class Pry # The default saver. Appends the given lines to `Pry.history.config.file`. # @param [Array] lines def write_to_file(lines) - history_file = File.expand_path(Pry.config.history.file) - - begin - File.open(history_file, 'a') do |f| - lines.each { |ln| f.puts ln } - end - rescue Errno::EACCES - # We should probably create an option Pry.show_warnings?!?!?! - warn 'Unable to write to your history file, history not saved' + if write_to_history? + history_file.close + @history_file = nil end end @@ -118,5 +101,28 @@ class Pry def clear_readline Readline::HISTORY.shift until Readline::HISTORY.empty? end + + # The history file for appending + def history_file + if @history_file.nil? + begin + @history_file ||= File.open(file_path, 'a') + @history_file.sync = true + rescue Errno::EACCES + # We should probably create an option Pry.show_warnings?!?!?! + warn 'Unable to write to your history file, history not saved' + @history_file = false + end + end + @history_file + end + + def save_history? + Pry.config.history.should_save && history_file + end + + def file_path + @file_path || Pry.config.history.file + end end end diff --git a/lib/pry/pry_class.rb b/lib/pry/pry_class.rb index c399c78a..fdeac8f9 100644 --- a/lib/pry/pry_class.rb +++ b/lib/pry/pry_class.rb @@ -191,11 +191,6 @@ class Pry Pry.history.load end - # Save new lines of Readline history if required. - def self.save_history - Pry.history.save - end - # @return [Boolean] Whether this is the first time a Pry session has # been started since loading the Pry class. def self.initial_session? diff --git a/lib/pry/repl.rb b/lib/pry/repl.rb index 4f695ee0..28066995 100644 --- a/lib/pry/repl.rb +++ b/lib/pry/repl.rb @@ -76,8 +76,6 @@ class Pry # Clean-up after the repl session. def epilogue pry.exec_hook :after_session, pry.output, pry.current_binding, pry - - Pry.save_history if Pry.config.history.should_save end # Read a line of input from the user, special handling for: diff --git a/spec/pry_history_spec.rb b/spec/pry_history_spec.rb index 15efe495..3d48483b 100644 --- a/spec/pry_history_spec.rb +++ b/spec/pry_history_spec.rb @@ -11,10 +11,6 @@ describe Pry do @saved_history.lines.each { |l| blk.call(l) } end - Pry.history.saver = proc do |lines| - @saved_history << lines.map { |l| "#{l}\n" }.join - end - Pry.load_history end @@ -44,56 +40,30 @@ describe Pry do end end - describe ".save_history" do - it "should include a trailing newline" do - Pry.history << "4" - Pry.save_history - @saved_history.should =~ /4\n\z/ + describe "saving to a file" do + before do + @histfile = Tempfile.new(["pryhistory", "txt"]) + @history = Pry::History.new(:file_path => @histfile.path) + Pry.config.history.should_save = true + @history.pusher = proc{ } end - it "should not change anything if history is not changed" do - @saved_history = "4\n5\n6\n" - Pry.save_history - @saved_history.should == "4\n5\n6\n" + after do + @histfile.close(true) + Pry.config.history.should_save = false end - it "should append new lines to the file" do - Pry.history << "4" - Pry.save_history - @saved_history.should == "1\n2\n3\n4\n" + it "should save lines to a file as they are written" do + @history.push "5" + File.read(@histfile.path).should == "5\n" end - it "should not clobber lines written by other Pry's in the meantime" do - Pry.history << "5" - @saved_history << "4\n" - Pry.save_history + it "should interleave lines from many places" do + @history.push "5" + File.open(@histfile.path, 'a'){ |f| f.puts "6" } + @history.push "7" - Pry.history.to_a[-3..-1].should == ["2", "3", "5"] - @saved_history.should == "1\n2\n3\n4\n5\n" - end - - it "should not delete lines from the file if this session's history was cleared" do - Pry.history.clear - Pry.save_history - @saved_history.should == "1\n2\n3\n" - end - - it "should save new lines that are added after the history was cleared" do - Pry.history.clear - Pry.history << "4" - Pry.save_history - @saved_history.should =~ /1\n2\n3\n4\n/ - end - - it "should only append new lines the second time it is saved" do - Pry.history << "4" - Pry.save_history - @saved_history << "5\n" - Pry.history << "6" - Pry.save_history - - Pry.history.to_a[-4..-1].should == ["2", "3", "4", "6"] - @saved_history.should == "1\n2\n3\n4\n5\n6\n" + File.read(@histfile.path).should == "5\n6\n7\n" end end end