chamomile-petals 0.1.1 → 0.2.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: 8ed123f1f94a7e5e22208bc83930247e62266c2436c1def4544321eb516eb7f9
4
- data.tar.gz: 3bca72d7c2b82b6b13971ae0a104c874fb65e06066252a75683c06595159d4fe
3
+ metadata.gz: b0e639488f319cee4214dadaf0a18d780c364f1e2dd0eb105ad8a02396c10476
4
+ data.tar.gz: 312869e2b9d7f6e1cbeb10a88144adbd576ff53979e4aa6c3668846614e5d9d2
5
5
  SHA512:
6
- metadata.gz: bb3390f954b95b548e3fa9af78ad1db0b122cdf65a4b620523546c6761e0dff1947ae266792bdf912039576dd344a692197b9e7690ba0d2b3eeb5e67b52c423b
7
- data.tar.gz: cd8d70d75e9dd197677df817751f529483edc0b4d613a65b0fe49c20c3976f276d823d780425ce8d71ad9f26f86f2979ce9e962943a42d422bd15d5b6e72f580
6
+ metadata.gz: 83bd46a6443068228e48ac8084480044cb6656376120f9ed096ad803887d8c50bfe103143c988bb628576a2d58d20a93aaab5f448f1f2c7a6d19b98aa020150e
7
+ data.tar.gz: d8f90b12a4a67f5a07e04870b83f004fff7d385de2face4bd4fb7008e0be3e906c2f9ce8fb1bedc469ea3be0003585964e39e53f912696148743b41eb4b7ff5e
data/lib/petals/cursor.rb CHANGED
@@ -74,7 +74,7 @@ module Petals
74
74
  }
75
75
  end
76
76
 
77
- def update(msg)
77
+ def handle(msg)
78
78
  return unless msg.is_a?(CursorBlinkMsg)
79
79
  return unless @mode == MODE_BLINK && @focused
80
80
  return unless msg.id == @id && msg.tag == @tag
@@ -84,6 +84,8 @@ module Petals
84
84
  blink_cmd
85
85
  end
86
86
 
87
+ alias update handle
88
+
87
89
  def view
88
90
  return @char if @mode == MODE_HIDE
89
91
  return @char if @blinked
@@ -52,7 +52,7 @@ module Petals
52
52
  read_dir_cmd(@current_directory)
53
53
  end
54
54
 
55
- def update(msg)
55
+ def handle(msg)
56
56
  case msg
57
57
  when FilePickerReadDirMsg
58
58
  return unless msg.id == @id
@@ -61,11 +61,13 @@ module Petals
61
61
  @cursor = @cursor.clamp(0, [entries_size - 1, 0].max)
62
62
  clamp_offset
63
63
  nil
64
- when Chamomile::KeyMsg
64
+ when Chamomile::KeyEvent
65
65
  handle_key(msg)
66
66
  end
67
67
  end
68
68
 
69
+ alias update handle
70
+
69
71
  def view
70
72
  return " (empty)" if @entries.empty?
71
73
 
@@ -93,7 +95,7 @@ module Petals
93
95
  end
94
96
 
95
97
  def did_select_file?(msg)
96
- return [false, nil] unless msg.is_a?(Chamomile::KeyMsg)
98
+ return [false, nil] unless msg.is_a?(Chamomile::KeyEvent)
97
99
 
98
100
  if @selected_path
99
101
  path = @selected_path
@@ -105,7 +107,7 @@ module Petals
105
107
  end
106
108
 
107
109
  def did_select_disabled_file?(msg)
108
- return [false, nil] unless msg.is_a?(Chamomile::KeyMsg)
110
+ return [false, nil] unless msg.is_a?(Chamomile::KeyEvent)
109
111
 
110
112
  if @disabled_selected_path
111
113
  path = @disabled_selected_path
data/lib/petals/help.rb CHANGED
@@ -59,10 +59,12 @@ module Petals
59
59
  end
