BasicObject
# File reline/ansi.rb, line 332
def self.clear_screen
@@output.write "\e[2J"
@@output.write "\e[1;1H"
end
# File reline/ansi.rb, line 244
def self.cursor_pos
begin
res = +''
m = nil
@@input.raw do |stdin|
@@output << "\e[6n"
@@output.flush
loop do
c = stdin.getc
next if c.nil?
res << c
m = res.match(/\e\[(?<row>\d+);(?<column>\d+)R/)
break if m
end
(m.pre_match + m.post_match).chars.reverse_each do |ch|
stdin.ungetc ch
end
end
column = m[:column].to_i - 1
row = m[:row].to_i - 1
rescue Errno::ENOTTY
begin
buf = @@output.pread(@@output.pos, 0)
row = buf.count("\n")
column = buf.rindex("\n") ? (buf.size - buf.rindex("\n")) - 1 : 0
rescue Errno::ESPIPE
# Just returns column 1 for ambiguous width because this I/O is not
# tty and can't seek.
row = 0
column = 1
end
end
Reline::CursorPos.new(column, row)
end
# File reline/ansi.rb, line 347
def self.deprep(otio)
Signal.trap('WINCH', @@old_winch_handler) if @@old_winch_handler
end
# File reline/ansi.rb, line 205
def self.empty_buffer?
unless @@buf.empty?
return false
end
!@@input.wait_readable(0)
end
# File reline/ansi.rb, line 323
def self.erase_after_cursor
@@output.write "\e[K"
end
# File reline/ansi.rb, line 227
def self.get_screen_size
s = @@input.winsize
return s if s[0] > 0 && s[1] > 0
s = [ENV["LINES"].to_i, ENV["COLUMNS"].to_i]
return s if s[0] > 0 && s[1] > 0
[24, 80]
rescue Errno::ENOTTY
[24, 80]
end
# File reline/ansi.rb, line 193
def self.getc
if Reline.core.config.enable_bracketed_paste
getc_with_bracketed_paste
else
inner_getc
end
end
# File reline/ansi.rb, line 299
def self.hide_cursor
if Reline::Terminfo.enabled?
begin
@@output.write Reline::Terminfo.tigetstr('civis')
rescue Reline::Terminfo::TerminfoError
# civis is undefined
end
else
# ignored
end
end
# File reline/ansi.rb, line 201
def self.in_pasting?
@@in_bracketed_paste_mode or (not Reline::IOGate.empty_buffer?)
end
# File reline/ansi.rb, line 279
def self.move_cursor_column(x)
@@output.write "\e[#{x + 1}G"
end
# File reline/ansi.rb, line 291
def self.move_cursor_down(x)
if x > 0
@@output.write "\e[#{x}B"
elsif x < 0
move_cursor_up(-x)
end
end
# File reline/ansi.rb, line 283
def self.move_cursor_up(x)
if x > 0
@@output.write "\e[#{x}A"
elsif x < 0
move_cursor_down(-x)
end
end
# File reline/ansi.rb, line 342
def self.prep
retrieve_keybuffer
nil
end
# File reline/ansi.rb, line 216
def self.retrieve_keybuffer
begin
return unless @@input.wait_readable(0.001)
str = @@input.read_nonblock(1024)
str.bytes.each do |c|
@@buf.push(c)
end
rescue EOFError
end
end
# File reline/ansi.rb, line 327
def self.scroll_down(x)
return if x.zero?
@@output.write "\e[#{x}S"
end
# File reline/ansi.rb, line 237
def self.set_screen_size(rows, columns)
@@input.winsize = [rows, columns]
self
rescue Errno::ENOTTY
self
end
# File reline/ansi.rb, line 338
def self.set_winch_handler(&handler)
@@old_winch_handler = Signal.trap('WINCH', &handler)
end
# File reline/config.rb, line 177
def add_default_key_binding(keystroke, target)
@key_actors[@keymap_label].default_key_bindings[keystroke] = target
end
# File reline/config.rb, line 173
def add_default_key_binding_by_keymap(keymap, keystroke, target)
@key_actors[keymap].default_key_bindings[keystroke] = target
end
# File reline/config.rb, line 165
def add_oneshot_key_binding(keystroke, target)
@oneshot_key_bindings[keystroke] = target
end
# File reline/config.rb, line 336
def bind_key(key, func_name)
if key =~ /\A"(.*)"\z/
keyseq = parse_keyseq($1)
else
keyseq = nil
end
if func_name =~ /"(.*)"/
func = parse_keyseq($1)
else
func = func_name.tr(?-, ?_).to_sym # It must be macro.
end
[keyseq, func]
end
# File reline/config.rb, line 264
def bind_variable(name, value)
case name
when 'history-size'
begin
@history_size = Integer(value)
rescue ArgumentError
@history_size = 500
end
when 'bell-style'
@bell_style =
case value
when 'none', 'off'
:none
when 'audible', 'on'
:audible
when 'visible'
:visible
else
:audible
end
when 'comment-begin'
@comment_begin = value.dup
when 'completion-query-items'
@completion_query_items = value.to_i
when 'isearch-terminators'
@isearch_terminators = retrieve_string(value)
when 'editing-mode'
case value
when 'emacs'
@editing_mode_label = :emacs
@keymap_label = :emacs
when 'vi'
@editing_mode_label = :vi_insert
@keymap_label = :vi_insert
end
when 'keymap'
case value
when 'emacs', 'emacs-standard', 'emacs-meta', 'emacs-ctlx'
@keymap_label = :emacs
when 'vi', 'vi-move', 'vi-command'
@keymap_label = :vi_command
when 'vi-insert'
@keymap_label = :vi_insert
end
when 'keyseq-timeout'
@keyseq_timeout = value.to_i
when 'show-mode-in-prompt'
case value
when 'off'
@show_mode_in_prompt = false
when 'on'
@show_mode_in_prompt = true
else
@show_mode_in_prompt = false
end
when 'vi-cmd-mode-string'
@vi_cmd_mode_string = retrieve_string(value)
when 'vi-ins-mode-string'
@vi_ins_mode_string = retrieve_string(value)
when 'emacs-mode-string'
@emacs_mode_string = retrieve_string(value)
when *VARIABLE_NAMES then
variable_name = :"@#{name.tr(?-, ?_)}"
instance_variable_set(variable_name, value.nil? || value == '1' || value == 'on')
end
end
# File reline/config.rb, line 234
def handle_directive(directive, file, no)
directive, args = directive.split(' ')
case directive
when 'if'
condition = false
case args
when 'mode'
when 'term'
when 'version'
else # application name
condition = true if args == 'Ruby'
condition = true if args == 'Reline'
end
@if_stack << [file, no, @skip_section]
@skip_section = !condition
when 'else'
if @if_stack.empty?
raise InvalidInputrc, "#{file}:#{no}: unmatched else"
end
@skip_section = !@skip_section
when 'endif'
if @if_stack.empty?
raise InvalidInputrc, "#{file}:#{no}: unmatched endif"
end
@skip_section = @if_stack.pop
when 'include'
read(args)
end
end
# File reline/config.rb, line 157
def key_bindings
# The key bindings for each editing mode will be overwritten by the user-defined ones.
kb = @key_actors[@editing_mode_label].default_key_bindings.dup
kb.merge!(@additional_key_bindings[@editing_mode_label])
kb.merge!(@oneshot_key_bindings)
kb
end
# File reline/config.rb, line 350
def key_notation_to_code(notation)
case notation
when /\(?:C|Control)-([A-Za-z_])/
(1 + $1.downcase.ord - ?a.ord)
when /\(?:M|Meta)-([0-9A-Za-z_])/
modified_key = $1
case $1
when /[0-9]/
?\M-0.bytes.first + (modified_key.ord - ?0.ord)
when /[A-Z]/
?\M-A.bytes.first + (modified_key.ord - ?A.ord)
when /[a-z]/
?\M-a.bytes.first + (modified_key.ord - ?a.ord)
end
when /\(?:C|Control)-(?:M|Meta)-[A-Za-z_]/, /\(?:M|Meta)-(?:C|Control)-[A-Za-z_]/
# 129 M-^A
when /\(\d{1,3})/ then $1.to_i(8) # octal
when /\x(\h{1,2})/ then $1.to_i(16) # hexadecimal
when "\\e" then ?\e.ord
when "\\\\" then ?\\.ord
when "\\\"" then ?".ord
when "\\'" then ?'.ord
when "\\a" then ?\a.ord
when "\\b" then ?\b.ord
when "\\d" then ?\d.ord
when "\\f" then ?\f.ord
when "\\n" then ?\n.ord
when "\\r" then ?\r.ord
when "\\t" then ?\t.ord
when "\\v" then ?\v.ord
else notation.ord
end
end
# File reline/config.rb, line 384
def parse_keyseq(str)
ret = []
str.scan(KEYSEQ_PATTERN) do
ret << key_notation_to_code($&)
end
ret
end
# File reline/config.rb, line 138
def read(file = nil)
file ||= default_inputrc_path
begin
if file.respond_to?(:readlines)
lines = file.readlines
else
lines = File.readlines(file)
end
rescue Errno::ENOENT
return nil
end
read_lines(lines, file)
self
rescue InvalidInputrc => e
warn e.message
nil
end
# File reline/config.rb, line 187
def read_lines(lines, file = nil)
if not lines.empty? and lines.first.encoding != Reline.encoding_system_needs
begin
lines = lines.map do |l|
l.encode(Reline.encoding_system_needs)
rescue Encoding::UndefinedConversionError
mes = "The inputrc encoded in #{lines.first.encoding.name} can't be converted to the locale #{Reline.encoding_system_needs.name}."
raise Reline::ConfigEncodingConversionError.new(mes)
end
end
end
conditions = [@skip_section, @if_stack]
@skip_section = nil
@if_stack = []
lines.each_with_index do |line, no|
next if line.match(/\A\s*#/)
no += 1
line = line.chomp.lstrip
if line.start_with?('$')
handle_directive(line[1..-1], file, no)
next
end
next if @skip_section
case line
when /^set +([^ ]+) +([^ ]+)/i
var, value = $1.downcase, $2
bind_variable(var, value)
next
when /\s*("#{KEYSEQ_PATTERN}+")\s*:\s*(.*)\s*$/o
key, func_name = $1, $2
keystroke, func = bind_key(key, func_name)
next unless keystroke
@additional_key_bindings[@keymap_label][keystroke] = func
end
end
unless @if_stack.empty?
raise InvalidInputrc, "#{file}:#{@if_stack.last[1]}: unclosed if"
end
ensure
@skip_section, @if_stack = conditions
end
# File reline/config.rb, line 181
def reset_default_key_bindings
@key_actors.values.each do |ka|
ka.reset_default_key_bindings
end
end