class Listener

This class works on the command line interface to allow the user to move the cursor, modify the input string in each point and retrieve commands from the history

Author

Massimiliano Dal Mas (max.codeware@gmail.com)

License

Distributed under MIT license

Constants

CHARS
CSI
LETTERS
NUMBERS
SPECIAL_CHARS

Public Class Methods

new() click to toggle source

Creates the main variables

# File lib/linmeric/Listener.rb, line 23
def initialize
  @final_string = ""
  @i = 0
  @s = 0
  @exit = false
  @list = Archive.new
end

Public Instance Methods

collect_single_key() click to toggle source

according to the collected key decides what to do: moving the cursor, surfing the history, or simply store chars in a variable

# File lib/linmeric/Listener.rb, line 57
  def collect_single_key()
    c = read_char
    case c
      
      # "TAB"
      when "\t"        
      
      # "RETURN"
      when "\r"
        puts c
        @exit = true
      when "\n"
        # "LINE FEED"
      when "\e"
        # "ESCAPE"
    
      # "UP ARROW"
      when "\e[A"       
        temp = @list.previous
        unless temp == ""
          clear_line
          @final_string = temp
          @i = @final_string.size
          print @final_string
        end
        
      # "DOWN ARROW"
      when "\e[B" 
          clear_line
          @final_string = @list.next_
          @i = @final_string.size
          print @final_string

      # "RIGHT ARROW"
      when "\e[C"
        @list.top
        unless @i == @final_string.size
          $stdout.write "#{CSI}1C"
          @i += 1
        end 
      
      # "LEFT ARROW"
      when "\e[D"
        @list.top
        unless @i == 0
          $stdout.write "#{CSI}1D" 
          @i -= 1
        end
     
      # Delete char
      when "\177" 
        @list.top
        unless @i == 0
          $stdout.write "#{CSI}1D"
          for i in (@i)...@final_string.size do
            $stdout.write "#{@final_string[i]}"
          end
          $stdout.write " "
          @final_string = @final_string.remove(@i-1)
          for i in (@i-2)...@final_string.size do
            $stdout.write "#{CSI}1D"
          end
          @i -= 1
        end

      when "\004"
        # "DELETE"
      when "\e[3~"
        # "ALTERNATE DELETE"
      
      # "Ctrl + C"
      when "\u0003"        
#        puts
#        exit 0
      when /^.$/
        @list.top
        if CHARS.include? c
          if @i < @final_string.size then
            last_i = @i + 2
            @final_string.insert @i, c
            clear_line
            $stdout.write "#{@final_string}"
            cursor_to(last_i)
            @i = last_i - 1
          else
            print c
            @final_string += c
            @i += 1
          end
        elsif c == "\f" then
          @i = 0
          print "\e[H\e[2J"
          print "Linmeric-main> "
        end
    end
  end
gets() click to toggle source

main function that can be used. It returns the stream the user wrote on the command line after they pressed return.

# File lib/linmeric/Listener.rb, line 156
def gets()
  collect_single_key while(!@exit)
  @list.store(@final_string)
  return @final_string.clone
ensure
  reset
end
read_char() click to toggle source

Reads a single char from the command line

# File lib/linmeric/Listener.rb, line 39
def read_char
  STDIN.echo = false
  STDIN.raw!

  input = STDIN.getc.chr
  if input == "\e" then
    input << STDIN.read_nonblock(3) rescue nil
    input << STDIN.read_nonblock(2) rescue nil
  end
ensure
  STDIN.echo = true
  STDIN.cooked!

  return input
end
reset() click to toggle source

reinitializates three main variables

# File lib/linmeric/Listener.rb, line 32
def reset
  @final_string = ""
  @i = 0
  @exit = false
end

Private Instance Methods

clear_line() click to toggle source

Clears the current line (deletes the typed input)

# File lib/linmeric/Listener.rb, line 167
def clear_line
  if @i < @final_string.size
    for i in @i...@final_string.size do
      $stdout.write "#{CSI}1C"
    end
  end
  @i = (@final_string == nil or @final_string == "") ? 0 : @final_string.size
  for i in 0...@i do
    $stdout.write "#{CSI}1D"
    $stdout.write " "
    $stdout.write "#{CSI}1D"
  end
  @i = 0
end
cursor_to(pos) click to toggle source

Moves the cursor backward of the number of specified position

  • argument: number of position the cursor must be moved backward

# File lib/linmeric/Listener.rb, line 185
def cursor_to(pos)
  return nil if pos < 0
  for i in pos..@final_string.size
    $stdout.write "#{CSI}1D"
  end
end