Class: Rcalc::Terminal

Inherits:
Object
  • Object
show all
Defined in:
lib/rcalc/terminal.rb

Overview

This class contains utilities related to terminal. Its initializer does not take any arguments.

Instance Method Summary collapse

Instance Method Details

#bgcolor!(id) ⇒ Object

Sets the current background color to a number

Examples:

set background color to red

t = Rcalc::Terminal.new
t.bgcolor!(Rcalc::TERMINAL_COLORS[:red])


115
116
117
# File 'lib/rcalc/terminal.rb', line 115

def bgcolor!(id)
  e! "48;5;#{id}m"
end

#bgrgb!(r, g, b) ⇒ Object

Sets the current background color to a RGB value

Examples:

set background color to red

t = Rcalc::Terminal.new
t.bgrgb!(255,0,0)


147
148
149
# File 'lib/rcalc/terminal.rb', line 147

def bgrgb!(r, g, b)
  e! "48;2;#{r};#{g};#{b}m"
end

#blocking_console_query(query, listen_until) ⇒ Object

Performs a blocking console query. Used by other functions in this class



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/rcalc/terminal.rb', line 9

def blocking_console_query(query, listen_until)
  # send query and block wait for response
  res = ''
  $stdin.raw do |stdin|
    $stdout << "#{esc}#{query}"
    $stdout.flush

    finished = false
    loop do
      c = stdin.getc
      res << c if c
      listen_until.split.each do |d|
        finished = true if c == d
      end
      break if finished
    end
  end
  res
end

#color!(id) ⇒ Object

Sets the current text color to a number

Examples:

set text color to red

t = Rcalc::Terminal.new
t.color!(Rcalc::TERMINAL_COLORS[:red])


104
105
106
# File 'lib/rcalc/terminal.rb', line 104

def color!(id)
  e! "38;5;#{id}m"
end

#e!(command) ⇒ Object

Function to print the CSI sequence followed by some command. Used by other functions in the class



77
78
79
# File 'lib/rcalc/terminal.rb', line 77

def e!(command)
  print "#{esc}#{command}"
end

#escObject

Function to get the CSI sequence. Used by other functions in the class



70
71
72
# File 'lib/rcalc/terminal.rb', line 70

def esc
  "\e["
end

#goto!(x, y) ⇒ Object

Sets cursor position

Examples:

set cursor to 10,10

t = Rcalc::Terminal.new
t.goto!(10, 10)


158
159
160
# File 'lib/rcalc/terminal.rb', line 158

def goto!(x, y)
  e! "#{y};#{x}f"
end

#listen!(&block) ⇒ Object

Listen for keypresses on the terminal

Examples:

t = Rcalc::Terminal.new
t.listen! do |key|
  print key
end


204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/rcalc/terminal.rb', line 204

def listen!(&block)
  $stdin.raw do |stdin|
    collect = ''

    finished = false
    loop do
      c = stdin.getch(min: 0, time: 0.01)

      if c.nil?
        if collect.length.positive?

          # sometimes multiple tokens appear inside a result
          # so we split it out and send them to the block
          split(collect).each do |token|
            finished = block.call(token)
          end
        end
        collect = ''

      else
        collect += c
      end

      break if finished
    end
  end
end

#posInteger

Gets the cursor position in the terminal. Returns two variables, x and y. Takes no arguments.

Examples:

t = Rcalc::Terminal.new
x, y = t.pos

Returns:

  • (Integer, Integer)

    x and y, or column, row in that order.



38
39
40
41
# File 'lib/rcalc/terminal.rb', line 38

def pos
  m = blocking_console_query('6n', 'R').match(/(?<row>\d+);(?<column>\d+)/)
  [Integer(m[:column]), Integer(m[:row])]
end

#rgb!(r, g, b) ⇒ Object

Sets the current text color to a RGB value

Examples:

set text color to red

t = Rcalc::Terminal.new
t.rgb!(255,0,0)


136
137
138
# File 'lib/rcalc/terminal.rb', line 136

def rgb!(r, g, b)
  e! "38;2;#{r};#{g};#{b}m"
end

#sizeInteger

Gets the size of the terminal in characters. Returns two variables, width and height. Takes no arguments.

Examples:

t = Rcalc::Terminal.new
w, h = t.size

Returns:

  • (Integer, Integer)

    width and height, or columns, rows in that order.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/rcalc/terminal.rb', line 51

def size
  # get current position
  x, y = pos

  # try go to the ends of the earth
  goto!(9999, 9999)

  # get that position
  tx, ty = pos

  # go back to current pos
  goto!(x, y)

  [tx, ty]
end

#split(collect) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/rcalc/terminal.rb', line 162

def split(collect)
  res = []

  inside_esc = false
  current = ''
  collect.each_char do |chr|
    # start of esc
    if chr == "\e"
      inside_esc = true

      # if there already is escaped content in the buffer,
      #  send it out and clear the buffer
      unless current.empty?
        res << current
        current = ''
      end
    end

    if inside_esc
      # if we are inside an escape, add chars to the buffer
      current << chr
    else
      # for all other characters, we just
      res << chr
    end
  end

  # if we were inside an escape, we need to send out the final set
  res << current if inside_esc

  res
end