table_tennis 0.0.3 → 0.0.4

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: 1d899b2742e12311a8f7e7b80cf4f6aad23eaeb45962c175740793bc1ef3e195
4
- data.tar.gz: 0ffd8dedbfd54dda07db0cf3bd3a171bc869a21779e43828dc7e7e6b0dcfc929
3
+ metadata.gz: bca2e5c4c1a64c9e8fee14a693e5dc678554c20973f5b1cdc585584623dcc99b
4
+ data.tar.gz: e2be7d5e448f04488c882bd63ac81a029f6008e43877b7c1112bb5a7a1a7a958
5
5
  SHA512:
6
- metadata.gz: b2f3a271ad8075d5ee6e590a580df33128124e3f3f97a8d9fae9e5d3fff1ef31dcb36ba4363bfd4d269c47c8a7fffeda79dbc2d4d6e5d5db755f9f2173f5dd25
7
- data.tar.gz: 78c83e5ecfad29dcc4e998426f798e11a023f74b02e9a4c46c4425925bc133556f2f5d0aea9416a313ab1513b9e9bba0605729e3cc391c47ec6e5abfa113f8e6
6
+ metadata.gz: 466b38cbfb6f20eabb66de0e4f125faac7f50cc903406559217ebd38e2b7fc40bc2e3b057c9b6a27c4b8165eaba76ec4cd58e710b5e34987f6ffec9a30230fce
7
+ data.tar.gz: 873288550ce91efc066d57d6a35b3c4ea56f67a4e464f9916677d61c62041c15f67d0a703694307db1079b49b0d6ad0a6e2113470c08edf154a42302ae89b834
data/.gitignore CHANGED
@@ -1,5 +1,7 @@
1
1
  .envrc
2
2
  .tool-versions
3
3
  .vscode
4
- *.gem
5
- terminals/
4
+ pkg/
5
+
6
+ # gems don't need to include this since the gemspec is enough
7
+ Gemfile.lock
data/Gemfile CHANGED
@@ -3,6 +3,8 @@ gemspec
3
3
 
4
4
  group :development, :test do
5
5
  gem "amazing_print"
6
+ gem "image_optim"
7
+ gem "image_optim_pack"
6
8
  gem "minitest"
7
9
  gem "minitest-hooks"
8
10
  gem "mocha"
@@ -10,5 +12,5 @@ group :development, :test do
10
12
  gem "pry"
11
13
  gem "rake"
12
14
  gem "simplecov", require: false
13
- gem "standard", require: false
15
+ gem "standard", require: false, platform: :mri
14
16
  end
data/README.md CHANGED
@@ -42,10 +42,10 @@ TableTennis examines the background color of your terminal to pick either the da
42
42
  Construct your table with an array of rows. Rows are hashes, ActiveRecord objects, structs, Data records, or anything that responds to `to_h`. It also supports oddballs like arrays (as rows) or even a single hash.
43
43
 
44
44
  ```ruby
45
- puts TableTennis.new([{a: "hello", b: "world"}, {a: "foo", b: "bar"})
45
+ puts TableTennis.new([{a: "hello", b: "world"}, {a: "foo", b: "bar"}])
46
46
  puts TableTennis.new(Recipe.all.to_a) # activerecord
47
47
  puts TableTennis.new(array_of_structs) # these use to_h
48
- puts TableTennis.new([[1,2],[3,4]]]) # array of arrays
48
+ puts TableTennis.new([[1,2],[3,4]]) # array of arrays
49
49
  puts TableTennis.new(authors[0]) # single hash
50
50
  ```
51
51
 
@@ -79,6 +79,7 @@ options = {
79
79
  | `row_numbers` | `false` | Show row numbers in the table. |
80
80
  | `save` | ─ | If you set this to a file path, TableTennis will save your table as a CSV file too. Useful if you want to do something else with the data. |
81
81
  | `search` | ─ | string/regex to highlight in output |
82
+ | `separators` | `true` | Include column and header separators in output. |
82
83
  | `strftime` | see → | strftime string for formatting Date/Time objects. The default is `"%Y-%m-%d"`, which looks like `2025-04-21` |
83
84
  | `theme` | nil | When unset, will be autodetected based on terminal background color. If autodetect fails the theme defaults to :dark. You can also manually specify `:dark`, `:light` or `:ansi`. If colors are turned off this setting has no effect.|
84
85
  | `title` | ─ | Add a title line to the table. |
@@ -149,8 +150,17 @@ We love CSV tools and use them all the time! Here are a few that we rely on:
149
150
  - [Terminal::Table](https://github.com/tj/terminal-table) - wonderful rubygem for pretty printing tables, great for non-hash data like confusion matrices
150
151
  - [visidata](https://www.visidata.org) - the best for poking around large files, it does everything
151
152
 
153
+ ### Changelog
154
+
155
+ #### 0.0.4 (April '25)
156
+
157
+ - Separators can be turned off with `separators: false`.
158
+ - Headers are in color now. Tweaked a few of the dark colors as well.
159
+ - Tricky math to better protect narrow columns with auto-layout.
160
+
152
161
  ### Special Thanks
153
162
 
154
163
  - [termbg](https://github.com/dalance/termbg) and [termenv](https://github.com/muesli/termenv) for showing how to safely detect the terminal background color. These libraries are widely used for Rust/Go, but as far as I know nothing similar exists for Ruby.
155
164
  - The [Paint gem](https://github.com/janlelis/paint) for help with ansi colors.
165
+ - I copied the header color themes from [tabiew](https://github.com/shshemi/tabiew). Great project!
156
166
  - Google Sheets for providing nice color scales
data/Rakefile CHANGED
@@ -1,5 +1,7 @@
1
1
  require "bundler/setup"
2
2
  require "rake/testtask"
3
+ require "bundler"
4
+ Bundler::GemHelper.install_tasks
3
5
 
4
6
  Rake::TestTask.new do
5
7
  # let the user pass *.rb on the command line
data/demo.tape ADDED
@@ -0,0 +1,23 @@
1
+ #
2
+ # script for vhs (https://github.com/charmbracelet/vhs)
3
+ #
4
+
5
+ # vhs settings
6
+ Output "/tmp/demo.gif"
7
+ Set FontFamily Menlo
8
+ Set FontSize 28
9
+ Set Width 1520
10
+ Set Height 1100
11
+ Set Margin 0
12
+ Set Padding 0
13
+
14
+ # fire up the app
15
+ Hide
16
+ Type@1ms "tennis --clear --demo 3 --title 'Star Wars People' --zebra --columns name,height,homeworld,species,films --color-scale height"
17
+ Enter
18
+ Wait+Screen /Star/
19
+ Show
20
+
21
+ # now take the screenshot
22
+ Sleep 0.5
23
+ Screenshot "/tmp/dark.png"
data/justfile CHANGED
@@ -1,79 +1,71 @@
1
+ default: test
1
2
 
2
- # read gem version
3
- gemver := `grep -Eo "[0-9]+\.[0-9]+\.[0-9]+" lib/table_tennis/version.rb`
4
-
5
- #
6
- # dev
7
- #
3
+ # check repo - lint & test
4
+ check: lint test
8
5
 
9
- default:
10
- @just --list
6
+ # for ci. don't bother linting on windows
7
+ ci:
8
+ @if [[ "{{os()}}" != "windows" ]]; then just lint ; fi
9
+ @just test
11
10
 
12
- check: lint test
11
+ # check test coverage
12
+ coverage:
13
+ COVERAGE=1 just test
14
+ open /tmp/coverage/index.html
13
15
 
14
- ci: check
16
+ # format with rubocop
17
+ format: (lint "-a")
15
18
 
19
+ gem-local:
20
+ @just _banner rake install:local...
21
+ bundle exec rake install:local
16
22
 
17
- format:
18
- @just banner format...
19
- bundle exec rubocop -a
23
+ # this will tag, build and push to rubygems
24
+ gem-push: check
25
+ @just _banner rake release...
26
+ rake release
20
27
 
28
+ # optimize images
21
29
  image_optim:
22
- @bundle exec image_optim --allow-lossy --svgo-precision=1 -r .
30
+ @# advpng/pngout are slow. consider --verbose as well
31
+ @bundle exec image_optim --allow-lossy --svgo-precision=1 --no-advpng --no-pngout -r .
23
32
 
24
- lint:
25
- @just banner lint...
26
- bundle exec rubocop
33
+ # lint with rubocop
34
+ lint *ARGS:
35
+ @just _banner lint...
36
+ bundle exec rubocop {{ARGS}}
27
37
 
38
+ # start pry with the lib loaded
28
39
  pry:
29
40
  bundle exec pry -I lib -r table_tennis.rb
30
41
 
42
+ # run tennis repeatedly
31
43
  tennis-watch *ARGS:
32
44
  @watchexec --stop-timeout=0 --clear clear tennis {{ARGS}}
33
45
 
46
+ # run tests
34
47
  test *ARGS:
35
- @just banner rake test {{ARGS}}
48
+ @just _banner rake test {{ARGS}}
36
49
  @bundle exec rake test {{ARGS}}
37
50
 
51
+ # run tests repeatedly
38
52
  test-watch *ARGS:
39
- @watchexec --stop-timeout=0 --clear clear just test "{{ARGS}}"
53
+ watchexec --stop-timeout=0 --clear clear just test "{{ARGS}}"
40
54
 
41
- #
42
- # coverage/profiling
43
- #
44
-
45
- coverage:
46
- COVERAGE=1 just test
47
- open /tmp/coverage/index.html
48
-
49
- #
50
- # gem tasks
51
- #
52
-
53
- # you can test locally from another project by dropping gem file into vendor/cache
54
- gem-push:
55
- @just banner bundle install and verify git...
56
- bundle install
57
- #@just check-git-status
58
- @just banner gem build...
59
- gem build table_tennis.gemspec
60
- @just banner tag...
61
- git tag -a "v{{gemver}}" -m "Tagging {{gemver}}"
62
- git push --tags
63
- @just banner gem push...
64
- gem push "table_tennis-{{gemver}}.gem"
55
+ # create sceenshot using vhs
56
+ vhs:
57
+ @just _banner "running vhs..."
58
+ vhs demo.tape
59
+ magick /tmp/dark.png -crop 1448x1004+18+16 screenshots/dark.png
65
60
 
66
61
  #
67
62
  # util
68
63
  #
69
64
 
70
- banner *ARGS: (_banner BG_GREEN ARGS)
71
- warning *ARGS: (_banner BG_YELLOW ARGS)
72
- fatal *ARGS: (_banner BG_RED ARGS)
65
+ _banner *ARGS: (_message BG_GREEN ARGS)
66
+ _warning *ARGS: (_message BG_YELLOW ARGS)
67
+ _fatal *ARGS: (_message BG_RED ARGS)
73
68
  @exit 1
74
- _banner color *ARGS:
69
+ _message color *ARGS:
75
70
  @msg=$(printf "[%s] %s" $(date +%H:%M:%S) "{{ARGS}}") ; \
76
71
  printf "{{color+BOLD+WHITE}}%-72s{{ NORMAL }}\n" "$msg"
77
-
78
- check-git-status:
79
- @if [ ! -z "$(git status --porcelain)" ]; then just fatal "git status is dirty, bailing."; fi
@@ -18,6 +18,7 @@ module TableTennis
18
18
  row_numbers: false, # show line numbers?
19
19
  save: nil, # csv file path to save the table when created
20
20
  search: nil, # string/regex to highlight in output
21
+ separators: true, # if true, show separators between columns
21
22
  strftime: nil, # string for formatting dates
22
23
  theme: nil, # :dark, :light or :ansi. :dark is the default
23
24
  title: nil, # string for table title, if any
@@ -51,6 +52,7 @@ module TableTennis
51
52
  placeholder: :str,
52
53
  row_numbers: :bool,
53
54
  save: :str,
55
+ separators: :bool,
54
56
  strftime: :str,
55
57
  title: :str,
56
58
  titleize: :bool,
@@ -28,8 +28,7 @@ module TableTennis
28
28
  # some math
29
29
  #
30
30
 
31
- AUTOLAYOUT_MIN_COLUMN_WIDTH = 2
32
- AUTOLAYOUT_FUDGE = 2
31
+ FUDGE = 2
33
32
 
34
33
  # Fit columns into terminal width. This is copied from the very simple HTML
35
34
  # table column algorithm. Returns a hash of column name to width.
@@ -37,30 +36,35 @@ module TableTennis
37
36
  # set provisional widths
38
37
  columns.each { _1.width = _1.measure }
39
38
 
40
- # how much space is available, and do we already fit?
39
+ # How much space is available, and do we already fit?
41
40
  screen_width = IO.console.winsize[1]
42
- available = screen_width - chrome_width - AUTOLAYOUT_FUDGE
41
+ available = screen_width - chrome_width - FUDGE
43
42
  return if available >= data_width
44
43
 
45
- # min/max column widths, which we use below
46
- min = columns.map { [_1.width, AUTOLAYOUT_MIN_COLUMN_WIDTH].min }
47
- max = columns.map(&:width)
44
+ # We don't fit, so we are going to shrink (truncate) some columns.
45
+ # Potentially all the way down to a lower bound. But what is the lower
46
+ # bound? It's nice to have a generous value so that narrow columns have
47
+ # a shot at avoiding truncation. That isn't always possible, though.
48
+ lower_bound = (available / columns.length).clamp(2, 10)
48
49
 
49
- # W = difference between the available space and the minimum table width
50
- # D = difference between maximum and minimum width of the table
51
- w = available - min.sum
52
- d = max.sum - min.sum
50
+ # Calculate a "min" and a "max" for each column, then allocate available
51
+ # space proportionally to each column. This is similar to the algorithm
52
+ # for HTML tables.
53
+ min = max = columns.map(&:width)
54
+ min = min.map { [_1, lower_bound].min }
53
55
 
54
- # edge case if we don't even have enough room for min
55
- if w <= 0
56
+ # W = difference between the available space and the minimum table width
57
+ # D = difference between maximum and minimum table width
58
+ # ratio = W / D
59
+ # col.width = col.min + ((col.max - col.min) * ratio)
60
+ ratio = (available - min.sum).to_f / (max.sum - min.sum)
61
+ if ratio <= 0
62
+ # even min doesn't fit, we gotta overflow
56
63
  columns.each.with_index { _1.width = min[_2] }
57
64
  return
58
65
  end
59
-
60
- # expand min to fit available space
61
- columns.each.with_index do
62
- # width = min + (delta * W / D)
63
- _1.width = min[_2] + ((max[_2] - min[_2]) * w / d.to_f).to_i
66
+ columns.zip(min, max).each do |column, min, max|
67
+ column.width = min + ((max - min) * ratio).to_i
64
68
  end
65
69
 
66
70
  # because we always round down, there might be some extra space to distribute
@@ -16,6 +16,7 @@ module TableTennis
16
16
  def run
17
17
  return if !config.color
18
18
  paint_title if config.title
19
+ paint_headers
19
20
  paint_row_numbers if config.row_numbers
20
21
  paint_rows if config.mark || config.zebra
21
22
  paint_columns if config.color_scales
@@ -32,6 +33,14 @@ module TableTennis
32
33
  set_style(r: :title, style: :title)
33
34
  end
34
35
 
36
+ NHEADER_COLORS = 6
37
+
38
+ def paint_headers
39
+ columns.each.with_index do |column, c|
40
+ set_style(r: :header, c:, style: :"header#{c % Theme::NHEADER_COLORS}")
41
+ end
42
+ end
43
+
35
44
  def paint_row_numbers
36
45
  set_style(c: 0, style: :chrome)
37
46
  end
@@ -127,8 +136,12 @@ module TableTennis
127
136
 
128
137
  def mark_style(user_mark)
129
138
  case user_mark
130
- when String, Symbol then [nil, user_mark] # assume bg color
131
- when Array then user_mark # a Paint array
139
+ when String, Symbol
140
+ # pick a nice fg color
141
+ [Util::Colors.contrast(user_mark), user_mark]
142
+ when Array
143
+ # a Paint array
144
+ user_mark
132
145
  else; :mark # default
133
146
  end
134
147
  end
@@ -32,12 +32,12 @@ module TableTennis
32
32
  if config.title
33
33
  io.puts render_separator(NW, BAR, NE)
34
34
  io.puts render_title
35
- io.puts render_separator(W, N, E)
35
+ io.puts render_separator(W, N, E) if config.separators
36
36
  else
37
37
  io.puts render_separator(NW, N, NE)
38
38
  end
39
39
  io.puts render_row(:header)
40
- io.puts render_separator(W, C, E)
40
+ io.puts render_separator(W, C, E) if config.separators
41
41
  rows.each_index { io.puts render_row(_1) }
42
42
  io.puts render_separator(SW, S, SE)
43
43
  end
@@ -59,9 +59,10 @@ module TableTennis
59
59
 
60
60
  # assemble line by rendering cells
61
61
  enum = (r != :header) ? rows[r].each : columns.map(&:header)
62
+ joiner = config.separators ? " #{pipe} " : " "
62
63
  line = enum.map.with_index do |value, c|
63
64
  render_cell(value, r, c, row_style)
64
- end.join(" #{pipe} ")
65
+ end.join(joiner)
65
66
  line = "#{pipe} #{line} #{pipe}"
66
67
 
67
68
  # afterward, apply row color
@@ -95,6 +96,7 @@ module TableTennis
95
96
  end
96
97
 
97
98
  def render_separator(l, m, r)
99
+ m = "" if !config.separators
98
100
  line = [].tap do |buf|
99
101
  columns.each.with_index do |column, c|
100
102
  buf << ((c == 0) ? l : m)
@@ -44,9 +44,13 @@ module TableTennis
44
44
  # Lazily calculate the list of columns.
45
45
  def columns
46
46
  names = config&.columns
47
- names ||= {}.tap do |memo|
48
- fat_rows.each { |row| row.each_key { memo[_1] = 1 } }
49
- end.keys
47
+ if !fat_rows.empty?
48
+ names ||= {}.tap do |memo|
49
+ fat_rows.each { |row| row.each_key { memo[_1] = 1 } }
50
+ end.keys
51
+ else
52
+ names = []
53
+ end
50
54
  names.each do |name|
51
55
  if !fat_rows.any? { _1.key?(name) }
52
56
  raise ArgumentError, "specified column `#{name}` not found in any row of input data"
@@ -88,13 +92,22 @@ module TableTennis
88
92
 
89
93
  # layout math
90
94
  #
91
- # |•xxxx•|•xxxx•|•xxxx•|•xxxx•||•xxxx•|•xxxx•|•xxxx•|•xxxx•|
92
- # ↑↑ ↑ ↑
93
- # 12 3 <- three chrome chars per column │
94
- #
95
- # extra chrome char at the end
96
- #
97
- def chrome_width = columns.length * 3 + 1
95
+ # with separators
96
+ # |•xxxx•|•xxxx•|•xxxx•|•xxxx•|•xxxx•|•xxxx•|•xxxx•|•xxxx•|
97
+ # ↑↑ ↑ ↑
98
+ # 12 3 <- three chrome chars per column
99
+ #
100
+ # extra chrome char at the end
101
+ # without
102
+ # |•xxxx••xxxx••xxxx••xxxx••xxxx••xxxx••xxxx••xxxx•|
103
+ # ↑ ↑ ↑
104
+ # 1 2 <- two chrome chars per column │
105
+ # │
106
+ # extra chrome char at beginning and end
107
+ def chrome_width
108
+ config.separators ? (columns.length * 3 + 1) : (columns.length * 2 + 2)
109
+ end
110
+ memo_wise :chrome_width
98
111
 
99
112
  # for debugging
100
113
  def debug(str)
@@ -5,27 +5,46 @@ module TableTennis
5
5
  prepend MemoWise
6
6
 
7
7
  RESET = Paint::NOTHING
8
+ NHEADER_COLORS = 6
8
9
  THEMES = {
9
10
  dark: {
10
- title: "#7f0",
11
+ title: ["blue-400", :bold],
11
12
  chrome: "gray-500",
12
13
  cell: "gray-200",
14
+ header0: ["#ff6188", :bold],
15
+ header1: ["#fc9867", :bold],
16
+ header2: ["#ffd866", :bold],
17
+ header3: ["#a9dc76", :bold],
18
+ header4: ["#78dce8", :bold],
19
+ header5: ["#ab9df2", :bold],
13
20
  mark: %w[white blue-500],
14
21
  search: %w[black yellow-300],
15
- zebra: %w[white #333],
22
+ zebra: %w[white #222],
16
23
  },
17
24
  light: {
18
- title: "blue-600",
25
+ title: ["blue-600", :bold],
19
26
  chrome: "#bbb",
20
27
  cell: "gray-800",
28
+ header0: ["#ee4066", :bold],
29
+ header1: ["#da7645", :bold],
30
+ header2: ["#ddb644", :bold],
31
+ header3: ["#87ba54", :bold],
32
+ header4: ["#56bac6", :bold],
33
+ header5: ["#897bd0", :bold],
21
34
  mark: %w[white blue-500],
22
35
  search: %w[black yellow-300],
23
36
  zebra: %w[black gray-200],
24
37
  },
25
38
  ansi: {
26
- title: :green,
39
+ title: %i[green bold],
27
40
  chrome: %i[faint default],
28
41
  cell: :default,
42
+ header0: nil, # not supported
43
+ header1: nil, # not supported
44
+ header2: nil, # not supported
45
+ header3: nil, # not supported
46
+ header4: nil, # not supported
47
+ header5: nil, # not supported
29
48
  mark: %i[white blue],
30
49
  search: %i[white magenta],
31
50
  zebra: nil, # not supported
@@ -50,6 +69,7 @@ module TableTennis
50
69
  if value.is_a?(Symbol) && THEME_KEYS.include?(value)
51
70
  value = THEMES[name][value]
52
71
  end
72
+
53
73
  # turn value(s) into colors
54
74
  colors = Array(value).map { Util::Colors.get(_1) }
55
75
  return if colors == [] || colors == [nil]
@@ -439,6 +439,14 @@ module TableTennis
439
439
 
440
440
  # is this color dark?
441
441
  def dark?(color)
442
+ color = get(color)
443
+ return true if !color
444
+
445
+ # take a guess at symbols too
446
+ if color.is_a?(Symbol)
447
+ return !%i[white gray].include?(color)
448
+ end
449
+
442
450
  luma = luma(color)
443
451
  !luma || luma < DARK_LUMA
444
452
  end
@@ -1,3 +1,3 @@
1
1
  module TableTennis
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/screenshots/dark.png CHANGED
Binary file
Binary file
data/screenshots/hope.png CHANGED
Binary file
Binary file
Binary file
Binary file
Binary file
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: table_tennis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Doppelt
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-20 00:00:00.000000000 Z
10
+ date: 2025-04-28 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: csv
@@ -88,10 +88,10 @@ files:
88
88
  - ".gitignore"
89
89
  - ".rubocop.yml"
90
90
  - Gemfile
91
- - Gemfile.lock
92
91
  - LICENSE
93
92
  - README.md
94
93
  - Rakefile
94
+ - demo.tape
95
95
  - justfile
96
96
  - lib/table_tennis.rb
97
97
  - lib/table_tennis/column.rb
data/Gemfile.lock DELETED
@@ -1,122 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- table_tennis (0.0.3)
5
- csv (~> 3.3)
6
- ffi (~> 1.17)
7
- memo_wise (~> 1.11)
8
- paint (~> 2.3)
9
- unicode-display_width (~> 3.1)
10
-
11
- GEM
12
- remote: https://rubygems.org/
13
- specs:
14
- amazing_print (1.7.2)
15
- ast (2.4.3)
16
- coderay (1.1.3)
17
- csv (3.3.2)
18
- docile (1.4.1)
19
- ffi (1.17.1)
20
- ffi (1.17.1-aarch64-linux-gnu)
21
- ffi (1.17.1-aarch64-linux-musl)
22
- ffi (1.17.1-arm-linux-gnu)
23
- ffi (1.17.1-arm-linux-musl)
24
- ffi (1.17.1-arm64-darwin)
25
- ffi (1.17.1-x86-linux-gnu)
26
- ffi (1.17.1-x86-linux-musl)
27
- ffi (1.17.1-x86_64-darwin)
28
- ffi (1.17.1-x86_64-linux-gnu)
29
- ffi (1.17.1-x86_64-linux-musl)
30
- json (2.10.2)
31
- language_server-protocol (3.17.0.4)
32
- lint_roller (1.1.0)
33
- memo_wise (1.11.0)
34
- method_source (1.1.0)
35
- minitest (5.25.5)
36
- minitest-hooks (1.5.2)
37
- minitest (> 5.3)
38
- mocha (2.7.1)
39
- ruby2_keywords (>= 0.0.5)
40
- ostruct (0.6.1)
41
- paint (2.3.0)
42
- parallel (1.26.3)
43
- parser (3.3.7.4)
44
- ast (~> 2.4.1)
45
- racc
46
- prism (1.4.0)
47
- pry (0.15.2)
48
- coderay (~> 1.1)
49
- method_source (~> 1.0)
50
- racc (1.8.1)
51
- rainbow (3.1.1)
52
- rake (13.2.1)
53
- regexp_parser (2.10.0)
54
- rubocop (1.73.2)
55
- json (~> 2.3)
56
- language_server-protocol (~> 3.17.0.2)
57
- lint_roller (~> 1.1.0)
58
- parallel (~> 1.10)
59
- parser (>= 3.3.0.2)
60
- rainbow (>= 2.2.2, < 4.0)
61
- regexp_parser (>= 2.9.3, < 3.0)
62
- rubocop-ast (>= 1.38.0, < 2.0)
63
- ruby-progressbar (~> 1.7)
64
- unicode-display_width (>= 2.4.0, < 4.0)
65
- rubocop-ast (1.43.0)
66
- parser (>= 3.3.7.2)
67
- prism (~> 1.4)
68
- rubocop-performance (1.24.0)
69
- lint_roller (~> 1.1)
70
- rubocop (>= 1.72.1, < 2.0)
71
- rubocop-ast (>= 1.38.0, < 2.0)
72
- ruby-progressbar (1.13.0)
73
- ruby2_keywords (0.0.5)
74
- simplecov (0.22.0)
75
- docile (~> 1.1)
76
- simplecov-html (~> 0.11)
77
- simplecov_json_formatter (~> 0.1)
78
- simplecov-html (0.13.1)
79
- simplecov_json_formatter (0.1.4)
80
- standard (1.47.0)
81
- language_server-protocol (~> 3.17.0.2)
82
- lint_roller (~> 1.0)
83
- rubocop (~> 1.73.0)
84
- standard-custom (~> 1.0.0)
85
- standard-performance (~> 1.7)
86
- standard-custom (1.0.2)
87
- lint_roller (~> 1.0)
88
- rubocop (~> 1.50)
89
- standard-performance (1.7.0)
90
- lint_roller (~> 1.1)
91
- rubocop-performance (~> 1.24.0)
92
- unicode-display_width (3.1.4)
93
- unicode-emoji (~> 4.0, >= 4.0.4)
94
- unicode-emoji (4.0.4)
95
-
96
- PLATFORMS
97
- aarch64-linux-gnu
98
- aarch64-linux-musl
99
- arm-linux-gnu
100
- arm-linux-musl
101
- arm64-darwin
102
- ruby
103
- x86-linux-gnu
104
- x86-linux-musl
105
- x86_64-darwin
106
- x86_64-linux-gnu
107
- x86_64-linux-musl
108
-
109
- DEPENDENCIES
110
- amazing_print
111
- minitest
112
- minitest-hooks
113
- mocha
114
- ostruct
115
- pry
116
- rake
117
- simplecov
118
- standard
119
- table_tennis!
120
-
121
- BUNDLED WITH
122
- 2.6.5