1
0
Fork 0
mirror of https://github.com/pry/pry.git synced 2022-11-09 12:35:05 -05:00
pry--pry/lib/pry/history.rb

140 lines
3.8 KiB
Ruby
Raw Normal View History

class Pry
# The History class is responsible for maintaining the user's input history,
# both internally and within Readline.
class History
attr_accessor :loader, :saver
# @return [Fixnum] Number of lines in history when Pry first loaded.
attr_reader :original_lines
def initialize(options = {})
@history = options[:history] || []
@file_path = options[:file_path]
@original_lines = 0
@loader = method(:read_from_file)
@saver = method(:save_to_file)
end
# Load the input history using `History.loader`.
2011-09-05 16:52:49 -04:00
# @return [Integer] The number of lines loaded
def load
@loader.call do |line|
next if invalid_readline_line?(line)
@history << line.chomp
@original_lines += 1
end
end
2011-12-02 00:26:22 -05:00
# Add a line to the input history, ignoring blank and duplicate lines.
2011-09-05 16:52:49 -04:00
# @param [String] line
# @return [String] The same line that was passed in
def push(line)
return line if line.empty? || invalid_readline_line?(line)
begin
last_line = @history[-1]
rescue IndexError
last_line = nil
end
return line if line == last_line
@history << line
if !should_ignore?(line) && Pry.config.history.should_save
@saver.call(line)
end
line
end
alias << push
# Clear this session's history. This won't affect the contents of the
# history file.
def clear
@history.clear
@original_lines = 0
end
# @return [Fixnum] The number of lines in history.
def history_line_count
@history.count
end
# @return [Fixnum] The number of lines in history from just this session.
def session_line_count
@history.count - @original_lines
end
2011-12-02 00:26:22 -05:00
# Return an Array containing all stored history.
2011-09-05 16:52:49 -04:00
# @return [Array<String>] An Array containing all lines of history loaded
# or entered by the user in the current session.
def to_a
@history.to_a
end
2015-10-25 12:39:42 -04:00
# Filter the history with the histignore options
# @return [Array<String>] An array containing all the lines that are not
# included in the histignore.
2015-10-25 12:39:42 -04:00
def filter(history)
2016-02-10 22:07:06 -05:00
history.select { |l| l unless should_ignore?(l) }
2015-10-25 12:39:42 -04:00
end
private
# Check if the line match any option in the histignore
# [Pry.config.history.histignore]
# @return [Boolean] a boolean that notifies if the line was found in the
# histignore array.
2016-02-10 22:07:06 -05:00
def should_ignore?(line)
hist_ignore = Pry.config.history.histignore
return false if hist_ignore.nil? || hist_ignore.empty?
2015-10-25 12:39:42 -04:00
hist_ignore.any? { |p| line.to_s.match(p) }
2015-10-25 12:39:42 -04:00
end
# The default loader. Yields lines from `Pry.history.config.file`.
def read_from_file
path = history_file_path
if File.exist?(path)
File.foreach(path) { |line| yield(line) }
end
rescue SystemCallError => error
warn "Unable to read history file: #{error.message}"
end
# The default saver. Appends the given line to `Pry.history.config.file`.
2012-12-28 20:35:04 -05:00
def save_to_file(line)
history_file.puts line if history_file
end
# The history file, opened for appending.
def history_file
if defined?(@history_file)
@history_file
else
unless File.exist?(history_file_path)
FileUtils.mkdir_p(File.dirname(history_file_path))
end
@history_file = File.open(history_file_path, 'a', 0600).tap do |file|
file.sync = true
end
end
rescue SystemCallError => error
warn "Unable to write history file: #{error.message}"
@history_file = false
end
def history_file_path
File.expand_path(@file_path || Pry.config.history.file)
end
def invalid_readline_line?(line)
# `Readline::HISTORY << line` raises an `ArgumentError` if `line`
# includes a null byte
line.include?("\0")
end
end
end