terminal_rb 0.16.0 → 0.16.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 05eda4c596ad7060b576cb01f6fe7dafd38e114274b44c14c4c90e1b3a2b322a
4
- data.tar.gz: '0479860569041d6fb874d38de0d183a2cc778a6803d3eed302425cd795133e06'
3
+ metadata.gz: c1c85e6d14f19a36f2efd995aa90b962ef24deaedeacd6ba5ba0392ae7d87f54
4
+ data.tar.gz: 99a8c94cbb3b79386fb1725378f4f7cfc6e97e1e4b93978cf6e67d0a1d0720a0
5
5
  SHA512:
6
- metadata.gz: ab038b9b4cc9ed41ba09673be9a2e2d25aa2edc2ffbf1fa0cad826ca7f55c8fef3aab734648f13f63750ea7799bce638479839e5f609e597eeb0bf4508b0f0e7
7
- data.tar.gz: b501721dfd7d6d79ceb8821fa5dd9d877e764e235435f3e6441e9b02b424a5873aba1318365a4b064a9430c135882be39470361d0042b56726be3dd2505e9db5
6
+ metadata.gz: 4d257376892920c46bd96c60a475953d169409552db6fc75a3e0f5f0613b34fe5bc3a2e18d77c53d05cf2670f0b81a02ba4ce237d83fb4c3299826d1c3e7cce8
7
+ data.tar.gz: 353f4ed0f0da7ad39ce7413335e31d89264e0587e12c450d6028c8fbfc5c30c986136e0babac12a146176d44c810aabdb403b52a13389a3900256f53cd5b96d8
data/README.md CHANGED
@@ -16,7 +16,7 @@ Terminal.rb supports you with input and output on your terminal. Simple [BBCode]
16
16
  - calculation for correct display width of strings containing Unicdode chars inclusive emojis
17
17
  - word-wise line break generator
18
18
  - supports [CSIu protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol)
19
- - mouse events support
19
+ - mouse events
20
20
 
21
21
  ## Examples
22
22
 
data/lib/terminal/ansi.rb CHANGED
@@ -571,7 +571,7 @@ module Terminal
571
571
 
572
572
  @re_test =
573
573
  /