60
60
  end
61
61
 
62
- def update(_msg)
62
+ def handle(_msg)
63
63
  nil
64
64
  end
65
65
 
66
+ alias update handle
67
+
66
68
  private
67
69
 
68
70
  def enabled_bindings(bindings)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Petals
4
- # Utilities for matching KeyMsg against normalized key maps.
4
+ # Utilities for matching KeyEvent against normalized key maps.
5
5
  module KeyBinding
6
6
  # Normalize a key map so mod arrays are sorted and frozen.
7
7
  # Call once at definition time to avoid per-keystroke allocations.
@@ -14,7 +14,7 @@ module Petals
14
14
  end.freeze
15
15
  end
16
16
 
17
- # Check if a KeyMsg matches any binding for a named action.
17
+ # Check if a KeyEvent matches any binding for a named action.
18
18
  # Expects a normalized key map (from .normalize) for best performance.
19
19
  def self.key_matches?(msg, key_map, action)
20
20
  return false unless msg.is_a?(Chamomile::KeyMsg)
data/lib/petals/list.rb CHANGED
@@ -212,9 +212,9 @@ module Petals
212
212
  @spinner_visible
213
213
  end
214
214
 
215
- def update(msg)
215
+ def handle(msg)
216
216
  case msg
217
- when Chamomile::KeyMsg
217
+ when Chamomile::KeyEvent
218
218
  handle_key(msg)
219
219
  when SpinnerTickMsg
220
220
  @spinner.update(msg)
@@ -230,6 +230,8 @@ module Petals
230
230
  end
231
231
  end
232
232
 
233
+ alias update handle
234
+
233
235
  def view
234
236
  sections = []
235
237
 
@@ -72,9 +72,9 @@ module Petals
72
72
 
73
73
  # Elm protocol
74
74
 
75
- def update(msg)
75
+ def handle(msg)
76
76
  case msg
77
- when Chamomile::KeyMsg
77
+ when Chamomile::KeyEvent
78
78
  if KeyBinding.key_matches?(msg, @key_map, :prev_page)
79
79
  prev_page
80
80
  elsif KeyBinding.key_matches?(msg, @key_map, :next_page)
@@ -85,6 +85,8 @@ module Petals
85
85
  nil
86
86
  end
87
87
 
88
+ alias update handle
89
+
88
90
  def view
89
91
  case @type
90
92
  when TYPE_ARABIC
@@ -79,7 +79,7 @@ module Petals
79
79
  @animating
80
80
  end
81
81
 
82
- def update(msg)
82
+ def handle(msg)
83
83
  return unless msg.is_a?(ProgressFrameMsg)
84
84
  return unless msg.id == @id && msg.tag == @tag
85
85
 
@@ -101,6 +101,8 @@ module Petals
101
101
  end
102
102
  end
103
103
 
104
+ alias update handle
105
+
104
106
  def view
105
107
  render_bar(@percent)
106
108
  end
@@ -42,7 +42,7 @@ module Petals
42
42
  end
43
43
 
44
44
  # Advance frame if msg is a matching SpinnerTickMsg; return cmd or nil.
45
- def update(msg)
45
+ def handle(msg)
46
46
  return unless msg.is_a?(SpinnerTickMsg)
47
47
  return unless msg.id == @id && msg.tag == @tag
48
48
 
@@ -51,6 +51,8 @@ module Petals
51
51
  tick_cmd
52
52
  end
53
53
 
54
+ alias update handle
55
+
54
56
  # Current frame string.
55
57
  def view
56
58
  @spinner_type.frames[@frame]
@@ -64,7 +64,7 @@ module Petals
64
64
  @running
65
65
  end
66
66
 
67
- def update(msg)
67
+ def handle(msg)
68
68
  return unless msg.is_a?(StopwatchTickMsg)
69
69
  return unless msg.id == @id && msg.tag == @tag
70
70
 
