terminal_rb 0.16.1 → 0.17.0

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: 1127036c0cda3cdc5e44853ba2f650d7475338166d363ca3f50c35900ac858d7
4
- data.tar.gz: 638eaaa9c3d072d8ee1acddab353150f4619f50420b03682b7436d9de19ff71a
3
+ metadata.gz: 4a91661bad1d2b3b3d432dd5ae4e0e0101b3a006773d30c58a39a75c703ab03e
4
+ data.tar.gz: 533349101fb9890e0bf0e73a407f9302ac881eeb9376aca78aba1e76486544ad
5
5
  SHA512:
6
- metadata.gz: 562cef6e62f27adadf22e361017968c422e0c3661787be87d4474debffb26e73f87fc104aeb5e2e4d10fb9a7ba4634d14f44e8c9bebf88ba776cee63912fabcb
7
- data.tar.gz: 5668c79725449d1bb9989ba691997adb93a18186a0bfde224ebd8a626a523db08b34a1b45aa2639d46e32acaab7490d47c7987daf875ea5ab6047e690d265885
6
+ metadata.gz: 39c6527ea4d97ff28e1fc11408297057ee537b44c945be71814cc7b99b4e2759863c063b023d1c7d9d4bb4b9c0ae8172bbb3ceb9166c93b54301119fb0443e9d
7
+ data.tar.gz: f068bf0ffbc3952260cae2a5e56506063b5bc566c66b4cac8f138732a1bd748a17c9d165ffa29a22a4ca85a12e4c78ba88d3e722a349c0de70d899892f5c7e06
data/lib/terminal/ansi.rb CHANGED
@@ -467,7 +467,7 @@ module Terminal
467
467
 
468
468
  # Create a hyperlink.
469
469
  # This is not widely supported; works for
470
- # Ghosty,
470
+ # Ghostty,
471
471
  # iTerm2,
472
472
  # Kitty,
473
473
  # Rio,
@@ -481,7 +481,7 @@ module Terminal
481
481
 
482
482
  # Show a simple notification.
483
483
  # This is not widely supported; works for
484
- # Ghosty,
484
+ # Ghostty,
485
485
  # iTerm2,
486
486
  # Kitty,
487
487
  # WezTerm.
@@ -490,6 +490,42 @@ module Terminal
490
490
  # @return (see cursor_up)
491
491
  def notify(text) = "\e]9;#{text}\a"
492
492
 
493
+ # Set task progress state.
494
+ # This is not widely supported; works for
495
+ # Ghostty,
496
+ # iTerm2,
497
+ # Kitty.
498
+ #
499
+ # @param state [:show, :warning, :error, :indeterminate, :hide]
500
+ # - `:show`
501
+ # show progress indicator with given percent value in default mode
502
+ # - `:warning`
503
+ # show progress with given percent value in warning mode
504
+ # - `:error`
505
+ # show progress with given percent value in error mode
506
+ # - `:indeterminate`
507
+ # show progress in indeterminate state (percent value is ignored)
508
+ # - `:hide`
509
+ # hide progress indicator (percent value is ignored)
510
+ # @return (see cursor_up)
511
+ def progress(state, percent = 0)
512
+ case state
513
+ when :show, true
514
+ state = 1
515
+ when :err, :error
516
+ state = 2
517
+ when :warn, :warning
518
+ state = 4
519
+ when Numeric
520
+ percent, state = state, 1
521
+ when :indeterminate
522
+ return +PROGRESS_SHOW_INDETERMINATE
523
+ else
524
+ return +PROGRESS_HIDE
525
+ end
526
+ "\e]9;4;#{state};#{percent.to_i.clamp(0, 100)}\a"
527
+ end
528
+
493
529
  # Create scaled text.
494
530
  # It uses the
495
531
  # [text sizing protocol](https://sw.kovidgoyal.net/kitty/text-sizing-protocol).
@@ -857,6 +893,11 @@ module Terminal
857
893
  # @private
858
894
  LINE_ERASE_PREV = -"#{cursor_prev_line(nil)}#{LINE_ERASE}"
859
895
 
896
+ # @private
897
+ PROGRESS_HIDE = "\e]9;4;0;0\a"
898
+ # @private
899
+ PROGRESS_SHOW_INDETERMINATE = "\e]9;4;3;0\a"
900
+
860
901
  # @comment seems not widely supported:
861
902
  # doubled: def cursor_column(column = 1) = "\e[#{column}`"
862
903
  # doubled: def cursor_row(row = 1) = "\e[#{row}d"
@@ -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
@@ -120,7 +120,11 @@ module Terminal
120
120
  @enum = Enumerator.new { |y| enum.each { y << _1 } }
121
121
  end
122
122
  end
123
+
124
+ private_constant :Writer, :CopyWriter, :ArrayWriter, :EnumerableWriter
123
125
  end
126
+
127
+ private_constant :Input
124
128
  end
125
129
 
126
130
  private_constant :Shell
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Terminal
4
4
  # The version number of the gem.
5
- VERSION = '0.16.1'
5
+ VERSION = '0.17.0'
6
6
  end
data/lib/terminal.rb CHANGED
@@ -301,7 +301,9 @@ module Terminal
301
301
  # whether to create a seperate shell or not
302
302
  # @option options [#readpartial, #to_io, Array, #each, #to_a, #to_s] :input
303
303
  # piped to the command as input
304
+ # @raise [ArgumentError] when command is missing
304
305
  def sh(*cmd, **options, &block)
306
+ raise(ArgumentError, 'command expected') if cmd.empty?
305
307
  return Shell.exec(cmd, **options, &block) if block_given?
306
308
  out = []
307
309
  err = []
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.1
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Blumtritt