574
- (?:\e\[[\d;:?]*[ABCDEFGHJKSTfminsuhl])
574
+ (?:\e\[[\x30-\x3f]*[\x20-\x2f]*[a-zA-Z])
575
575
  |
576
576
  (?:\e\]\d+(?:;[^\a\e]+)*(?:\a|\e\\))
577
577
  /x
@@ -5,13 +5,6 @@ module Terminal
5
5
  # Key event reported from {read_key_event} and {on_key_event}.
6
6
  #
7
7
  class KeyEvent
8
- # ANSI code sequence received from standard input.
9
- # This can be a simple value like `"a"`or more complex input like
10
- # `"\e[24;6~"` (for Shift+Ctrl+F12).
11
- #
12
- # @return [String] received ANSI code sequence
13
- attr_reader :raw
14
-
15
8
  # Pressed key without any modifiers.
16
9
  # This can be a string for simple keys like `"a"` or a Symbol like `:F12`
17
10
  # (see {.key_names}).
@@ -24,11 +17,9 @@ module Terminal
24
17
  # @return [Integer] modifier key code
25
18
  attr_reader :modifier
26
19
 
27
- # Mouse event position.
28
- #
29
- # @return [[Integer,Integer]] row and column
30
- # @return nil when no coordinates are assigned
31
- attr_reader :position
20
+ # @attribute [r] modifier?
21
+ # @return [true, false] whether a key modifier was pressed
22
+ def modifier? = @modifier != 0
32
23
 
33
24
  # Name of the key event.
34
25
  # This can be a simple name like `"a"` or `"Shift+Ctrl+F12"` for combined
@@ -37,9 +28,18 @@ module Terminal
37
28
  # @return [String] key name
38
29
  attr_reader :name
39
30
 
40
- # @attribute [r] modifier?
41
- # @return [true, false] whether a key modifier was pressed
42
- def modifier? = @modifier != 0
31
+ # Mouse event position.
32
+ #
33
+ # @return [[Integer,Integer]] row and column
34
+ # @return nil when no coordinates are assigned
35
+ attr_reader :position
36
+
37
+ # ANSI code sequence received from standard input.
38
+ # This can be a simple value like `"a"`or more complex input like
39
+ # `"\e[24;6~"` (for Shift+Ctrl+F12).
40
+ #
41
+ # @return [String] received ANSI code sequence
42
+ attr_reader :raw
43
43
 
44
44
  # @attribute [r] simple?
45
45
  # @return [true, false] whether a simple key was pressed
@@ -48,6 +48,14 @@ module Terminal
48
48
  # All pressed keys.
49
49
  # This is composed by all {modifier} and the {key}.
50
50
  #
51
+ # @example
52
+ # Terminal::KeyEvent["\e\r"].to_a
53
+ # => [:Alt, :Enter]
54
+ # Terminal::KeyEvent['a'].to_a
55
+ # => ['a']
56
+ # Terminal::KeyEvent["\e[<12;45;30m"].to_a
57
+ # => [:Shift, :Alt, :MBLeftUp]
58
+ #
51
59
  # @return [Array<Symbol, String>] all pressed keys
52
60
  def to_a = @ary.dup
53
61
 
@@ -76,9 +84,9 @@ module Terminal
76
84
  @key = key
77
85
  @modifier = modifier
78
86
  @position = position
79
- @ary = MODIFIERS.filter_map { |b, n| n if modifier.allbits?(b) }
87
+ @ary = MODIFIERS.filter_map { |b, n| n if (modifier & b) == b }
80
88
  @ary << key if key
81
- @name = @ary.join('+') # .encode(Encoding::UTF_8)
89
+ @name = @ary.join('+')
82
90
  end
83
91
 
84
92
  class << self
@@ -103,9 +111,9 @@ module Terminal
103
111
  ).dup
104
112
  end
105
113
 
106
- # Translate a ANSI input code sequence into a related KeyEvent.
114
+ # Translate an ANSI input code sequence into a related KeyEvent.
107
115
  #
108
- # @param raw [String] keyboard input
116
+ # @param raw [String] keyboard, mouse or focus event sequence
109
117
  # @return [KeyEvent] related key event
110
118
  def [](raw)
111
119
  cached = @cache[raw] and return cached if @cache
@@ -85,7 +85,7 @@ module Terminal
85
85
  on_bumb_key_event(&block)
86
86
  true
87
87
  when :csi_u, :legacy
88
- on_tty_key_event(mouse, mouse_move, focus, &block)
88
+ on_tty_key_event(mouse_option(mouse, mouse_move, focus), &block)
89
89
  true
90
90
  else
91
91
  false
@@ -94,36 +94,30 @@ module Terminal
94
94
 
95
95
  private
96
96
 
97
- def on_tty_key_event(mouse, mouse_move, focus)
97
+ def mouse_option(mouse, mouse_move, focus)
98
+ opts = +(mouse ? '1000' : '')
98
99
  # highlight: '1001'
99
100
  # drag: '1002'
100
- # move: '1003'
101
- # focus: '1004' - lost: "\e[O", get: "\e[I"
101
+ opts << ';1003' if mouse_move
102
+ opts << ';1004' if focus
102
103
  # ext: '1005'
103
104
  # sgr: '1006'
104
105
  # urxvt: '1015'
105
106
  # pixel: '1016'
106
- opts =
107
- if mouse || mouse_move || focus
108
- opts = mouse ? +"\e[?1006;1000" : +"\e[?1006"
109
- opts << ';1003' if mouse_move
110
- opts << ';1004' if focus
111
- raw_write("#{opts}h") ? "#{opts}l" : nil
112
- end
107
+ "\e[?#{opts};1006" unless opts.empty?
108
+ end
109
+
110
+ def on_tty_key_event(opts)
113
111
  STDIN.noecho do |stdin|
112
+ opts = raw_write("#{opts}h") ? "#{opts}l" : nil
114
113
  while (raw = stdin.getch)
115
- if raw != "\e"
116
- yield(KeyEvent[raw]) ? next : break
117
- end
114
+ (yield(KeyEvent[raw]) ? next : break) if raw != "\e"
118
115
  lesci = 0
119
- while (nc = stdin.read_nonblock(1, exception: false))
120
- break unless String === nc
116
+ while String === (nc = stdin.read_nonblock(1, exception: false))
121
117
  lesci = raw.size if nc == "\e"
122
118
  raw << nc
123
119
  end
124
- if lesci < 2
125
- yield(KeyEvent[raw]) ? next : break
126
- end
120
+ (yield(KeyEvent[raw]) ? next : break) if lesci < 2
127
121
  break unless raw[1..].split("\e").all? { yield(KeyEvent["\e#{_1}"]) }
128
122
  end
129
123
  end
@@ -147,16 +141,13 @@ module Terminal
147
141
  return :legacy if im == 'legacy'
148
142
  return :dumb if im == 'dumb' || !STDIN.tty?
149
143
  STDIN.noecho do |stdin|
150
- if raw_write("\e[>1u\e[?u\e[c")
151
- inp = +''
152
- inp << stdin.getch until inp.rindex('c')
153
- if inp.include?("\e[?1u")
154
- at_exit { raw_write("\e[<u") }
155
- return :csi_u
156
- end
157
- end
144
+ return :legacy unless raw_write("\e[>1u\e[?u\e[c")
145
+ inp = +''
146
+ inp << stdin.getch until inp.rindex('c')
147
+ return :legacy unless inp.include?("\e[?1u")
148
+ at_exit { raw_write("\e[<u") }
149
+ :csi_u
158
150
  end
159
- :legacy
160
151
  rescue Interrupt
161
152
  :legacy
162
153
  rescue IOError, SystemCallError
@@ -61,5 +61,12 @@ RSpec.shared_context 'with Terminal.rb' do |ansi: true, application: :kitty, col
61
61
  allow(Terminal).to receive(:read_key_event) do
62
62
  Terminal::KeyEvent[stdin.shift || raise('stdin buffer is empty')]
63
63
  end
64
+
65
+ allow(Terminal).to receive(:on_key_event) do |&b|
66
+ while true
67
+ ev = Terminal::KeyEvent[stdin.shift || raise('stdin buffer is empty')]
68
+ b[ev] or break
69
+ end
70
+ end
64
71
  end
65
72
  end
data/lib/terminal/text.rb CHANGED
@@ -447,7 +447,7 @@ module Terminal
447
447
  @scan_snippet =
448
448
  /\G(?:
449
449
  (\r?\n)
450
- | (\e\[[\d;:?]*[ABCDEFGHJKSTfhilmnsu])
450
+ | (\e\[[\x30-\x3f]*[\x20-\x2f]*[a-zA-Z])
451
451
  | (\e\]\d+(?:;[^\a\e]+)*(?:\a|\e\\))
452
452
  | (\s+)
453
453
  | (\X)
@@ -455,7 +455,7 @@ module Terminal
455
455
 
456
456
  @scan_width =
457
457
  /\G(?:
458
- (?:\e\[[\d;:?]*[ABCDEFGHJKSTfhilmnsu])
458
+ (?:\e\[[\x30-\x3f]*[\x20-\x2f]*[a-zA-Z])
459
459
  | (?:\e\]\d+(?:;[^\a\e]+)*(?:\a|\e\\))
460
460
  | (\s+)
461
461
  | (\X)
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Terminal
4
4
  # The version number of the gem.
5
- VERSION = '0.16.0'
5
+ VERSION = '0.16.2'
6
6
  end
data/lib/terminal.rb CHANGED
@@ -16,16 +16,42 @@ require_relative 'terminal/input'
16
16
  #
17
17
  module Terminal
18
18
  class << self
19
- # Return true if the current terminal supports ANSI control codes.
20
- # When the terminal does not support it, {colors} will return 2 (two) and
21
- # all output methods ({<<}, {print}, {puts}) will not forward ANSI control
22
- # codes to the terminal, {read_key_event} and {on_key_event} will not
23
- # support extended key codes and/or mouse events.
19
+ # Return `true` if the current terminal supports ANSI control codes for
20
+ # output.
21
+ # In this case all output methods ({<<}, {print}, {puts}) will forward ANSI
22
+ # control codes to the terminal and translate BBCode (see {Ansi.bbcode}).
23
+ #
24
+ # When `false` is returned (ANSI is not supported) the output methods will
25
+ # not forward ANSI control codes and BBCodes will be removed.
26
+ # The {colors} method will just return 2 (two).
27
+ #
28
+ # @see tui?
24
29
  #
25
30
  # @attribute [r] ansi?
26
- # @return [Boolean] whether ANSI control codes are supported
31
+ # @return [true, false] whether ANSI control codes are supported for output
27
32
  def ansi? = @ansi
28
33
 
34
+ # Return `true` if the current terminal supports ANSI control codes for
35
+ # input _and_ output.
36
+ # In this case not only all output methods ({<<}, {print}, {puts}) will
37
+ # forward ANSI control codes to the terminal and translate BBCode
38
+ # (see {Ansi.bbcode}). But also the input methods {read_key_event} and
39
+ # {on_key_event} will support extended key codes, mouse and focus events.
40
+ #
41
+ # @see ansi?
42
+ #
43
+ # @attribute [r] tui?
44
+ # @return [true, false]
45
+ # whether ANSI control codes are supported for input and output
46
+ def tui?
47
+ case input_mode
48
+ when :csi_u, :legacy
49
+ @ansi
50
+ else
51
+ false
52
+ end
53
+ end
54
+
29
55
  # Terminal application identifier.
30
56
  #
31
57
  # The detection supports a wide range of terminal emulators but may return
@@ -127,7 +153,7 @@ module Terminal
127
153
 
128
154
  # @see colors
129
155
  # @attribute [r] true_color?
130
- # @return [Boolean] whether true colors are supported
156
+ # @return [true, false] whether true colors are supported
131
157
  def true_color? = (colors == 16_777_216)
132
158
 
133
159
  # Hide the cursor.
@@ -365,5 +391,6 @@ module Terminal
365
391
  autoload :Text, "#{dir}/text.rb"
366
392
  autoload :Detect, "#{dir}/detect.rb"
367
393
  autoload :Shell, "#{dir}/shell.rb"
394
+ autoload :VERSION, "#{dir}/version.rb"
368
395
  private_constant :Detect, :Shell
369
396
  end
data/terminal_rb.gemspec CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
6
6
  spec.name = 'terminal_rb'
7
7
  spec.version = Terminal::VERSION
8
8
  spec.summary = <<~SUMMARY.tr("\n", ' ')
9
- Fast terminal access with ANSI, CSIu, mouse eventing, BBCode, word-wise
9
+ Fast terminal access with ANSI, CSIu, mouse events, BBCode, word-wise
10
10
  line break support and much more.
11
11
  SUMMARY
12
12
  spec.description = <<~DESCRIPTION.tr("\n", ' ')
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: 0.16.0
4
+ version: 0.16.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Blumtritt
@@ -69,6 +69,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
69
  requirements: []
70
70
  rubygems_version: 3.7.2
71
71
  specification_version: 4
72
- summary: Fast terminal access with ANSI, CSIu, mouse eventing, BBCode, word-wise line
72
+ summary: Fast terminal access with ANSI, CSIu, mouse events, BBCode, word-wise line
73
73
  break support and much more.
74
74
  test_files: []