Class: Ansi::Selector::Impl

Inherits:
Object
  • Object
show all
Defined in:
lib/ansi/selector/impl.rb

Direct Known Subclasses

MultiImpl, SingleImpl

Constant Summary collapse

POSITION_SCRIPT_PATH =
File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "position.sh"))
CODES =
{
  standout_mode: `tput rev`,
  exit_standout_mode: `tput rmso`,
  cursor_up: `tput cuu1`,
  cursor_down: `tput cud1`,
  carriage_return_key: `tput cr`
}

Instance Method Summary collapse

Constructor Details

#initialize(options, formatter, preselected) ⇒ Impl

Returns a new instance of Impl.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/ansi/selector/impl.rb', line 16

def initialize(options, formatter, preselected)
  @options = options
  @formatter = formatter
  @highlighted_line_index = 0
  @cursor_line_index = 0
  @columns = terminal_columns

  # Converts options to column-aligned strings.
  formatted = @options.map(&@formatter).map(&method(:Array)).map { |line| line.map(&:to_s).map(&method(:strip_ansi_colors)) }
  @formatted ||= formatted.map do |f|
    f.map.with_index do |part, column|
      width = formatted.map { |fm| fm[column] }.compact.map(&:size).max
      part.ljust(width)
    end.join('  ')
  end

  Signal.trap('SIGWINCH', proc do
    columns = terminal_columns
    if columns < @columns && !all_options_fit?(columns)
      # When a buffer gets narrower, the text that doesn't fit into the screen anymore
      # starts jumping around in a way that makes it hard to predict. In such case we
      # clear everything and re-print options at the beginning of the buffer to
      # simplify things.
      tty.print(`printf '\e[2J'`)
      tty.print(`tput cup 0 0`)
    else
      print_line(0)
    end

    @columns = columns
    print_options
  end)
end

Instance Method Details

#all_options_fit?(columns) ⇒ Boolean

Returns:

  • (Boolean)


50
51
52
# File 'lib/ansi/selector/impl.rb', line 50

def all_options_fit?(columns)
  option_indices.map(&method(:final_text_for_line)).map(&:size).all? { |size| size < columns }
end

#selectObject



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/ansi/selector/impl.rb', line 64

def select
  print_options
  answer = ask_to_choose
  # We need to reprint here in order to render the lines that are behind the buffer.
  range(@highlighted_line_index, @options.size - 1).each(&method(:print_line))
  go_to_line(@options.size)

  answer
ensure
  tty.close
end

#terminal_columnsFixnum

Returns:

  • (Fixnum)


55
56
57
# File 'lib/ansi/selector/impl.rb', line 55

def terminal_columns
  `tput cols`.to_i
end

#terminal_linesFixnum

Returns:

  • (Fixnum)


60
61
62
# File 'lib/ansi/selector/impl.rb', line 60

def terminal_lines
  `tput lines`.to_i
end