natty-ui 0.7.0 → 0.8.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.
@@ -2,8 +2,6 @@
2
2
 
3
3
  require 'natty-ui'
4
4
 
5
- UI = NattyUI::StdOut
6
-
7
5
  LOREM = <<~LOREM
8
6
  Lorem ipsum dolor sit
9
7
  amet, consectetur adipisicing
@@ -14,7 +12,7 @@ LOREM = <<~LOREM
14
12
  nostrud exercitation ullamco
15
13
  laboris nisi ut aliquip ex
16
14
  ea commodo [[bold]]consequat[[/]]. Duis
17
- aute irure dolor in
15
+ aute irure [[bold green]]dolor[[/]] in
18
16
  reprehenderit in voluptate
19
17
  velit [[underline]]esse cillum[[/]] dolore eu
20
18
  fugiat nulla pariatur.
@@ -24,20 +22,15 @@ LOREM = <<~LOREM
24
22
  deserunt mollit anim id
25
23
  est laborum.
26
24
  LOREM
27
- WORDS = LOREM.split(/\W+/).uniq.sort!.freeze
28
-
29
- UI.space
30
- UI.h2 'Print a list in columns'
31
- UI.space
32
25
 
33
- UI.h3 'Lorem ipsum lines'
34
- UI.ls LOREM.lines(chomp: true)
35
- UI.space
26
+ ui.space
27
+ ui.h1 'Print a list in columns'
28
+ ui.space
36
29
 
37
- UI.h3 'Lorem ipsum word list (compact)'
38
- UI.ls WORDS
39
- UI.space
30
+ ui.h2 'Lorem ipsum lines (compact)'
31
+ ui.ls LOREM.lines(chomp: true), glyph: 1
32
+ ui.space
40
33
 
41
- UI.h3 'Lorem ipsum word list (row-wise)'
42
- UI.ls WORDS, compact: false
43
- UI.space
34
+ ui.h2 'Lorem ipsum lines (row-wise)'
35
+ ui.ls LOREM.lines(chomp: true), glyph: 1, compact: false
36
+ ui.space
data/examples/progress.rb CHANGED
@@ -2,67 +2,62 @@
2
2
 
3
3
  require 'natty-ui'
4
4
 
5
- UI = NattyUI::StdOut
6
-
7
- UI.space
8
- UI.h1 'NattyUI Progress Indication Demo'
9
- UI.space
5
+ ui.space
6
+ ui.h1 'NattyUI Progress Indication Demo'
7
+ ui.space
10
8
 
11
9
  # just simulate some work
12
10
  def something = sleep(0.5)
13
11
  def some = sleep(0.15)
14
12
 
15
- UI.info 'Tasks are sections to visualize step by step processing.' do |info|
16
- info.task 'Assemble assets' do |task|
17
- task.task('Initialize') { something }
13
+ ui.info 'Tasks are sections to visualize step by step processing.' do
14
+ ui.task 'Assemble assets' do
15
+ ui.task('Initialize') { something }
18
16
 
19
- progress = task.progress 'Connect to server...'
17
+ progress = ui.progress 'Connect to server...'
20
18
  20.times do
21
19
  progress.step
22
20
  some
23
21
  end
24
22
  progress.ok 'Connected'
25
23
 
26
- task.task('Collect files...') { something }
24
+ ui.task('Collect files...') { something }
27
25
 
28
- task.task 'Compile files...' do |subtask|
26
+ ui.task 'Compile files...' do
29
27
  %w[readme.txt main.css main.html sub.html].each do |name|
30
- subtask.msg "Compile file [[bright_yellow]]./source/#{name}[[/]]..."
28
+ ui.msg "Compile file [[bright_yellow]]./source/#{name}[[/]]..."
31
29
  something
32
30
  end
33
- subtask.done 'Files compiled.'
31
+ ui.done 'Files compiled.'
34
32
  end
35
33
 
36
- progress = task.progress('Compress files', max_value: 11)
34
+ progress = ui.progress('Compress files', max_value: 11)
37
35
  11.times do
38
36
  progress.step
39
37
  something
40
38
  end
41
39
  progress.done 'All compressed'
42
40
 
43
- task.task('Signing') { something }
41
+ ui.task('Signing') { something }
44
42
 
45
- task.task('Store assembled results') { something }
43
+ ui.task('Store assembled results') { something }
46
44
  end
