Skip to content

Instantly share code, notes, and snippets.

@JakeAustwick
Created December 8, 2011 21:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JakeAustwick/1448664 to your computer and use it in GitHub Desktop.
Save JakeAustwick/1448664 to your computer and use it in GitHub Desktop.
#!/usr/local/bin/ruby -w
#
# history_buffer.rb
#
# Created by Fabio Cevasco on 2008-03-01.
# Copyright (c) 2008 Fabio Cevasco. All rights reserved.
#
# This is Free Software. See LICENSE for details.
#
#
#
module InLine
#
# The HistoryBuffer class is used to hold the editor and line histories, as well
# as word completion matches.
#
class HistoryBuffer < Array
attr_reader :position, :size
attr_accessor :duplicates, :exclude, :cycle
undef <<
#
# Create an instance of InLine::HistoryBuffer.
# This method takes an optional block used to override the
# following instance attributes:
# * <tt>@duplicates</tt> - whether or not duplicate items will be stored in the
# buffer.
# * <tt>@exclude</tt> - a Proc object defining exclusion rules to prevent items
# from being added to the buffer.
# * <tt>@cycle</tt> - Whether or not the buffer is cyclic.
#
def initialize(size)
@duplicates = true
@exclude = lambda { nil }
@cycle = false
yield self if block_given?
@size = size
@position = nil
end
#
# Resize the buffer, resetting <tt>@position</tt> to nil.
#
def resize(new_size)
if new_size < @size
@size-new_size.times { pop }
end
@size = new_size
@position = nil
end
#
# Clear the content of the buffer and reset <tt>@position</tt> to nil.
#
def empty
@position = nil
clear
end
#
# Retrieve the element at <tt>@position</tt>.
#
def get
return nil unless length > 0
@position = length-1 unless @position
at @position
end
#
# Return true if <tt>@position</tt> is at the end of the buffer.
#
def end?
@position == length-1
end
#
# Return true if <tt>@position</tt> is at the start of the buffer.
#
def start?
@position == 0
end
#
# Decrement <tt>@position</tt>.
#
def back
return nil unless length > 0
case @position
when nil: @position = length-1
when 0: @position = length-1 if @cycle
else @position -= 1
end
end
#
# Increment <tt>@position</tt>.
#
def forward
return nil unless length > 0
case @position
when nil: @position = length-1
when length-1: @position = 0 if @cycle
else @position += 1
end
end
#
# Add a new item to the buffer.
#
def <<(item)
delete(item) unless @duplicates
unless @exclude.call(item)
# Remove the oldest element if size is exceeded
if @size <= length
reverse!.pop
reverse!
end
# Add the new item and reset the position
push(item)
@position = nil
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment