terminal_rb 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/terminal/ansi/screen_viewer.rb +5 -5
- data/lib/terminal/ansi.rb +17 -17
- data/lib/terminal/input/ansi.rb +21 -8
- data/lib/terminal/input/dumb.rb +1 -4
- data/lib/terminal/input/key_event.rb +7 -7
- data/lib/terminal/input.rb +5 -6
- data/lib/terminal/output/ansi.rb +1 -0
- data/lib/terminal/output/dumb.rb +2 -1
- data/lib/terminal/output.rb +4 -4
- data/lib/terminal/rspec/helper.rb +9 -9
- data/lib/terminal/shell.rb +1 -1
- data/lib/terminal/text/formatter.rb +32 -25
- data/lib/terminal/text.rb +1 -1
- data/lib/terminal/version.rb +1 -1
- data/lib/terminal.rb +27 -27
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8f2f93f672f13936c9415cf3a474533df0f5785da3272f3482a02842a0607917
|
|
4
|
+
data.tar.gz: 52a1498c80085ea7667b7641416f406ae8694e02505a0c3201efd5f150f8d986
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 41cfbe3e34fa3db0af51674dc0f70f32dd08fb20d2b3a1040eff2834c65440f917f2ecea021500037658fbcf613373148c8399fdb29b7ea987916e71c570a65d
|
|
7
|
+
data.tar.gz: b6485ac5e2a9ba17ec72ffadc94cad6f5348ab846f885d12e9a68a338c15baeaa0d564ce1e1a4d2f946505887782e02dfd7221fc03e60bd3e7bb40afb88b47a1
|
data/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Terminal.rb v1.0.
|
|
1
|
+
# Terminal.rb v1.0.6
|
|
2
2
|
|
|
3
3
|
Terminal.rb supports you with input and output on your terminal. Simple [BBCode](https://en.wikipedia.org/wiki/BBCode)-like markup for attributes and coloring, word-wise line breaks, correct special key recognition and mouse event reporting enable you to implement your CLI app quickly and easily.
|
|
4
4
|
|
|
5
5
|
- Gem: [rubygems.org](https://rubygems.org/gems/terminal_rb)
|
|
6
6
|
- Source: [codeberg.org](https://codeberg.org/mblumtritt/Terminal.rb)
|
|
7
|
-
- Help: [rubydoc.info](https://rubydoc.info/gems/terminal_rb/1.0.
|
|
7
|
+
- Help: [rubydoc.info](https://rubydoc.info/gems/terminal_rb/1.0.6/Terminal)
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
@@ -52,7 +52,7 @@ module Terminal
|
|
|
52
52
|
# Total number of lines.
|
|
53
53
|
#
|
|
54
54
|
# @attribute [r] line_count
|
|
55
|
-
# @return [Integer, nil]
|
|
55
|
+
# @return [Integer, nil] `nil` when not already calculated
|
|
56
56
|
def line_count = @buf&.size
|
|
57
57
|
|
|
58
58
|
# Index of the topmost visible line.
|
|
@@ -68,7 +68,7 @@ module Terminal
|
|
|
68
68
|
|
|
69
69
|
# Resize to the current terminal dimensions and redraw.
|
|
70
70
|
#
|
|
71
|
-
# @return [self, nil]
|
|
71
|
+
# @return [self, nil] `nil` when resize is not required
|
|
72
72
|
def resize_to_screen = _resize(*Terminal.size)
|
|
73
73
|
|
|
74
74
|
# Resize to specific dimensions (clamped to terminal bounds)
|
|
@@ -76,7 +76,7 @@ module Terminal
|
|
|
76
76
|
#
|
|
77
77
|
# @param rows [Integer] new row count
|
|
78
78
|
# @param columns [Integer] new column count
|
|
79
|
-
# @return [self, nil]
|
|
79
|
+
# @return [self, nil] `nil` when resize is not required
|
|
80
80
|
def resize(rows, columns)
|
|
81
81
|
_resize(
|
|
82
82
|
rows.clamp(1, Terminal.rows),
|
|
@@ -99,7 +99,7 @@ module Terminal
|
|
|
99
99
|
|
|
100
100
|
# Scroll to the beginning of the content.
|
|
101
101
|
#
|
|
102
|
-
# @return [self, nil]
|
|
102
|
+
# @return [self, nil] `nil` when already on begin
|
|
103
103
|
def begin
|
|
104
104
|
return draw unless @buf
|
|
105
105
|
return if @line_top == 0
|
|
@@ -109,7 +109,7 @@ module Terminal
|
|
|
109
109
|
|
|
110
110
|
# Scroll to the end of the content.
|
|
111
111
|
#
|
|
112
|
-
# @return [self, nil]
|
|
112
|
+
# @return [self, nil] `nil` when already on end
|
|
113
113
|
def end
|
|
114
114
|
return draw unless @buf
|
|
115
115
|
idx = @buf.size - @rows_visible
|
data/lib/terminal/ansi.rb
CHANGED
|
@@ -45,7 +45,7 @@ module Terminal
|
|
|
45
45
|
# Generate an ANSI escape sequence from attribute names or color
|
|
46
46
|
# indices.
|
|
47
47
|
#
|
|
48
|
-
# Accepts symbols (`:bold`,
|
|
48
|
+
# Accepts symbols (`:bold`, `:red`), strings (`"bold"`, `"#ff0000"`),
|
|
49
49
|
# or integers for 256-color palette (0-255 foreground, 256-511
|
|
50
50
|
# background, 512-767 underline color).
|
|
51
51
|
#
|
|
@@ -122,11 +122,11 @@ module Terminal
|
|
|
122
122
|
#
|
|
123
123
|
# @example
|
|
124
124
|
# Terminal::Ansi.try_convert('bold red') # => "\e[1;31m"
|
|
125
|
-
# Terminal::Ansi.try_convert('invalid')
|
|
125
|
+
# Terminal::Ansi.try_convert('invalid') # => nil
|
|
126
126
|
#
|
|
127
127
|
# @param attributes [#to_s] space-separated attribute names
|
|
128
128
|
# @param separator [String] delimiter for splitting
|
|
129
|
-
# @return [String, nil] ANSI escape sequence, or
|
|
129
|
+
# @return [String, nil] ANSI escape sequence, or `nil` if any
|
|
130
130
|
# attribute is invalid
|
|
131
131
|
def try_convert(attributes, separator: ' ')
|
|
132
132
|
return unless attributes
|
|
@@ -168,9 +168,9 @@ module Terminal
|
|
|
168
168
|
|
|
169
169
|
# Convert BBCode markup to ANSI escape codes.
|
|
170
170
|
#
|
|
171
|
-
# Tags like
|
|
172
|
-
#
|
|
173
|
-
# Escape a tag with a backslash:
|
|
171
|
+
# Tags like `[bold]` are converted to their ANSI equivalents;
|
|
172
|
+
# `[/bold]` or `[/]` resets. Unknown tags are left unchanged.
|
|
173
|
+
# Escape a tag with a backslash: `[\\bold]` renders as `[bold]`.
|
|
174
174
|
#
|
|
175
175
|
# @see .unbbcode
|
|
176
176
|
# @see .plain
|
|
@@ -361,7 +361,7 @@ module Terminal
|
|
|
361
361
|
# Terminal::Ansi.cursor_pos(1, 1) # home position
|
|
362
362
|
# Terminal::Ansi.cursor_pos(10, 5) # row 10, column 5
|
|
363
363
|
#
|
|
364
|
-
# @param row [Integer, nil] row number;
|
|
364
|
+
# @param row [Integer, nil] row number; `nil` moves to home
|
|
365
365
|
# @param column [Integer, nil] column number
|
|
366
366
|
# @return (see .[])
|
|
367
367
|
def cursor_pos(row, column = nil)
|
|
@@ -396,7 +396,7 @@ module Terminal
|
|
|
396
396
|
# Erase part of the screen.
|
|
397
397
|
#
|
|
398
398
|
# @param part [Symbol] area to erase:
|
|
399
|
-
#
|
|
399
|
+
# `:all`, `:below`, `:above`, or `:scrollback`
|
|
400
400
|
# @return (see .[])
|
|
401
401
|
def screen_erase(part = :all) = "\e[#{@screen_erase[part]}J"
|
|
402
402
|
|
|
@@ -449,7 +449,7 @@ module Terminal
|
|
|
449
449
|
# Erase part of the current line.
|
|
450
450
|
#
|
|
451
451
|
# @param part [Symbol] area to erase:
|
|
452
|
-
#
|
|
452
|
+
# `:all`, `:to_end`, or `:to_start`
|
|
453
453
|
# @return (see .[])
|
|
454
454
|
def line_erase(part = :all) = "\e[#{@line_erase[part]}K"
|
|
455
455
|
|
|
@@ -472,7 +472,7 @@ module Terminal
|
|
|
472
472
|
# @see .link_end
|
|
473
473
|
#
|
|
474
474
|
# @param url [#to_s] the link URL
|
|
475
|
-
# @param params [Hash] optional link parameters (e.g.,
|
|
475
|
+
# @param params [Hash] optional link parameters (e.g., `id:`)
|
|
476
476
|
# @return (see .[])
|
|
477
477
|
def link_start(url, **params)
|
|
478
478
|
"\e]8;#{params.map { it.join('=') }.join(':')};#{url}\a"
|
|
@@ -520,12 +520,12 @@ module Terminal
|
|
|
520
520
|
# Terminal.raw_write(Terminal::Ansi.progress(:error)) # error state
|
|
521
521
|
# Terminal.raw_write(Terminal::Ansi.progress(nil)) # hide
|
|
522
522
|
#
|
|
523
|
-
# @param state [Symbol, Numeric,
|
|
524
|
-
# -
|
|
525
|
-
#
|
|
523
|
+
# @param state [Symbol, Numeric, true, false] progress state:
|
|
524
|
+
# - `:show` or `true` to show, `:err`/`:error`, `:warn`/`:warning`,
|
|
525
|
+
# `:indeterminate`, a `Numeric` (0-100) to set percentage, or
|
|
526
526
|
# any other value to hide
|
|
527
|
-
# @param percent [
|
|
528
|
-
#
|
|
527
|
+
# @param percent [#to_i] progress percentage (0-100, used with
|
|
528
|
+
# `:show` state)
|
|
529
529
|
# @return (see .[])
|
|
530
530
|
def progress(state, percent = 0)
|
|
531
531
|
case state
|
|
@@ -563,9 +563,9 @@ module Terminal
|
|
|
563
563
|
# @param fracd [Integer, nil] fractional denominator
|
|
564
564
|
# (must be > fracn, max 15)
|
|
565
565
|
# @param vertical [Symbol, Integer, nil] vertical alignment:
|
|
566
|
-
#
|
|
566
|
+
# `:top`, `:bottom`, `:middle`
|
|
567
567
|
# @param horizontal [Symbol, Integer, nil] horizontal alignment:
|
|
568
|
-
#
|
|
568
|
+
# `:left`, `:right`, `:center`
|
|
569
569
|
# @return (see .[])
|
|
570
570
|
def scale(
|
|
571
571
|
text,
|
data/lib/terminal/input/ansi.rb
CHANGED
|
@@ -6,14 +6,13 @@ module Terminal
|
|
|
6
6
|
attr_reader :input_mode
|
|
7
7
|
|
|
8
8
|
def on_key_event(mouse: false, mouse_move: false, focus: false)
|
|
9
|
-
raise('already reading key events') if (@in_recursion += 1) != 1
|
|
10
9
|
return unless block_given?
|
|
11
|
-
opts =
|
|
10
|
+
opts = nil
|
|
12
11
|
STDIN.noecho do
|
|
13
|
-
opts
|
|
12
|
+
opts = __input_options(mouse, mouse_move, focus)
|
|
14
13
|
while (raw = @in.getch)
|
|
15
14
|
next yield(KeyEvent[raw]) if raw != "\e"
|
|
16
|
-
while
|
|
15
|
+
while (nc = @in.read_nonblock(1, exception: false)).is_a?(String)
|
|
17
16
|
raw << nc
|
|
18
17
|
end
|
|
19
18
|
next yield(KeyEvent[raw]) if raw.rindex("\e") < 2
|
|
@@ -25,13 +24,15 @@ module Terminal
|
|
|
25
24
|
__input_error
|
|
26
25
|
false
|
|
27
26
|
ensure
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
if opts
|
|
28
|
+
@in_opts.pop
|
|
29
|
+
@in&.syswrite(opts)
|
|
30
|
+
end
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
private
|
|
33
34
|
|
|
34
|
-
def
|
|
35
|
+
def __input_options(mouse, mouse_move, focus)
|
|
35
36
|
opts = (mouse ? ['1000'] : [])
|
|
36
37
|
# highlight: '1001'
|
|
37
38
|
# drag: '1002'
|
|
@@ -41,7 +42,19 @@ module Terminal
|
|
|
41
42
|
# sgr: '1006'
|
|
42
43
|
# urxvt: '1015'
|
|
43
44
|
# pixel: '1016'
|
|
44
|
-
|
|
45
|
+
if (last = @in_opts[-1])
|
|
46
|
+
if opts.empty?
|
|
47
|
+
@in.syswrite("#{last}l")
|
|
48
|
+
return "#{last}h"
|
|
49
|
+
end
|
|
50
|
+
@in_opts << (opts = "\e[?#{opts.join(';')};1006")
|
|
51
|
+
@in.syswrite("#{last}l#{opts}h")
|
|
52
|
+
return "#{opts}l#{last}h"
|
|
53
|
+
end
|
|
54
|
+
return if opts.empty?
|
|
55
|
+
@in_opts << (opts = "\e[?#{opts.join(';')};1006")
|
|
56
|
+
@in.syswrite("#{opts}h")
|
|
57
|
+
"#{opts}l"
|
|
45
58
|
end
|
|
46
59
|
end
|
|
47
60
|
|
data/lib/terminal/input/dumb.rb
CHANGED
|
@@ -5,8 +5,7 @@ module Terminal
|
|
|
5
5
|
module DumpInput
|
|
6
6
|
def input_mode = :dumb
|
|
7
7
|
|
|
8
|
-
def on_key_event(*
|
|
9
|
-
raise('already reading key events') if (@in_recursion += 1) != 1
|
|
8
|
+
def on_key_event(*)
|
|
10
9
|
return unless block_given?
|
|
11
10
|
while (raw = STDIN.getc)
|
|
12
11
|
opts = dumb_keys[raw.ord] if raw.size == 1
|
|
@@ -17,8 +16,6 @@ module Terminal
|
|
|
17
16
|
rescue IOError, SystemCallError
|
|
18
17
|
__input_error
|
|
19
18
|
false
|
|
20
|
-
ensure
|
|
21
|
-
@in_recursion -= 1
|
|
22
19
|
end
|
|
23
20
|
|
|
24
21
|
private
|
|
@@ -23,8 +23,8 @@ module Terminal
|
|
|
23
23
|
class KeyEvent
|
|
24
24
|
# The key identifier.
|
|
25
25
|
#
|
|
26
|
-
# @return [Symbol, String, nil] a named key like
|
|
27
|
-
#
|
|
26
|
+
# @return [Symbol, String, nil] a named key like `:Enter`, `:Tab`,
|
|
27
|
+
# `:MBLeft` (mouse), or a character string like `"a"`; `nil` for
|
|
28
28
|
# unknown sequences
|
|
29
29
|
attr_reader :key
|
|
30
30
|
|
|
@@ -61,8 +61,8 @@ module Terminal
|
|
|
61
61
|
|
|
62
62
|
# Mouse position when this is a mouse event.
|
|
63
63
|
#
|
|
64
|
-
# @return [Array<Integer, Integer>, nil]
|
|
65
|
-
# events,
|
|
64
|
+
# @return [Array<Integer, Integer>, nil] `[row, column]` for mouse
|
|
65
|
+
# events, `nil` for keyboard events
|
|
66
66
|
attr_reader :position
|
|
67
67
|
|
|
68
68
|
# The raw input sequence as received from the terminal.
|
|
@@ -85,8 +85,8 @@ module Terminal
|
|
|
85
85
|
# @private
|
|
86
86
|
# Destructuring-friendly array representation.
|
|
87
87
|
#
|
|
88
|
-
# @return [Array<String>]
|
|
89
|
-
# @return [Array<String, String>]
|
|
88
|
+
# @return [Array<String>] `[raw]` if {#simple?}
|
|
89
|
+
# @return [Array<String, String>] `[raw, name]` otherwise
|
|
90
90
|
def to_ary = simple? ? [@raw] : [@raw, @name]
|
|
91
91
|
|
|
92
92
|
# @return [String] the event {#name}
|
|
@@ -140,7 +140,7 @@ module Terminal
|
|
|
140
140
|
@names ||=
|
|
141
141
|
(@csiu.values + @csi.values + @ss3.values)
|
|
142
142
|
.uniq
|
|
143
|
-
.keep_if { Symbol
|
|
143
|
+
.keep_if { it.is_a?(Symbol) }
|
|
144
144
|
.sort!
|
|
145
145
|
).dup
|
|
146
146
|
end
|
data/lib/terminal/input.rb
CHANGED
|
@@ -15,7 +15,7 @@ module Terminal
|
|
|
15
15
|
# Terminal.input_mode # => :csi_u
|
|
16
16
|
#
|
|
17
17
|
# @attribute [r] input_mode
|
|
18
|
-
# @return [Symbol]
|
|
18
|
+
# @return [Symbol] `:csi_u`, `:legacy`, `:dumb`, or `:error`
|
|
19
19
|
|
|
20
20
|
#
|
|
21
21
|
# @!endgroup
|
|
@@ -42,8 +42,7 @@ module Terminal
|
|
|
42
42
|
# @param focus [true, false] enable terminal focus/unfocus events
|
|
43
43
|
# @yield [event] called for each input event
|
|
44
44
|
# @yieldparam event [KeyEvent] the parsed key event
|
|
45
|
-
# @return [nil, false]
|
|
46
|
-
# @raise [RuntimeError] if already inside a key event loop
|
|
45
|
+
# @return [nil, false] `false` on I/O error
|
|
47
46
|
|
|
48
47
|
# @!method self.read_key_event
|
|
49
48
|
#
|
|
@@ -53,7 +52,7 @@ module Terminal
|
|
|
53
52
|
# event = Terminal.read_key_event
|
|
54
53
|
# puts "You pressed: #{event.name}"
|
|
55
54
|
#
|
|
56
|
-
# @return [KeyEvent, false] the next key event, or
|
|
55
|
+
# @return [KeyEvent, false] the next key event, or `false` on error
|
|
57
56
|
|
|
58
57
|
#
|
|
59
58
|
# @!endgroup
|
|
@@ -62,10 +61,10 @@ module Terminal
|
|
|
62
61
|
# @private
|
|
63
62
|
module Input
|
|
64
63
|
def input_mode
|
|
65
|
-
@in_recursion = 0
|
|
66
64
|
case @input_mode = __find_input_mode
|
|
67
65
|
when :legacy, :csi_u
|
|
68
66
|
@in = IO.console
|
|
67
|
+
@in_opts = []
|
|
69
68
|
require_relative('input/ansi')
|
|
70
69
|
extend AnsiInput
|
|
71
70
|
when :dumb
|
|
@@ -105,7 +104,7 @@ module Terminal
|
|
|
105
104
|
con = IO.console
|
|
106
105
|
STDIN.noecho do
|
|
107
106
|
return :legacy if con.syswrite("\e[>1u\e[?u\e[c") != 12
|
|
108
|
-
inp =
|
|
107
|
+
inp = ''.b
|
|
109
108
|
inp << con.getch until inp.rindex('c')
|
|
110
109
|
return :legacy unless inp.include?("\e[?1u")
|
|
111
110
|
end
|
data/lib/terminal/output/ansi.rb
CHANGED
data/lib/terminal/output/dumb.rb
CHANGED
|
@@ -67,13 +67,14 @@ module Terminal
|
|
|
67
67
|
suffix: nil
|
|
68
68
|
)
|
|
69
69
|
objects.flatten!
|
|
70
|
+
return @out.puts if objects.empty?
|
|
70
71
|
@out.puts(
|
|
71
72
|
Text::Formatter.format(
|
|
72
73
|
*objects,
|
|
73
74
|
ansi: false,
|
|
74
75
|
bbcode:,
|
|
75
76
|
spaces:,
|
|
76
|
-
eol
|
|
77
|
+
eol:,
|
|
77
78
|
align:,
|
|
78
79
|
width:,
|
|
79
80
|
height:,
|
data/lib/terminal/output.rb
CHANGED
|
@@ -66,7 +66,7 @@ module Terminal
|
|
|
66
66
|
#
|
|
67
67
|
# The terminal size.
|
|
68
68
|
#
|
|
69
|
-
# @return [Array<Integer, Integer>]
|
|
69
|
+
# @return [Array<Integer, Integer>] `[rows, columns]`
|
|
70
70
|
|
|
71
71
|
# Terminal width in columns.
|
|
72
72
|
#
|
|
@@ -89,7 +89,7 @@ module Terminal
|
|
|
89
89
|
# Current cursor position.
|
|
90
90
|
# This is only available when ANSI is supported ({ansi?} return true).
|
|
91
91
|
#
|
|
92
|
-
# @return [Array<Integer, Integer>, nil]
|
|
92
|
+
# @return [Array<Integer, Integer>, nil] `[row, column]` or `nil` if
|
|
93
93
|
# unavailable
|
|
94
94
|
|
|
95
95
|
# Whether the terminal has been resized since the last size query.
|
|
@@ -113,7 +113,7 @@ module Terminal
|
|
|
113
113
|
# @example
|
|
114
114
|
# Terminal << '[bold]Hello[/bold] World'
|
|
115
115
|
#
|
|
116
|
-
# @param object [#to_s, nil] the object to output;
|
|
116
|
+
# @param object [#to_s, nil] the object to output; `nil` is ignored
|
|
117
117
|
# @return [self]
|
|
118
118
|
|
|
119
119
|
# @!method print(*objects, bbcode: true)
|
|
@@ -162,7 +162,7 @@ module Terminal
|
|
|
162
162
|
# processing.
|
|
163
163
|
#
|
|
164
164
|
# @param object [#to_s] object to write
|
|
165
|
-
# @return [Integer, nil] bytes written, or
|
|
165
|
+
# @return [Integer, nil] bytes written, or `nil` on error
|
|
166
166
|
|
|
167
167
|
# @!method hide_cursor
|
|
168
168
|
#
|
|
@@ -4,9 +4,9 @@ require 'stringio'
|
|
|
4
4
|
|
|
5
5
|
# RSpec shared context for testing code that uses Terminal.rb.
|
|
6
6
|
#
|
|
7
|
-
# Stubs all Terminal I/O methods and provides
|
|
8
|
-
#
|
|
9
|
-
# input is read from the
|
|
7
|
+
# Stubs all Terminal I/O methods and provides `stdout`, `stdin`, and
|
|
8
|
+
# `stdoutstr` test helpers. Output is captured into the `stdout` array;
|
|
9
|
+
# input is read from the `stdin` array.
|
|
10
10
|
#
|
|
11
11
|
# @example Basic usage
|
|
12
12
|
# RSpec.describe MyClass do
|
|
@@ -22,15 +22,15 @@ require 'stringio'
|
|
|
22
22
|
# include_context 'with Terminal.rb', ansi: false, colors: 8,
|
|
23
23
|
# size: [40, 120]
|
|
24
24
|
#
|
|
25
|
-
# @param ansi [true, false] mock ANSI support (default:
|
|
25
|
+
# @param ansi [true, false] mock ANSI support (default: `true`)
|
|
26
26
|
# @param application [Symbol] mock terminal application
|
|
27
|
-
# (default:
|
|
28
|
-
# @param colors [Integer, Symbol] mock color depth; use
|
|
29
|
-
# for 16777216 (default:
|
|
27
|
+
# (default: `:kitty`)
|
|
28
|
+
# @param colors [Integer, Symbol] mock color depth; use `:true_color`
|
|
29
|
+
# for 16777216 (default: `256`)
|
|
30
30
|
# @param size [Array<Integer, Integer>] mock terminal size as
|
|
31
|
-
#
|
|
31
|
+
# `[rows, columns]` (default: `[25, 80]`)
|
|
32
32
|
# @param pos [Array<Integer, Integer>] mock cursor position as
|
|
33
|
-
#
|
|
33
|
+
# `[row, column]` (default: `[1, 1]`)
|
|
34
34
|
RSpec.shared_context 'with Terminal.rb' do |ansi: true, application: :kitty, colors: 256, size: [25, 80], pos: [1, 1]|
|
|
35
35
|
let(:stdout) { StringIO.new }
|
|
36
36
|
let(:stdout_lines) { stdout.string.lines(chomp: true) }
|
data/lib/terminal/shell.rb
CHANGED
|
@@ -77,7 +77,7 @@ module Terminal
|
|
|
77
77
|
return unless obj
|
|
78
78
|
return copy_writer(obj) if obj.respond_to?(:readpartial)
|
|
79
79
|
return copy_writer(obj.to_io) if obj.respond_to?(:to_io)
|
|
80
|
-
return array_writer(obj) if Array
|
|
80
|
+
return array_writer(obj) if obj.is_a?(Array)
|
|
81
81
|
if obj.respond_to?(:each)
|
|
82
82
|
return enum_writer(obj.enum_for(:each)) if obj.respond_to?(:enum_for)
|
|
83
83
|
return enum_writer(Enumerator.new { |y| obj.each { y << it } })
|
|
@@ -32,8 +32,8 @@ module Terminal
|
|
|
32
32
|
# # => [["Hello", 5]]
|
|
33
33
|
#
|
|
34
34
|
# @param (see #initialize)
|
|
35
|
-
# @param with_size [true, false] when
|
|
36
|
-
# return
|
|
35
|
+
# @param with_size [true, false] when `true`,
|
|
36
|
+
# return `[line, width]` pairs instead of plain strings
|
|
37
37
|
# @param (see #lines_with_size)
|
|
38
38
|
# @return (see #lines_with_size)
|
|
39
39
|
def self.[](
|
|
@@ -86,17 +86,23 @@ module Terminal
|
|
|
86
86
|
# @param ansi [true, false] recognize ANSI escape codes
|
|
87
87
|
# @param bbcode [true, false] process BBCode markup
|
|
88
88
|
# @param spaces [true, false] preserve whitespace;
|
|
89
|
-
# when
|
|
89
|
+
# when `false` leading/trailing spaces and multiple spaces are
|
|
90
90
|
# collapsed
|
|
91
91
|
# @param eol [true, false] preserve line endings;
|
|
92
|
-
# when
|
|
92
|
+
# when `false` newlines are treated as spaces
|
|
93
93
|
def initialize(*str, ansi: true, bbcode: true, spaces: true, eol: true)
|
|
94
94
|
@lex = []
|
|
95
95
|
return if str.empty?
|
|
96
96
|
ansi ? _generate_ansi(str, bbcode) : _generate(str, bbcode)
|
|
97
97
|
return if @lex.empty?
|
|
98
|
+
@keep_paragraph = true
|
|
98
99
|
@lex = _ignore_whitespace unless spaces
|
|
99
|
-
|
|
100
|
+
case eol
|
|
101
|
+
when false, nil
|
|
102
|
+
@lex = _ignore_newline
|
|
103
|
+
when :no_paragraph
|
|
104
|
+
@keep_paragraph = false
|
|
105
|
+
end
|
|
100
106
|
end
|
|
101
107
|
|
|
102
108
|
# Word-wrap and return lines with their display widths.
|
|
@@ -106,10 +112,10 @@ module Terminal
|
|
|
106
112
|
# fmt.lines_with_size(width: 5)
|
|
107
113
|
# # => [["Hello", 5], ["World", 5]]
|
|
108
114
|
#
|
|
109
|
-
# @param width [
|
|
110
|
-
#
|
|
115
|
+
# @param width [#to_i, nil] maximum line width in columns;
|
|
116
|
+
# `nil` returns unwrapped lines
|
|
111
117
|
# @return [Array<String, Integer>] pairs of
|
|
112
|
-
#
|
|
118
|
+
# `[line_text, display_width]`
|
|
113
119
|
# @raise (see #format)
|
|
114
120
|
def lines_with_size(width: nil)
|
|
115
121
|
return [] if @lex.empty?
|
|
@@ -125,9 +131,9 @@ module Terminal
|
|
|
125
131
|
# fmt.lines(width: 5)
|
|
126
132
|
# # => ["Hello", "World"]
|
|
127
133
|
#
|
|
128
|
-
# @param width [
|
|
134
|
+
# @param width [#to_i, nil] maximum line width in columns
|
|
129
135
|
# @return [Array<String>]
|
|
130
|
-
# @raise [ArgumentError] if
|
|
136
|
+
# @raise [ArgumentError] if `width` is zero or negative
|
|
131
137
|
def lines(width: nil) = lines_with_size(width:).map(&:first)
|
|
132
138
|
|
|
133
139
|
# Format lines with alignment, padding, and decorations.
|
|
@@ -138,11 +144,11 @@ module Terminal
|
|
|
138
144
|
# # => [" Hi "]
|
|
139
145
|
#
|
|
140
146
|
# @param align [Symbol, nil] text alignment:
|
|
141
|
-
#
|
|
142
|
-
# @param width [
|
|
143
|
-
# @param height [
|
|
147
|
+
# `:left`, `:right`, `:center`, or `nil` (no fill)
|
|
148
|
+
# @param width [#to_i, nil] output line width in columns
|
|
149
|
+
# @param height [#to_i, nil] number of output lines;
|
|
144
150
|
# negative values take lines from the end
|
|
145
|
-
# @param padding [
|
|
151
|
+
# @param padding [#to_i, Array, nil] CSS-style padding
|
|
146
152
|
# - 1 value: all sides;
|
|
147
153
|
# - 2 values: [vertical, horizontal];
|
|
148
154
|
# - 3 values: [top, horizontal, bottom];
|
|
@@ -150,7 +156,7 @@ module Terminal
|
|
|
150
156
|
# @param prefix [#to_s, nil] string prepended to each line
|
|
151
157
|
# @param suffix [#to_s, nil] string appended to each line
|
|
152
158
|
# @return [Array<String>] formatted output lines
|
|
153
|
-
# @raise [ArgumentError] if
|
|
159
|
+
# @raise [ArgumentError] if `width` is zero or negative
|
|
154
160
|
def format(
|
|
155
161
|
align: nil,
|
|
156
162
|
width: nil,
|
|
@@ -226,7 +232,7 @@ module Terminal
|
|
|
226
232
|
# fmt = Terminal::Text::Formatter.new("short\na longer line")
|
|
227
233
|
# fmt.max_line_width # => 13
|
|
228
234
|
#
|
|
229
|
-
# @return [Integer] widest line in columns,
|
|
235
|
+
# @return [Integer] widest line in columns, `0` when empty
|
|
230
236
|
def max_line_width
|
|
231
237
|
@max_line_width ||=
|
|
232
238
|
(@lex.empty? ? 0 : (@unlimited || _unlimited).max_by(&:last)[-1])
|
|
@@ -239,7 +245,7 @@ module Terminal
|
|
|
239
245
|
# Terminal::Text::Formatter.new('Hello World').to_s(width: 5)
|
|
240
246
|
# # => "Hello\nWorld"
|
|
241
247
|
#
|
|
242
|
-
# @param width [
|
|
248
|
+
# @param width [#to_i, nil] maximum line width in columns
|
|
243
249
|
# @return [String]
|
|
244
250
|
def to_s(width: nil) = lines(width:).join("\n")
|
|
245
251
|
|
|
@@ -298,7 +304,7 @@ module Terminal
|
|
|
298
304
|
size -= last.size
|
|
299
305
|
next add_line.call
|
|
300
306
|
end
|
|
301
|
-
add_line.call if size > 0
|
|
307
|
+
add_line.call if (current != EOP) || (@keep_paragraph || size > 0)
|
|
302
308
|
next
|
|
303
309
|
end
|
|
304
310
|
|
|
@@ -510,7 +516,7 @@ module Terminal
|
|
|
510
516
|
# @private
|
|
511
517
|
class Space
|
|
512
518
|
attr_accessor :size
|
|
513
|
-
def to_str = (' ' * @size)
|
|
519
|
+
def to_str = (@size == 1 ? ' ' : ' ' * @size)
|
|
514
520
|
def initialize = (@size = 1)
|
|
515
521
|
def inc = (@size += 1)
|
|
516
522
|
def inspect = @size == 1 ? '<Space>' : "<Space #{@size}>"
|
|
@@ -568,7 +574,7 @@ module Terminal
|
|
|
568
574
|
class << self
|
|
569
575
|
attr_reader :to_str, :size, :inspect
|
|
570
576
|
end
|
|
571
|
-
@to_str =
|
|
577
|
+
@to_str = Ansi::RESET
|
|
572
578
|
@size = 0
|
|
573
579
|
@inspect = '<CsiEnd>'
|
|
574
580
|
end
|
|
@@ -584,11 +590,12 @@ module Terminal
|
|
|
584
590
|
|
|
585
591
|
ENCODING = Encoding::UTF_8
|
|
586
592
|
|
|
587
|
-
|
|
588
|
-
Hash
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
593
|
+
space_cache =
|
|
594
|
+
Hash.new { |h, s| h[s] = s < 1 ? '' : ' ' * s }.compare_by_identity
|
|
595
|
+
space_cache[0]
|
|
596
|
+
space_cache[1]
|
|
597
|
+
space_cache[2]
|
|
598
|
+
SPACE_CACHE = space_cache.freeze
|
|
592
599
|
|
|
593
600
|
SCAN_REGEX =
|
|
594
601
|
/\G(?:
|
data/lib/terminal/text.rb
CHANGED
|
@@ -28,7 +28,7 @@ module Terminal
|
|
|
28
28
|
# Terminal::Text.ambiguous_char_width # => 1
|
|
29
29
|
# Terminal::Text.ambiguous_char_width = 2 # for CJK terminals
|
|
30
30
|
#
|
|
31
|
-
# @return [Integer] default:
|
|
31
|
+
# @return [Integer] default: `1`
|
|
32
32
|
attr_accessor :ambiguous_char_width
|
|
33
33
|
|
|
34
34
|
# Calculate the display width of a string in terminal columns.
|
data/lib/terminal/version.rb
CHANGED
data/lib/terminal.rb
CHANGED
|
@@ -30,32 +30,32 @@ module Terminal
|
|
|
30
30
|
# Detect the terminal emulator application.
|
|
31
31
|
#
|
|
32
32
|
# Known applications:
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
-
#
|
|
33
|
+
# `:alacritty`,
|
|
34
|
+
# `:amiga`,
|
|
35
|
+
# `:code_edit`,
|
|
36
|
+
# `:dg_unix`,
|
|
37
|
+
# `:docker`,
|
|
38
|
+
# `:fluent`,
|
|
39
|
+
# `:hpterm`,
|
|
40
|
+
# `:hyper`,
|
|
41
|
+
# `:iterm`,
|
|
42
|
+
# `:kitty`,
|
|
43
|
+
# `:macos`,
|
|
44
|
+
# `:mintty`,
|
|
45
|
+
# `:ms_terminal`,
|
|
46
|
+
# `:ncr260`,
|
|
47
|
+
# `:nsterm`,
|
|
48
|
+
# `:terminator`,
|
|
49
|
+
# `:terminology`,
|
|
50
|
+
# `:termite`,
|
|
51
|
+
# `:vscode`,
|
|
52
|
+
# `:vt100`,
|
|
53
|
+
# `:warp`,
|
|
54
|
+
# `:wyse`,
|
|
55
|
+
# `:xnuppc`
|
|
56
56
|
#
|
|
57
|
-
# Any unrecognized
|
|
58
|
-
# symbol. Returns
|
|
57
|
+
# Any unrecognized `TERM_PROGRAM` value is converted to a sanitized
|
|
58
|
+
# symbol. Returns `nil` when no terminal can be identified.
|
|
59
59
|
#
|
|
60
60
|
# @example
|
|
61
61
|
# Terminal.application # => :kitty
|
|
@@ -77,7 +77,7 @@ module Terminal
|
|
|
77
77
|
# @param cmd [Array<String>] command and arguments
|
|
78
78
|
# @param options [Hash] options passed to the shell runner
|
|
79
79
|
# @return [Array<Process::Status, Array<String>, Array<String>>]
|
|
80
|
-
#
|
|
80
|
+
# `[status, stdout_lines, stderr_lines]`
|
|
81
81
|
# @example
|
|
82
82
|
# status, output, error = Terminal.sh('echo', 'hello')
|
|
83
83
|
# output # => ["hello\n"]
|
|
@@ -88,7 +88,7 @@ module Terminal
|
|
|
88
88
|
# @param options [Hash] options passed to the shell runner
|
|
89
89
|
# @yield [line, type] called for each output line
|
|
90
90
|
# @yieldparam line [String] the output line
|
|
91
|
-
# @yieldparam type [Symbol]
|
|
91
|
+
# @yieldparam type [Symbol] `:output` or `:error`
|
|
92
92
|
# @return [Process::Status] the exit status
|
|
93
93
|
# @example
|
|
94
94
|
# Terminal.sh('make') do |line, type|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: terminal_rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Blumtritt
|
|
@@ -60,13 +60,13 @@ metadata:
|
|
|
60
60
|
yard.run: yard
|
|
61
61
|
source_code_uri: https://codeberg.org/mblumtritt/Terminal.rb
|
|
62
62
|
bug_tracker_uri: https://codeberg.org/mblumtritt/Terminal.rb/issues
|
|
63
|
-
documentation_uri: https://rubydoc.info/gems/terminal_rb/1.0.
|
|
63
|
+
documentation_uri: https://rubydoc.info/gems/terminal_rb/1.0.6
|
|
64
64
|
rdoc_options: []
|
|
65
65
|
require_paths:
|
|
66
66
|
- lib
|
|
67
67
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
68
68
|
requirements:
|
|
69
|
-
- - "
|
|
69
|
+
- - ">="
|
|
70
70
|
- !ruby/object:Gem::Version
|
|
71
71
|
version: '3.4'
|
|
72
72
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
@@ -75,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
75
75
|
- !ruby/object:Gem::Version
|
|
76
76
|
version: '0'
|
|
77
77
|
requirements: []
|
|
78
|
-
rubygems_version: 4.0.
|
|
78
|
+
rubygems_version: 4.0.15
|
|
79
79
|
specification_version: 4
|
|
80
80
|
summary: Fast terminal access with ANSI, CSIu, mouse events, BBCode, word-wise line
|
|
81
81
|
break support and much more.
|