@@ -73,6 +73,8 @@ module Petals
73
73
  tick_cmd
74
74
  end
75
75
 
76
+ alias update handle
77
+
76
78
  def view
77
79
  total = @elapsed.ceil.to_i
78
80
  hours = total / 3600
data/lib/petals/table.rb CHANGED
@@ -8,14 +8,33 @@ module Petals
8
8
  attr_accessor :columns, :key_map, :height
9
9
  attr_reader :cursor, :rows
10
10
 
11
- def initialize(columns: [], rows: [], height: 10, key_map: DEFAULT_KEY_MAP)
12
- @columns = columns
11
+ # Accepts columns as keyword arg or via block DSL.
12
+ #
13
+ # # Keyword form (original)
14
+ # Table.new(columns: [Column.new(title: "Name", width: 20)], rows: rows)
15
+ #
16
+ # # Block DSL form (new)
17
+ # Table.new(rows: rows) do |t|
18
+ # t.column "Name", width: 20
19
+ # t.column "Size", width: 10
20
+ # end
21
+ #
22
+ # # Hash form (new)
23
+ # Table.new(columns: [{ title: "Name", width: 20 }], rows: rows)
24
+ def initialize(columns: [], rows: [], height: 10, key_map: DEFAULT_KEY_MAP, &block)
25
+ @columns = normalize_columns(columns)
13
26
  @rows = rows
14
27
  @height = height
15
28
  @key_map = key_map
16
29
  @cursor = 0
17
30
  @offset = 0
18
31
  @focused = false
32
+
33
+ if block
34
+ builder = ColumnBuilder.new
35
+ block.call(builder)
36
+ @columns = builder.columns unless builder.columns.empty?
37
+ end
19
38
  end
20
39
 
21
40
  def rows=(rows)
@@ -69,17 +88,21 @@ module Petals
69
88
  @focused
70
89
  end
71
90
 
72
- def update(msg)
91
+ # Handle an incoming event.
92
+ def handle(msg)
73
93
  return unless @focused
74
94
 
75
95
  case msg
76
- when Chamomile::KeyMsg
96
+ when Chamomile::KeyEvent
77
97
  handle_key(msg)
78
98
  end
79
99
 
80
100
  nil
81
101
  end
82
102
 
103
+ # Backward compat alias
104
+ alias update handle
105
+
83
106
  def view
84
107
  header = render_header
85
108
  separator = render_separator
@@ -88,8 +111,34 @@ module Petals
88
111
  [header, separator, body].compact.join("\n")
89
112
  end
90
113
 
114
+ # DSL builder for column definitions.
115
+ class ColumnBuilder
116
+ attr_reader :columns
117
+
118
+ def initialize
119
+ @columns = []
120
+ end
121
+
122
+ def column(title, width: 20)
123
+ @columns << Column.new(title: title, width: width)
124
+ end
125
+ end
126
+
91
127
  private
92
128
 
129
+ def normalize_columns(columns)
130
+ columns.map do |col|
131
+ case col
132
+ when Column
133
+ col
134
+ when Hash
135
+ Column.new(title: col[:title], width: col[:width] || 20)
136
+ else
137
+ col
138
+ end
139
+ end
140
+ end
141
+
93
142
  def row_count
94
143
  @rows.length
95
144
  end
@@ -168,19 +168,21 @@ module Petals
168
168
  @last_char_offset = 0
169
169
  end
170
170
 
171
- def update(msg)
171
+ def handle(msg)
172
172
  return unless @focused
173
173
 
174
174
  case msg
175
- when Chamomile::KeyMsg
175
+ when Chamomile::KeyEvent
176
176
  handle_key(msg)
177
- when Chamomile::PasteMsg
177
+ when Chamomile::PasteEvent
178
178
  handle_paste(msg)
179
179
  end
180
180
 
181
181
  nil
182
182
  end
183
183
 
184
+ alias update handle
185
+
184
186
  def view
