Skip to content

Rewrite native Go/C extensions as pure Ruby#8

Open
khasinski wants to merge 7 commits intomarcoroth:mainfrom
khasinski:pure-ruby
Open

Rewrite native Go/C extensions as pure Ruby#8
khasinski wants to merge 7 commits intomarcoroth:mainfrom
khasinski:pure-ruby

Conversation

@khasinski
Copy link
Contributor

@khasinski khasinski commented Mar 8, 2026

Summary

  • Replace Go/C/CGo native extensions with pure Ruby implementations
  • Only runtime dependency: unicode-display_width for terminal width calculation
  • All 196 tests pass (160 original + 36 new)

New modules

  • Ansi -- escape sequence generation and stripping
  • Color -- profile detection, hex/ANSI256 resolution, adaptive colors
  • ColorBlend -- LUV/HCL color space blending
  • Renderer -- layout join/place functions
  • Immutable -- shared builder pattern for Style, Table, List, Tree
  • List -- 6 enumerator types, nesting support
  • Tree -- recursive nesting, two enumerator styles

Rewritten modules

  • Style -- full render pipeline (tabs, max_width, alignment, padding, border, margins, ANSI)
  • Table -- column auto-fit, width distribution, border rendering, style_func
  • Border -- character definitions for all border types

Replace Go/CGo/C native extensions with pure Ruby implementations.
Only runtime dependency is unicode-display_width for terminal width
calculation.

New modules: Ansi (escape sequences), Color (profile detection, hex/
ANSI256 resolution), ColorBlend (LUV/HCL blending), Renderer (layout
join/place), Immutable (shared builder pattern), List, Tree.

Existing modules rewritten: Style (full render pipeline), Table
(column auto-fit, width distribution, border rendering), Border
(character definitions for all border types).

Also updates CI workflow, Rakefile, Gemfile.lock, and RBS type
signatures to remove Go/compile steps and match the new pure Ruby API.
36 new tests covering: ANSI code verification, tab conversion, style
getters, word wrapping, combined styles, empty content, border_row,
border_style on tables, Ansi module, Color module, inheritance,
nested trees/lists.
HEADER_ROW and style_func were declared in both lipgloss.rbs and
table.rbs, causing steep to fail. Remove duplicates from per-file
RBS files since lipgloss.rbs has the complete declarations.
Update RBS signatures to declare all new modules, constants, and
private methods. Configure Steepfile to downgrade metaprogramming-
related diagnostics (define_method, allocate, instance_variable_set)
that steep cannot resolve.
Auto-correct layout, style, and lint offenses. Add rubocop exclusions
for metrics and naming cops on render methods and color math code that
use short variable names (r, g, b) and have inherent complexity.
Reorder Style render pipeline to match Go lipgloss: ANSI styling
before padding, inline strips input newlines, height applied after
padding. Split apply_width_and_alignment into apply_wrapping and
apply_horizontal_alignment.

Fix JoinHorizontal to normalize line widths within blocks before
joining. Add column shrinking to Table distribute_width (shrink widest
first). Implement table height property. Change Table style_func to
lazy block evaluation. Add Ansi.truncate for shared ANSI-aware
truncation with RESET emit. Fix enumerator style spacing in List/Tree.

Move rubocop file-level excludes to inline disables. Split
pure_ruby_test.rb into feature-specific test files. Add 18 new tests
covering all fixes.
# First line of subtree (the root)
sub_root = sub_lines[0]
styled_prefix = if @enumerator_style
"#{@enumerator_style.render(prefix.rstrip)} "
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Behavior change vs native ext: re-adds space after styled enumerator symbol. Native ext omitted it, but Go lipgloss v1.1.0 uses PaddingRight(1) to add the space. Same change in list.rb:60.

@khasinski khasinski marked this pull request as ready for review March 9, 2026 16:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant