Skip to content

Commit

Permalink
Re-arrange, and fix readline prompt
Browse files Browse the repository at this point in the history
  • Loading branch information
raggi committed Oct 27, 2009
1 parent 9a7aee2 commit f360f18
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 90 deletions.
2 changes: 1 addition & 1 deletion bin/ir
@@ -1,4 +1,4 @@
#!/usr/bin/env ruby -Ilib -rubygems
#!/usr/bin/env ruby

require 'ir'

Expand Down
108 changes: 19 additions & 89 deletions lib/ir.rb
@@ -1,73 +1,6 @@
class Ir
class Tty
DEFAULTS = {
:tty_exit_on_eof => true
}
def initialize(input = $stdin, output = $stdout, options = {})
options = DEFAULTS.merge(options)
@exit_on_eof = options[:tty_exit_on_eof]
@input = input
@output = output
@ir = Ir.new(options.merge(:output => self))
consume
end

def consume
exit_on_eof { interruptable { @ir << @input.readline } while true }
end

def print(*args)
exit_on_eof do
@output.print(*args)
@output.flush
end
end

def puts(*args)
exit_on_eof { @output.puts(*args) }
end

private
def interruptable
yield
rescue Interrupt
@ir.interrupt
end

def exit_on_eof
yield
rescue EOFError
puts # TODO optionme?
exit if @exit_on_eof
end
end

class Readline < Tty
TERM = "\n"
DEFAULTS = {
:term => TERM,
# Darwin readline bug!
# TODO - support native readline build here, more cleanly
:puts_on_interrupt => RUBY_PLATFORM !~ /darwin/
}

def initialize(output = $stdout, options = {})
require 'readline'
super($stdin, $stdout, DEFAULTS.merge(options))
end

def consume
exit_on_eof do
interruptable do
if line = ::Readline.readline
@ir << line + TERM
else
raise EOFError
end
end while true
end
end
end
autoload :Tty, 'ir/tty'
autoload :Readline, 'ir/readline'

FROM = "\tfrom "

Expand Down Expand Up @@ -109,29 +42,13 @@ def initialize(options = {})
@buffer, @bufferline, @inputline, @prompt = '', 1, 1, :normal
# So runtimes can do: Thread.current[:ir].notify "OHAI"
Thread.current[@options[:thread_local_var]] = self
prompt
end

def prompt(name = nil, lineno = nil)
lineno ||= @inputline
name ||= @prompt
prompt = @prompts[name]
case prompt
when String
print prompt
when Proc
print prompt.call(@name, lineno, name)
else
print prompt.to_s
end
end

# Lines are expected to include the \n
def <<(data)
@buffer << data
@inputline += data.count(@term)
syntax? ? consume : @prompt = :syntax
prompt
end

def syntax?
Expand All @@ -149,29 +66,42 @@ def consume
clear
end

def prompt(name = nil, lineno = nil)
lineno ||= @inputline
name ||= @prompt
prompt = @prompts[name]
case prompt
when String
prompt
when Proc
prompt.call(@name, lineno, name)
else
prompt.to_s
end
end

def notify_exception(exception)
notify "#{exception.class.inspect}: #{exception.message}"
notify *exception.backtrace.map { |t| FROM + t }
end

def results(*args)
args.each do |arg|
prompt :result, @inputline - 1
print prompt(:result, @inputline - 1)
puts arg
end
end

def notify(*args)
args.each do |arg|
prompt :notify, @inputline - 1
print prompt(:notify, @inputline - 1)
puts arg
end
end

def interrupt
puts if @options[:puts_on_interrupt]
clear if @options[:clear_on_interrupt]
prompt
end

def clear
Expand All @@ -188,7 +118,7 @@ def puts(*args)
@output.puts(*args)
end

# Immediately load irbrc
# Immediately load irbrc
def self.irbrc
home = ENV['HOME']
home ||= ENV['HOMEDRIVE'] + ENV['HOMEPATH']
Expand Down
29 changes: 29 additions & 0 deletions lib/ir/readline.rb
@@ -0,0 +1,29 @@
require 'readline'

class Ir
class Readline < Tty
TERM = "\n"
DEFAULTS = {
:term => TERM,
# Darwin readline bug!
# TODO - support native readline build here, more cleanly
:puts_on_interrupt => RUBY_PLATFORM !~ /darwin/
}

def initialize(output = $stdout, options = {})
super($stdin, $stdout, DEFAULTS.merge(options))
end

def consume
exit_on_eof do
interruptable do
if line = ::Readline.readline(@ir.prompt)
@ir << line + TERM
else
raise EOFError
end
end while true
end
end
end
end
49 changes: 49 additions & 0 deletions lib/ir/tty.rb
@@ -0,0 +1,49 @@
class Ir
class Tty
DEFAULTS = {
:tty_exit_on_eof => true
}
def initialize(input = $stdin, output = $stdout, options = {})
options = DEFAULTS.merge(options)
@exit_on_eof = options[:tty_exit_on_eof]
@input = input
@output = output
@ir = Ir.new(options.merge(:output => self))
consume
end

def consume
exit_on_eof do
interruptable do
print @ir.prompt
@ir << @input.readline
end while true
end
end

def print(*args)
exit_on_eof do
@output.print(*args)
@output.flush
end
end

def puts(*args)
exit_on_eof { @output.puts(*args) }
end

private
def interruptable
yield
rescue Interrupt
@ir.interrupt
end

def exit_on_eof
yield
rescue EOFError
puts # TODO optionme?
exit if @exit_on_eof
end
end
end

0 comments on commit f360f18

Please sign in to comment.