class TTY::Reader

A class responsible for reading character input from STDIN

Used internally to provide key and line reading functionality

@api public

Attributes

breaker[RW]
line[RW]

Public Instance Methods

read_line(prompt = '', value: '', echo: true, raw: true, nonblock: false) click to toggle source
# File lib/greenhat/tty/reader.rb, line 17
def read_line(prompt = '', value: '', echo: true, raw: true, nonblock: false)
  # Greenhat Shim:: Store Line
  self.breaker = false
  self.line = Line.new(value, prompt: prompt)
  screen_width = TTY::Screen.width
  buffer = ''

  output.print(line)

  while (codes = get_codes(echo: echo, raw: raw, nonblock: nonblock)) &&
        (code = codes[0])
    char = codes.pack('U*')

    # GreenHat Shim / Back Tab Down Submodule
    if [:back_tab, :ctrl_c].include? console.keys[char] 
      clear_display(line, screen_width)
      trigger_key_event(char, line: line.to_s)
      break
    end

    # Greenhat Shim
    if EXIT_KEYS.include?(console.keys[char])
      trigger_key_event(char, line: line.to_s)
      exit
    end

    clear_display(line, screen_width) if raw && echo

    if console.keys[char] == :backspace || code == BACKSPACE
      unless line.start?
        line.left
        line.delete
      end
    elsif console.keys[char] == :delete || code == DELETE
      line.delete
    elsif console.keys[char].to_s =~ /ctrl_/
      # skip
    elsif console.keys[char] == :up
      line.replace(history_previous) if history_previous?
    elsif console.keys[char] == :down
      line.replace(history_next? ? history_next : buffer) if track_history?
    elsif console.keys[char] == :left
      line.left
    elsif console.keys[char] == :right
      line.right
    elsif console.keys[char] == :home
      line.move_to_start
    elsif console.keys[char] == :end
      line.move_to_end
    else
      if raw && [CARRIAGE_RETURN, NEWLINE].include?(code)
        char = "\n"
        line.move_to_end
      end
      line.insert(char)
      buffer = line.text
    end

    if (console.keys[char] == :backspace || code == BACKSPACE) && echo
      if raw
        output.print("\e[1X") unless line.start?
      else
        output.print("\s" + (line.start? ? '' : "\b"))
      end
    end

    # trigger before line is printed to allow for line changes
    trigger_key_event(char, line: line.to_s)

    if raw && echo
      output.print(line.to_s)
      if char == "\n"
        line.move_to_start
      elsif !line.end? # readjust cursor position
        output.print(cursor.backward(line.text_size - line.cursor))
      end
    end

    # Greenhat Shim do things
    next unless [CARRIAGE_RETURN, NEWLINE].include?(code) || breaker

    buffer = ''
    output.puts unless echo
    break
  end

  add_to_history(line.text.rstrip) if track_history? && echo

  line.text
end