summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/irb/ext/save-history.rb20
-rw-r--r--test/irb/test_history.rb36
2 files changed, 51 insertions, 5 deletions
diff --git a/lib/irb/ext/save-history.rb b/lib/irb/ext/save-history.rb
index ac358c8ccb..7acaebe36a 100644
--- a/lib/irb/ext/save-history.rb
+++ b/lib/irb/ext/save-history.rb
@@ -81,6 +81,8 @@ module IRB
end
}
end
+ @loaded_history_lines = history.size
+ @loaded_history_mtime = File.mtime(history_file)
end
end
@@ -105,12 +107,20 @@ module IRB
raise
end
- open(history_file, "w:#{IRB.conf[:LC_MESSAGES].encoding}", 0600) do |f|
+ if File.exist?(history_file) && @loaded_history_mtime &&
+ File.mtime(history_file) != @loaded_history_mtime
+ history = history[@loaded_history_lines..-1]
+ append_history = true
+ end
+
+ open(history_file, "#{append_history ? 'a' : 'w'}:#{IRB.conf[:LC_MESSAGES].encoding}", 0600) do |f|
hist = history.map{ |l| l.split("\n").join("\\\n") }
- begin
- hist = hist.last(num) if hist.size > num and num > 0
- rescue RangeError # bignum too big to convert into `long'
- # Do nothing because the bignum should be treated as inifinity
+ unless append_history
+ begin
+ hist = hist.last(num) if hist.size > num and num > 0
+ rescue RangeError # bignum too big to convert into `long'
+ # Do nothing because the bignum should be treated as inifinity
+ end
end
f.puts(hist)
end
diff --git a/test/irb/test_history.rb b/test/irb/test_history.rb
index 392a6afa9a..aad89529ea 100644
--- a/test/irb/test_history.rb
+++ b/test/irb/test_history.rb
@@ -127,6 +127,37 @@ module TestIRB
INPUT
end
+ def test_history_concurrent_use
+ omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
+ IRB.conf[:SAVE_HISTORY] = 1
+ assert_history(<<~EXPECTED_HISTORY, <<~INITIAL_HISTORY, <<~INPUT) do |history_file|
+ exit
+ 5
+ exit
+ EXPECTED_HISTORY
+ 1
+ 2
+ 3
+ 4
+ INITIAL_HISTORY
+ 5
+ exit
+ INPUT
+ assert_history(<<~EXPECTED_HISTORY2, <<~INITIAL_HISTORY2, <<~INPUT2)
+ exit
+ EXPECTED_HISTORY2
+ 1
+ 2
+ 3
+ 4
+ INITIAL_HISTORY2
+ 5
+ exit
+ INPUT2
+ File.utime(File.atime(history_file), File.mtime(history_file) + 2, history_file)
+ end
+ end
+
private
def assert_history(expected_history, initial_irb_history, input)
@@ -143,6 +174,11 @@ module TestIRB
io = TestInputMethod.new
io.class::HISTORY.clear
io.load_history
+ if block_given?
+ history = io.class::HISTORY.dup
+ yield IRB.rc_file("_history")
+ io.class::HISTORY.replace(history)
+ end
io.class::HISTORY.concat(input.split)
io.save_history