47
- info.puts(
45
+
46
+ ui.puts(
48
47
  'The details are removed ([[italic]]in ANSI version[[/]]) when the task',
49
48
  'ended sucessfully.'
50
49
  )
51
50
  end
52
51
 
53
- UI.info 'Details of failed tasks will not be cleaned.' do |info|
54
- info.task 'Assemble assets' do |task|
55
- task.task('Initialize') { something }
56
-
57
- progress = task.progress 'Connect to server...'
58
- 20.times do
59
- progress.step
60
- some
52
+ ui.info 'Details of failed tasks will not be cleaned.' do
53
+ ui.task 'Assemble assets' do
54
+ ui.task('Initialize') { something }
55
+ ui.task('Connect to Server') do
56
+ something
57
+ ui.failed 'Unable to connect to server'
61
58
  end
62
- progress.failed 'Unable to connect to server'
63
-
64
- task.error 'This code will not be reachd!'
59
+ ui.error 'This code will not be reachd!'
65
60
  end
66
61
  end
67
62
 
68
- UI.space
63
+ ui.space
data/examples/query.rb CHANGED
@@ -2,42 +2,36 @@
2
2
 
3
3
  require 'natty-ui'
4
4
 
5
- UI = NattyUI::StdOut
5
+ ui.space
6
+ ui.h1 'NattyUI Query Demo'
7
+ ui.space
6
8
 
7
- UI.space
8
- UI.h1 'NattyUI Query Demo'
9
- UI.space
9
+ # little helper
10
+ def abort!
11
+ ui.failed 'aborted'
12
+ exit
13
+ end
10
14
 
11
- unless UI.ask('Do you like to continute? (Y|n)')
12
- UI.failed 'aborted'
15
+ unless ui.ask('Do you like to continute? (Y|n): ')
16
+ ui.info 'ok, try later!'
13
17
  exit
14
18
  end
15
19
 
16
20
  choice =
17
- UI.query(
21
+ ui.query(
18
22
  'Which fruits do you prefer?',
19
23
  'Apples',
20
- 'Bananas',
24
+ '[[yellow]]Bananas[[/]]',
21
25
  'Cherries',
22
- x: 'No fruits',
23
- result: :choice
26
+ x: 'No fruits'
24
27
  )
25
- unless choice
26
- UI.failed 'aborted'
27
- exit false
28
- end
29
- UI.info "Your choice: #{choice}"
28
+ abort! unless choice
29
+ ui.info "Your choice: #{choice}"
30
30
 
31
- answer = UI.request 'Are you okay?'
32
- unless answer
33
- UI.failed 'aborted'
34
- exit false
35
- end
36
- UI.info "Your answer: #{answer.inspect}"
31
+ answer = ui.request 'What is your favorite verb?: '
32
+ abort! unless answer
33
+ ui.info "Your answer: #{answer.inspect}"
37
34
 
38
- answer = UI.request('What is your current password?', password: true)
39
- unless answer
40
- UI.failed 'aborted'
41
- exit false
42
- end
43
- UI.info "I'll keep your secret!"
35
+ answer = ui.request('What is your current password?:', password: true)
36
+ abort! unless answer
37
+ ui.info "I'll keep your secret!"
data/examples/table.rb ADDED
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'natty-ui'
4
+
5
+ User = Struct.new(:id, :name, :address)
6
+
7
+ USERS = [
8
+ User.new(1, 'Henry', 'henry@some.test'),
9
+ User.new(2, 'Sam', 'sam-sam@some.test'),
10
+ User.new(3, 'Taylor', 'taylor@some.test'),
11
+ User.new(3, 'Max', 'maxxx@some.test')
12
+ ].freeze
13
+
14
+ ui.space
15
+ ui.h1 'The User List'
16
+ ui.space
17
+
18
+ ui.table(User.members, *USERS)
data/lib/natty-ui/ansi.rb CHANGED
@@ -5,44 +5,85 @@ module NattyUI
5
5
  # Helper module for ANSI escape codes.
6
6
  #
7
7
  module Ansi
8
- class << self
9
- # @return [String] ANSI code to reset all attributes
10
- def reset = "\e[0m"
8
+ # ANSI code to move the cursor down.
9
+ CURSOR_DOWN = "\e[B"
10
+
11
+ # ANSI code to move the cursor up.
12
+ CURSOR_UP = "\e[A"
13
+
14
+ # ANSI code to move the cursor left.
15
+ CURSOR_LEFT = "\e[D"
16
+
17
+ # ANSI code to move the cursor right.
18
+ CURSOR_RIGHT = "\e[C"
19
+
20
+ # ANSI code to move the cursor to beginning of the line below.
21
+ CURSOR_LINE_DOWN = "\e[E"
22
+
23
+ # ANSI code to move the cursor to beginning of the line up.
24
+ CURSOR_LINE_UP = "\e[F"
25
+
26
+ # ANSI code to hide the cursor.
27
+ CURSOR_HIDE = "\e[?25l"
28
+
29
+ # ANSI code to show the cursor (again).
30
+ CURSOR_SHOW = "\e[?25h"
31
+
32
+ # ANSI code to save current cursor position.
33
+ CURSOR_SAVE_POS = "\e[s"
34
+
35
+ # ANSI code to restore saved cursor position.
36
+ CURSOR_RESTORE_POS = "\e[u"
37
+
38
+ # ANSI code to set cursor position on upper left corner.
39
+ CURSOR_HOME = "\e[H"
40
+
41
+ # ANSI code to erase current line and position to first column.
42
+ LINE_CLEAR = "\e[1K\e[0G"
43
+
44
+ # ANSI code to erase current line.
45
+ LINE_ERASE = "\e[2K"
11
46
 
12
- # @return [String] ANSI code to save current screen state
13
- def screen_save = "\e[?47h"
47
+ # ANSI code to erase to end of current line.
48
+ LINE_ERASE_TO_END = "\e[0K"
14
49
 
15
- # @return [String] ANSI code to restore screen state
16
- def screen_restore = "\e[?47l"
50
+ # ANSI code to erase to begin of current line.
51
+ LINE_ERASE_TO_BEGIN = "\e[1K"
17
52
 
18
- # @return [String] ANSI code to alternate screen
19
- def screen_alternative = "\e[?1049h"
53
+ # ANSI code to save current screen state.
54
+ SCREEN_SAVE = "\e[?47h"
20
55
 
21
- # @return [String] ANSI code to set alternate screen off
22
- def screen_alternative_off = "\e[?1049l"
56
+ # ANSI code to restore screen state.
57
+ SCREEN_RESTORE = "\e[?47l"
23
58
 
24
- # @return [String] ANSI code to erase screen
25
- def screen_erase = "\e[2J"
59
+ # ANSI code to erase screen.
60
+ SCREEN_ERASE = "\e[2J"
26
61
 
27
- # @return [String] ANSI code to erase screen below current cursor position
28
- def screen_erase_below = "\e[0J"
62
+ # ANSI code to erase screen below current cursor position.
63
+ SCREEN_ERASE_BELOW = "\e[0J"
29
64
 
30
- # @return [String] ANSI code to erase screen above current cursor position
31
- def screen_erase_above = "\e[1J"
65
+ # ANSI code to erase screen above current cursor position.
66
+ SCREEN_ERASE_ABOVE = "\e[1J"
32
67
 
33
- # @return [String] ANSI code to erase current line
34
- def line_erase = "\e[2K"
68
+ # ANSI code to alternate screen
69
+ SCREEN_ALTERNATIVE = "\e[?1049h"
35
70
 
36
- # @return [String] ANSI code to erase to end of current line
37
- def line_erase_to_end = "\e[0K"
71
+ # ANSI code to set alternate screen off.
72
+ SCREEN_ALTERNATIVE_OFF = "\e[?1049l"
38
73
 
39
- # @return [String] ANSI code to erase to begin of current line
40
- def line_erase_to_begin = "\e[1K"
74
+ # ANSI code to reset all attributes.
75
+ RESET = "\e[0m"
41
76
 
42
- # @return [String] ANSI code to erase current line and position to first
43
- # column
44
- def line_clear = "\e[1K\e[0G"
77
+ # @!visibility private
78
+ CURSOR_RIGHT_ALIGNED = "\e[9999G\e[D\e[C"
45
79
 
80
+ # @!visibility private
81
+ BLANK_SLATE = "\e[0m\e[s\e[?47h\e[H\e[2J"
82
+
83
+ # @!visibility private
84
+ UNBLANK_SLATE = "\e[?47l\e[u\e[0m"
85
+
86
+ class << self
46
87
  # @param lines [Integer] number of lines
47
88
  # @return [String] ANSI code to move the cursor up
48
89
  def cursor_up(lines = nil) = "\e[#{lines}A"
@@ -60,37 +101,18 @@ module NattyUI
60
101
  def cursor_left(columns = nil) = "\e[#{columns}D"
61
102
 
62
103
  # @param lines [Integer] number of lines
63
- # @return [String] ANSI code to move the cursor to beginning of the line
64
- # some lines down
104
+ # @return [String] ANSI code to move the cursor to beginning of some lines
105
+ # below
65
106
  def cursor_line_down(lines = nil) = "\e[#{lines}E"
66
107
 
67
108
  # @param lines [Integer] number of lines
68
- # @return [String] ANSI code to move the cursor to beginning of the line
69
- # some lines up
109
+ # @return [String] ANSI code to move the cursor to beginning of some lines
110
+ # up
70
111
  def cursor_line_up(lines = nil) = "\e[#{lines}F"
71
112
 
72
- # @param columns [Integer] number of columns
113
+ # @param column [Integer] column number
73
114
  # @return [String] ANSI code to move the cursor to given column
74
- def cursor_column(columns = nil) = "\e[#{columns}G"
75
-
76
- # @return [String] ANSI code positioning the cursor on right hand side of
77
- # the terminal
78
- def cursor_right_aligned = "\e[9999G\e[D\e[C"
79
-
80
- # @return [String] ANSI code to hide the cursor
81
- def cursor_hide = "\e[?25l"
82
-
83
- # @return [String] ANSI code to show the cursor (again)
84
- def cursor_show = "\e[?25h"
85
-
86
- # @return [String] ANSI code to save current cursor position
87
- def cursor_save_pos = "\e[s"
88
-
89
- # @return [String] ANSI code to restore saved cursor position
90
- def cursor_restore_pos = "\e[u"
91
-
92
- # @return [String] ANSI code to set cursor position on upper left corner
93
- def cursor_home = "\e[H"
115
+ def cursor_column(column = nil) = "\e[#{column}G"
94
116
 
95
117
  # @param row [Integer] row to set cursor
96
118
  # @param column [Integer] column to set cursor
@@ -100,17 +122,17 @@ module NattyUI
100
122
  column ? "\e[;#{column}H" : "\e[H"
101
123
  end
102
124
 
103
- # Decorate given `obj` with ANSI `attributes`.
125
+ # Decorate given `str` with ANSI `attributes`.
104
126
  #
105
127
  # @see []
106
128
  #
107
- # @param obj [#to_s] object to be decorated
129
+ # @param str [#to_s] object to be decorated
108
130
  # @param attributes [Symbol, String] attribute names to be used
109
131
  # @param reset [Boolean] whether to include reset code for ANSI attributes
110
- # @return [String] `obj` converted and decorated with the ANSI `attributes`
111
- def embellish(obj, *attributes, reset: true)
132
+ # @return [String] `str` converted and decorated with the ANSI `attributes`
133
+ def embellish(str, *attributes, reset: true)
112
134
  attributes = self[*attributes]
113
- attributes.empty? ? "#{obj}" : "#{attributes}#{obj}#{"\e[0m" if reset}"
135
+ attributes.empty? ? str.to_s : "#{attributes}#{str}#{"\e[0m" if reset}"
114
136
  end
115
137
 
116
138
  # Remove ANSI attribtes from given string.
@@ -229,9 +251,7 @@ module NattyUI
229
251
  def try_convert(attributes)
230
252
  return if (attributes = attributes.to_s.split).empty?
231
253
  "\e[#{
232
- attributes
233
- .map { |arg| ATTRIBUTES[arg] || color(arg) || return }
234
- .join(';')
254
+ attributes.map { ATTRIBUTES[_1] || color(_1) || return }.join(';')
235
255
  }m"
236
256
  end
237
257
 
@@ -262,7 +282,7 @@ module NattyUI
262
282
  end
263
283
  val.delete_prefix!('#')
264
284
  case val.size
265
- when 2
285
+ when 1, 2
266
286
  "#{base}5;#{val.hex}" if /\A[[:xdigit:]]+\z/.match?(val)
267
287
  when 3
268
288
  if /\A[[:xdigit:]]+\z/.match?(val)
@@ -433,7 +453,7 @@ module NattyUI
433
453
  ul_bright_magenta: '58;2;255;0;255',
434
454
  ul_bright_cyan: '58;2;0;255;255',
435
455
  ul_bright_white: '58;2;255;255;255'
436
- }.tap { |ret| ret.merge!(ret.transform_keys(&:to_s)).freeze }
456
+ }.tap { _1.merge!(_1.transform_keys(&:to_s)).freeze }
437
457
  private_constant :ATTRIBUTES
438
458
  end
439
459
  end