185
187
  return "#{@prompt}#{@placeholder}" if @lines == [""] && !@placeholder.empty? && !@focused
186
188
 
@@ -65,21 +65,23 @@ module Petals
65
65
  recalc_offset
66
66
  end
67
67
 
68
- # Elm protocol
69
-
70
- def update(msg)
68
+ # Handle an incoming event. Primary API — replaces the old `update` name.
69
+ def handle(msg)
71
70
  return unless @focused
72
71
 
73
72
  case msg
74
- when Chamomile::KeyMsg
73
+ when Chamomile::KeyEvent
75
74
  handle_key(msg)
76
- when Chamomile::PasteMsg
75
+ when Chamomile::PasteEvent
77
76
  handle_paste(msg)
78
77
  end
79
78
 
80
79
  nil
81
80
  end
82
81
 
82
+ # Backward compat alias
83
+ alias update handle
84
+
83
85
  def view
84
86
  return "#{@prompt}#{@placeholder}" if @value.empty? && !@placeholder.empty? && !@focused
85
87
 
data/lib/petals/timer.rb CHANGED
@@ -70,7 +70,7 @@ module Petals
70
70
  @remaining <= 0
71
71
  end
72
72
 
73
- def update(msg)
73
+ def handle(msg)
74
74
  case msg
75
75
  when TimerTickMsg
76
76
  return unless msg.id == @id && msg.tag == @tag
@@ -87,6 +87,8 @@ module Petals
87
87
  end
88
88
  end
89
89
 
90
+ alias update handle
91
+
90
92
  def view
91
93
  total = @remaining.ceil.to_i
92
94
  total = 0 if total.negative?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Petals
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -18,24 +18,36 @@ module Petals
18
18
  @soft_wrap = false
19
19
  end
20
20
 
21
- def set_width(new_width)
21
+ def width=(new_width)
22
22
  @width = new_width
23
23
  clamp_offset
24
24
  @x_offset = @x_offset.clamp(0, [max_horizontal_scroll, 0].max) unless @soft_wrap
25
25
  end
26
26
 
27
- def set_height(new_height)
27
+ # Backward compat alias
28
+ alias set_width width=
29
+
30
+ def height=(new_height)
28
31
  @height = new_height
29
32
  clamp_offset
30
33
  end
31
34
 
32
- def set_content(s)
33
- @lines = s.split("\n", -1)
35
+ # Backward compat alias
36
+ alias set_height height=
37
+
38
+ def content=(s)
39
+ @lines = s.to_s.split("\n", -1)
34
40
  clamp_offset
35
41
  @x_offset = @x_offset.clamp(0, [max_horizontal_scroll, 0].max) unless @soft_wrap
36
42
  self
37
43
  end
38
44
 
45
+ # Backward compat — preserves the return-self convention
46
+ def set_content(s)
47
+ self.content = s
48
+ self
49
+ end
50
+
39
51
  def content
40
52
  @lines.join("\n")
41
53
  end
@@ -138,19 +150,21 @@ module Petals
138
150
  self
139
151
  end
140
152
 
141
- # Elm protocol
142
-
143
- def update(msg)
153
+ # Handle an incoming event.
154
+ def handle(msg)
144
155
  case msg
145
- when Chamomile::KeyMsg
156
+ when Chamomile::KeyEvent
146
157
  handle_key(msg)
147
- when Chamomile::MouseMsg
158
+ when Chamomile::MouseEvent
148
159
  handle_mouse(msg)
149
160
  end
150
161
 
151
162
  nil
152
163
  end
153
164
 
165
+ # Backward compat alias
166
+ alias update handle
167
+
154
168
  def view
155
169
  if @soft_wrap
156
170
  render_soft_wrap
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chamomile-petals
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jack Killilea
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-10 00:00:00.000000000 Z
11
+ date: 2026-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chamomile
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.1'
19
+ version: '0.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.1'
26
+ version: '0.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement