Module: Terminal
- Defined in:
- lib/terminal.rb,
lib/terminal/ansi.rb,
lib/terminal/text.rb,
lib/terminal/input.rb,
lib/terminal/shell.rb,
lib/terminal/detect.rb,
lib/terminal/version.rb,
lib/terminal/input/key_event.rb,
lib/terminal/text/char_width.rb,
lib/terminal/ansi/named_colors.rb
Overview
Terminal access with support for ANSI control codes and BBCode-like embedded text attribute syntax (see Ansi.bbcode). It automagically detects whether your terminal supports ANSI features, like coloring (see Terminal.colors) or the CSIu protocol support (see Terminal.read_key_event, Terminal.on_key_event and Terminal.input_mode). It calculates the display width for Unicode chars (see Text.width) and help you to display text with word-wise line breaks (see Text.each_line).
Defined Under Namespace
Modules: Ansi, Text Classes: KeyEvent
Constant Summary collapse
- VERSION =
The version number of the gem.
'0.16.0'
Class Attribute Summary collapse
-
.ansi? ⇒ Boolean
readonly
Return true if the current terminal supports ANSI control codes.
-
.application ⇒ Symbol?
readonly
Terminal application identifier.
-
.colors ⇒ Integer
readonly
Number of supported colors.
-
.columns ⇒ Integer
Screen column count.
-
.input_mode ⇒ :csi_u, ...
readonly
Supported input mode.
-
.pos ⇒ [Integer, Integer]?
Current cursor position.
-
.rows ⇒ Integer
Screen row count.
-
.size ⇒ [Integer, Integer]
Screen size as a tuple of Terminal.rows and Terminal.columns.
-
.true_color? ⇒ Boolean
readonly
Whether true colors are supported.
Class Method Summary collapse
-
.<<(object) ⇒ Terminal
Writes the given object to the terminal.
-
.hide_alt_screen ⇒ Terminal
Hide the alternate screen.
-
.hide_cursor ⇒ Terminal
Hide the cursor.
-
.on_key_event(mouse: false, mouse_move: false, focus: false) {|event| ... } ⇒ true, ...
Event loop for key and mouse events.
-
.print(*objects, bbcode: true) ⇒ nil
Writes the given objects to the terminal.
-
.puts(*objects, bbcode: true) ⇒ nil
Writes the given objects to the terminal.
-
.read_key(mode: :named) ⇒ String, ...
deprecated
Deprecated.
Use rather Terminal.read_key_event for better input handling.
-
.read_key_event ⇒ KeyEvent?
Read next KeyEvent from standard input.
-
.sh(*cmd, **options, &block) ⇒ Object
Execute a command and report command output line by line or capture the output.
-
.show_alt_screen ⇒ Terminal
Show the alternate screen.
-
.show_cursor ⇒ Terminal
Show the cursor.
Class Attribute Details
.ansi? ⇒ Boolean (readonly)
Return true if the current terminal supports ANSI control codes. When the terminal does not support it, colors will return 2 (two) and all output methods (<<, print, puts) will not forward ANSI control codes to the terminal, read_key_event and on_key_event will not support extended key codes and/or mouse events.
27 |
# File 'lib/terminal.rb', line 27 def ansi? = @ansi |
.application ⇒ Symbol? (readonly)
Terminal application identifier.
The detection supports a wide range of terminal emulators but may return
nil if an unsupported terminal was found. These are the supported
application IDs:
:alacritty, :amiga, :code_edit, :dg_unix, :docker, :fluent,
:hpterm, :hyper, :iterm, :macos, :mintty, :ms_terminal,
:ncr260, :nsterm, :terminator, :terminology, :termite,
:vt100, :warp, :wezterm, :wyse, :xnuppc
41 |
# File 'lib/terminal.rb', line 41 def application = (@application ||= Detect.application) |
.colors ⇒ Integer (readonly)
Number of supported colors. The detection checks various conditions to find the correct value. The most common values are
16_777_216for 24-bit encoding (true_color? return true)256for 8-Bit encoding52for some Unix terminals with an extended color palette8for 3-/4-bit encoding2if ANSI is not supported in general (ansi? return false)
55 |
# File 'lib/terminal.rb', line 55 def colors = (@colors ||= ansi? ? Detect.colors : 2) |
.columns ⇒ Integer
Screen column count. See size for support and detection details.
62 |
# File 'lib/terminal.rb', line 62 def columns = size[1] |
.input_mode ⇒ :csi_u, ... (readonly)
Supported input mode.
20 21 22 |
# File 'lib/terminal/input.rb', line 20 def input_mode @input_mode ||= find_input_mode end |
.pos ⇒ [Integer, Integer]?
Current cursor position. This is only available when ANSI is supported (ansi? return true).
75 76 77 78 79 |
# File 'lib/terminal.rb', line 75 def pos @con&.cursor rescue IOError @con = nil end |
.rows ⇒ Integer
Screen row count. See size for support and detection details.
93 |
# File 'lib/terminal.rb', line 93 def rows = size[0] |
.size ⇒ [Integer, Integer]
Screen size as a tuple of rows and columns.
If the terminal does not support the report of it's dimension or ANSI
is not supported in general then environment variables COLUMNS and
LINES will be used.
If this failed [25, 80] will be returned as default.
Setting the terminal size is not widely supported.
114 115 116 117 118 119 |
# File 'lib/terminal.rb', line 114 def size @size ||= @inf&.winsize || _default_size rescue IOError @inf = nil @size = _default_size end |
.true_color? ⇒ Boolean (readonly)
Returns whether true colors are supported.
131 |
# File 'lib/terminal.rb', line 131 def true_color? = (colors == 16_777_216) |
Class Method Details
.<<(object) ⇒ Terminal
Writes the given object to the terminal. Interprets embedded BBCode.
186 187 188 189 190 191 192 |
# File 'lib/terminal.rb', line 186 def <<(object) @out.write(Ansi.bbcode(object)) if @out && object != nil self rescue IOError @out = nil self end |
.hide_alt_screen ⇒ Terminal
Hide the alternate screen. Will not send the control code if the alternate screen is not used.
When you called show_alt_screen n-times you need to call hide_alt_screen n-times to show the default screen again.
176 177 178 179 |
# File 'lib/terminal.rb', line 176 def hide_alt_screen raw_write(Ansi::SCREEN_ALTERNATE_OFF) if @as > 0 && (@as -= 1).zero? self end |
.hide_cursor ⇒ Terminal
Hide the cursor. Will not send the control code if the cursor is already hidden.
When you called hide_cursor n-times you need to call show_cursor n-times to show the cursor again.
140 141 142 143 |
# File 'lib/terminal.rb', line 140 def hide_cursor raw_write(Ansi::CURSOR_HIDE) if ansi? && (@cc += 1) == 1 self end |
.on_key_event(mouse: false, mouse_move: false, focus: false) {|event| ... } ⇒ true, ...
Event loop for key and mouse events.
81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/terminal/input.rb', line 81 def on_key_event(mouse: false, mouse_move: false, focus: false, &block) return unless block case input_mode when :dumb on_bumb_key_event(&block) true when :csi_u, :legacy on_tty_key_event(mouse, mouse_move, focus, &block) true else false end end |
.print(*objects, bbcode: true) ⇒ nil
Writes the given objects to the terminal. Optionally interprets embedded BBCode.
200 201 202 203 204 205 206 207 |
# File 'lib/terminal.rb', line 200 def print(*objects, bbcode: true) return unless @out return @out.print(*objects) unless bbcode objects.each { @out.write(Ansi.bbcode(_1)) } nil rescue IOError @out = nil end |
.puts(*objects, bbcode: true) ⇒ nil
Writes the given objects to the terminal. Writes a newline after each object that does not already end with a newline sequence in it's String represenation. If called without any arguments, writes a newline only.
Optionally interprets embedded BBCode.
218 219 220 221 222 223 224 225 226 |
# File 'lib/terminal.rb', line 218 def puts(*objects, bbcode: true) return unless @out return @out.puts if objects.empty? return @out.puts(objects) unless bbcode objects.flatten! objects.empty? ? @out.puts : @out.puts(objects.map! { Ansi.bbcode(_1) }) rescue IOError @out = nil end |
.read_key(mode: :named) ⇒ String, ...
Use rather read_key_event for better input handling.
Read next keyboard input.
The input will be returned as named key codes like "Ctrl+c" by default.
This can be changed by mode.
36 37 38 39 40 41 42 43 44 45 |
# File 'lib/terminal/input.rb', line 36 def read_key(mode: :named) warn( 'Terminal.read_key is deprecaded; use Terminal.read_key_event instead.', uplevel: 1 ) event = read_key_event or return return event.raw if mode == :raw key, name = event mode == :both ? [key, name] : name || key end |
.read_key_event ⇒ KeyEvent?
Read next KeyEvent from standard input.
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/terminal/input.rb', line 51 def read_key_event case input_mode when :dumb raw = read_dumb or return opts = @dumb_keys[raw.ord] if raw.size == 1 KeyEvent.new(raw, *opts) when :csi_u, :legacy raw = read_tty or return KeyEvent[raw] end end |
.sh(*cmd, **options) ⇒ [Process::Status, output, error]? .sh(*cmd, **options) {|line, type| ... } ⇒ Process::Status?
Execute a command and report command output line by line or capture the output.
278 279 280 281 282 283 284 285 286 287 288 289 |
# File 'lib/terminal.rb', line 278 def sh(*cmd, **, &block) return Shell.exec(cmd, **, &block) if block_given? out = [] err = [] [ Shell.exec(cmd, **) do |line, type| (type == :error ? err : out) << line end, out, err ] end |
.show_alt_screen ⇒ Terminal
Show the alternate screen. Will not send the control code if the alternate screen is already used.
When you called show_alt_screen n-times you need to call hide_alt_screen n-times to show the default screen again.
164 165 166 167 |
# File 'lib/terminal.rb', line 164 def show_alt_screen raw_write(Ansi::SCREEN_ALTERNATE) if ansi? && (@as += 1) == 1 self end |
.show_cursor ⇒ Terminal
Show the cursor. Will not send the control code if the cursor is not hidden.
When you called hide_cursor n-times you need to call show_cursor n-times to show the cursor again.
152 153 154 155 |
# File 'lib/terminal.rb', line 152 def show_cursor raw_write(Ansi::CURSOR_SHOW) if @cc > 0 && (@cc -= 1).zero? self end |