-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathmigrate_to_buffer.rb
More file actions
executable file
ยท145 lines (117 loc) ยท 4.94 KB
/
migrate_to_buffer.rb
File metadata and controls
executable file
ยท145 lines (117 loc) ยท 4.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# frozen_string_literal: true
#--
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
#++
# !/usr/bin/env ruby
# Migration script to refactor widget renderers from Frame to Buffer
require "fileutils"
WIDGETS_DIR = "/Users/kerrick/Developer/ratatui_ruby/ext/ratatui_ruby/src/widgets"
# Files to update (excluding block.rs which is already done)
WIDGET_FILES = %w[
barchart.rs
calendar.rs
canvas.rs
center.rs
chart.rs
clear.rs
cursor.rs
gauge.rs
layout.rs
line_gauge.rs
list.rs
overlay.rs
paragraph.rs
ratatui_logo.rs
ratatui_mascot.rs
scrollbar.rs
sparkline.rs
table.rs
tabs.rs
].freeze
def migrate_file(filepath)
puts "Migrating #{File.basename(filepath)}..."
content = File.read(filepath)
original_content = content.dup
# 1. Update function signature
content.gsub!("pub fn render(frame: &mut Frame,", "pub fn render(buffer: &mut Buffer,")
content.gsub!("pub fn render_ratatui_mascot(frame: &mut Frame,", "pub fn render_ratatui_mascot(buffer: &mut Buffer,")
# 2. Update imports - Add Buffer, remove Frame
# Handle various import patterns
content.gsub!(/use ratatui::\{([^}]*),\s*Frame\s*\};/, 'use ratatui::{\1};')
content.gsub!(/use ratatui::\{Frame,\s*([^}]*)\};/, 'use ratatui::{\1};')
content.gsub!("use ratatui::Frame;", "")
# Add Buffer import if not present
unless content.match?(/use ratatui::(?:\{[^}]*)?buffer::Buffer/)
# Find the ratatui use statement and add buffer::Buffer
content.gsub!("use ratatui::{", "use ratatui::{buffer::Buffer, ")
content.gsub!("use ratatui::layout::Rect;", "use ratatui::{buffer::Buffer, layout::Rect};")
end
# 3. Update widget.render calls
# frame.render_widget(widget, area) โ widget.render(area, buffer)
content.gsub!(/frame\.render_widget\(([^,]+),\s*([^)]+)\)/, '\1.render(\2, buffer)')
# 4. Update direct buffer access
content.gsub!("frame.buffer_mut()", "buffer")
# 5. Update recursive render_node calls
content.gsub!("render_node(frame,", "render_node(buffer,")
# 5.5. Update stateful widget rendering
# frame.render_stateful_widget(widget, area, state) โ StatefulWidget::render(widget, area, buffer, state)
content.gsub!(/frame\.render_stateful_widget\(([^,]+),\s*([^,]+),\s*([^)]+)\)/, 'StatefulWidget::render(\1, \2, buffer, \3)')
# Add StatefulWidget import if stateful widgets are used
if content.match?(/StatefulWidget::render/) && !content.match?(/use ratatui::widgets::StatefulWidget/) && content.match?(/use ratatui::/)
content.sub!("use ratatui::{", "use ratatui::{widgets::StatefulWidget, ")
end
# 6. Clean up any double-added Buffer imports and duplicate Widget imports
content.gsub!(/buffer::Buffer,\s*buffer::Buffer,/, "buffer::Buffer,")
content.gsub!(/widgets::Widget,\s*widgets::Widget/, "widgets::Widget")
content.gsub!(/(use ratatui::\{[^}]*widgets::Widget[^}]*),\s*widgets::Widget/, '\1')
# 7. Fix Widget trait usage - make sure Widget is imported where .render is called
# Add Widget to imports if calling .render on widgets
if content.match?(/\.render\(area,\s*buffer\)/) && !content.match?(/use ratatui::widgets::Widget/) && content.match?(/use ratatui::\{/) && !content.match?(/widgets::Widget/)
content.sub!("use ratatui::{", "use ratatui::{widgets::Widget, ")
end
# 8. For files that don't have proper Buffer imports yet, add them
if !content.match?(/use ratatui::\{[^}]*buffer::Buffer/) && content.match?(/use ratatui::/)
# Try to add to first ratatui import
content.sub!("use ratatui::", "use ratatui::{buffer::Buffer};\nuse ratatui::")
end
# 9. Special case: cursor.rs uses frame.set_cursor_position which doesn't exist on Buffer
# Cursor widget needs special handling - it can't work with just Buffer
if File.basename(filepath) == "cursor.rs"
puts " โ cursor.rs requires special handling - skipping set_cursor_position"
# This widget can't be fully migrated as set_cursor_position is Frame-only
# Will need manual fix or different approach
end
# Only write if content changed
if content != original_content
File.write(filepath, content)
puts " โ Updated #{File.basename(filepath)}"
true
else
puts " - No changes needed for #{File.basename(filepath)}"
false
end
end
def main
puts "Starting widget renderer migration..."
puts "=" * 60
updated_count = 0
WIDGET_FILES.each do |filename|
filepath = File.join(WIDGETS_DIR, filename)
unless File.exist?(filepath)
puts " โ File not found: #{filename}"
next
end
# Create backup
backup_path = "#{filepath}.premigration"
FileUtils.cp(filepath, backup_path) unless File.exist?(backup_path)
updated_count += 1 if migrate_file(filepath)
end
puts "=" * 60
puts "Migration complete!"
puts " Files updated: #{updated_count}/#{WIDGET_FILES.length}"
puts "\nBackups saved with .premigration extension"
puts "Run 'bundle exec rake compile' to verify the changes"
end
main if __FILE__ == $PROGRAM_NAME