write to history incrementally

This makes it less essential for drivers to finalize the pry instance.
This commit is contained in:
Conrad Irwin 2012-12-28 16:57:30 -08:00
parent 7c13b1f7b1
commit 09160e7906
5 changed files with 47 additions and 79 deletions

View File

@ -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

View File

@ -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<String>] 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

View File

@ -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?

View File

@ -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:

View File

@ -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