Skip to content

Instantly share code, notes, and snippets.

@Mon-Ouie
Created October 9, 2011 07:47
Show Gist options
  • Save Mon-Ouie/1273417 to your computer and use it in GitHub Desktop.
Save Mon-Ouie/1273417 to your computer and use it in GitHub Desktop.
require 'io/console'
class Coolline
# Creates a new cool line
# @param [IO] input Input to read from. This has to be an actual IO object.
# @param [IO] output Output. This can be an object of any kind.
#
# @yield after each character entered
# @yieldparam [String] line
# @yieldreturn [String] string to print for this input
def initialize(input = STDIN, output = $stdout, &block)
@input = input
@output = output
@transform = block
end
# Reads a line from the terminal
# @param [String] prompt Characters to print before each line
def readline(prompt = ">> ")
@line = ""
@pos = 0
@max_length = 0
print prompt
until (char = @input.getch) == "\r"
handle(char)
line = fill_line(transform(@line))
print "\r"
print prompt + fill_line(transform(@line))
print "\e[#{prompt.size + @pos + 1}G"
end
print "\n"
@line
end
def gets
readline ""
end
private
def transform(line)
ret = @transform ? @transform.call(line) : line
@max_length = ret.length if ret.length > @max_length
ret
end
def handle(char)
case char
when "\b", "\x7F"
if @pos != 0
@line[@pos - 1] = ''
@pos -= 1
end
when "\C-a"
@pos = 0
when "\C-e"
@pos = @line.size
when "\C-k"
@line[@pos..-1] = ""
when "\C-f"
if @pos != @line.size
@pos += 1
end
when "\C-b"
if @pos != 0
@pos -= 1
end
when "\C-d"
if @pos != @line.size
@line[@pos] = ""
end
when "\C-c"
raise Interrupt
when "\C-w"
if @pos != 0
pos = @pos - 1
pos -= 1 if pos != -1 and word_boundary? @line[pos]
pos -= 1 until pos == -1 or word_boundary? @line[pos]
@line[(pos + 1)..@pos] = ""
@pos = pos + 1
end
when "\C-a".."\C-z"
# ignore other control codes
else
@line.insert @pos, char
@pos += char.size
end
end
def fill_line(line)
line.ljust(@max_length)
end
def word_boundary?(char)
char =~ /[ _-]/
end
end
require 'coderay'
cool = Coolline.new do |line|
CodeRay.scan(line, :ruby).term
end
loop do
cool.readline
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment