cani 0.5.8 → 0.5.9

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
- SHA256:
3
- metadata.gz: 97a7a44de697f793827e056d88bc55cdc51c8d5d44119b75c3f1fc619b1c10a3
4
- data.tar.gz: dc62177619b558a496c499c63754210b157f1a84513b4f24636ad20961995df3
2
+ SHA1:
3
+ metadata.gz: bbdbb28b9c3709f04c106775b5d019f7d4e29177
4
+ data.tar.gz: cb812356aac2f7ad341f8d80fe16db97539813b4
5
5
  SHA512:
6
- metadata.gz: ad9b0f922f4816e1ab336a868f06a732298837ef5d9eecf271e93aa29bee6c78a14f7d04241ef3d2b123fbd117cec43b731edfeaf8df4873a463b24c0280c06b
7
- data.tar.gz: '09a7aee1a40aada6855807b20f5de20b4cd5a91db1ff0cdd65d89969ffa3ac50fd762a0f480abc21a470f685b0d78f244f66a0d5a18c5ce6c685b7a3a775231c'
6
+ metadata.gz: 01ffd79c7dcbb0aae80cac9585d687eaf00c2226f617d4a70cb409384d9938373363e5b38d93c8988f6e92a525ce88774cb0aa922a3435cf4381b1dbb203d8f0
7
+ data.tar.gz: fc4287ccb47965a06f6218af9de4d67d1ff63d677687d5042fd3df9bb9e13e630463727269bb08a89f2c58d31a05ee66739578b9a97a61a329983306e8fdd781
@@ -0,0 +1 @@
1
+ TargetRubyVersion: "2.1"
@@ -0,0 +1,15 @@
1
+ ### 24-07-2019 VERSION 0.5.6
2
+
3
+ - Fix issue where `cani` would crash when used without arguments. Original behavior of showing `cani help` in that case is restored. ([#14](../../pull/14))
4
+ - Disable FZF's preview window using `--no-preview` to override `FZF_DEFAULT_OPTS` ([#12](../../issues/12))
5
+
6
+ ### 06-07-2019 VERSION 0.5.5
7
+
8
+ - Added ability to (permanently) toggle between enabling and disabling of automatic shell configuration injection
9
+
10
+ ### 06-10-2018 VERSION 0.5.4
11
+
12
+ - Fixed issue where `system` prints the version of fzf before running the command.
13
+ - When multiple matches are found for a given query: `cani use shadow`, an fzf window will
14
+ now be opened with results filtered by the text `shadow` as initial query string.
15
+
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in cani.gemspec
6
6
  gemspec
data/README.md CHANGED
@@ -10,6 +10,13 @@ on a regular interval together with completions.
10
10
 
11
11
  ## Latest changes
12
12
 
13
+ dates are in dd-mm-yyyy format older changes can be found in the [changelog](/CHANGELOG.md)
14
+
15
+ ### 16-09-2019 VERSION 0.5.9
16
+
17
+ - Fix glitch where current era border would be drawn incorrectly at certain widths.
18
+ - Do not print an empty era row if none of the visible browsers show anything.
19
+
13
20
  ### 28-07-2019 VERSION 0.5.8
14
21
 
15
22
  - Fix line overflow issue when terminal is too small for "widest" display
@@ -19,21 +26,6 @@ on a regular interval together with completions.
19
26
 
20
27
  - Titles shown in `cani use` may take up to 50 characters if the terminal is wide enough.
21
28
 
22
- ### 24-07-2019 VERSION 0.5.6
23
-
24
- - Fix issue where `cani` would crash when used without arguments. Original behavior of showing `cani help` in that case is restored. ([#14](../../pull/14))
25
- - Disable FZF's preview window using `--no-preview` to override `FZF_DEFAULT_OPTS` ([#12](../../issues/12))
26
-
27
- ### 06-07-2019 VERSION 0.5.5
28
-
29
- - Added ability to (permanently) toggle between enabling and disabling of automatic shell configuration injection
30
-
31
- ### 06-10-2018 VERSION 0.5.4
32
-
33
- - Fixed issue where `system` prints the version of fzf before running the command.
34
- - When multiple matches are found for a given query: `cani use shadow`, an fzf window will
35
- now be opened with results filtered by the text `shadow` as initial query string.
36
-
37
29
  ## Installation
38
30
 
39
31
  Add this line to your application's Gemfile:
@@ -227,9 +219,9 @@ Last but not least, all `cani` commands can be piped. This will skip running `fz
227
219
  **use** _(the output of_ `cani use ft-name` _cannot be piped)_
228
220
  ```sh
229
221
  cani use | head -3
230
- [rc] 97.11% PNG alpha transparency +chr +ff +edge +ie +saf +saf.ios +op +and +bb
231
- [un] 75.85% Animated PNG (APNG) +chr +ff -edge -ie +saf +saf.ios +op -and -bb
232
- [ls] 94.32% Video element +chr +ff +edge +ie +saf +saf.ios +op +and +bb
222
+ [rc] 97.11% PNG alpha transparency +chr +ff +edge +ie +saf +saf.ios +op +and +bb
223
+ [un] 75.85% Animated PNG (APNG) +chr +ff -edge -ie +saf +saf.ios +op -and -bb
224
+ [ls] 94.32% Video element +chr +ff +edge +ie +saf +saf.ios +op +and +bb
233
225
  ```
234
226
 
235
227
  **show**
@@ -10,27 +10,29 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ['sidneyliebrand@gmail.com']
11
11
 
12
12
  spec.summary = 'A simple caniuse CLI.'
13
- spec.description = 'An interactive TUI (using FZF / Curses) for exploring caniuse.com in your terminal.'
13
+ spec.description = 'An interactive TUI (using FZF / Curses) ' \
14
+ 'for exploring caniuse.com in your terminal.'
14
15
  spec.homepage = 'https://github.com/SidOfc/cani'
15
16
  spec.license = 'MIT'
16
17
 
17
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
18
19
  `git ls-files -z`.split("\x0").reject do |f|
19
20
  f.match(%r{^(test|spec|features|assets)/})
20
21
  end
21
22
  end
22
23
 
23
- spec.bindir = 'exe'
24
- spec.require_paths = ['lib']
25
- spec.executables << 'cani'
24
+ spec.bindir = 'exe'
25
+ spec.require_paths = ['lib']
26
+
27
+ spec.executables << 'cani'
26
28
 
27
29
  spec.add_runtime_dependency 'colorize'
28
30
  spec.add_runtime_dependency 'curses'
29
- spec.add_runtime_dependency 'tty-screen'
30
31
  spec.add_runtime_dependency 'json'
32
+ spec.add_runtime_dependency 'tty-screen'
31
33
 
32
- spec.add_development_dependency 'bundler', '~> 1.16'
34
+ spec.add_development_dependency 'bundler'
33
35
  spec.add_development_dependency 'pry'
34
- spec.add_development_dependency 'rake', '~> 10.0'
35
- spec.add_development_dependency 'rspec', '~> 3.0'
36
+ spec.add_development_dependency 'rake', '~> 12'
37
+ spec.add_development_dependency 'rspec'
36
38
  end
@@ -66,8 +66,8 @@ module Cani
66
66
  name = Regexp.new name.to_s.downcase.gsub(/(\W)/, '.*'), :i
67
67
  features.select do |ft|
68
68
  ft.title.downcase.match(name) ||
69
- ft.name.downcase.match(name) ||
70
- ft.description.downcase.match(name)
69
+ ft.name.downcase.match(name) ||
70
+ ft.description.downcase.match(name)
71
71
  end
72
72
  end
73
73
 
@@ -5,24 +5,24 @@ module Cani
5
5
 
6
6
  ABBR_MAP = { 'ios' => 'saf.ios' }.freeze
7
7
  LABEL_MAP = {
8
- 'ie' => 'Internet Explorer',
9
- 'edge' => 'Edge',
10
- 'ff' => 'Firefox',
11
- 'chr' => 'Chrome',
12
- 'saf' => 'Safari',
13
- 'op' => 'Opera',
8
+ 'ie' => 'Internet Explorer',
9
+ 'edge' => 'Edge',
10
+ 'ff' => 'Firefox',
11
+ 'chr' => 'Chrome',
12
+ 'saf' => 'Safari',
13
+ 'op' => 'Opera',
14
14
  'saf.ios' => 'IOS Safari',
15
- 'o.mini' => 'Opera Mini',
16
- 'and' => 'Android Browser',
17
- 'bb' => 'BlackBerry Browser',
18
- 'o.mob' => 'Opera Mobile',
15
+ 'o.mini' => 'Opera Mini',
16
+ 'and' => 'Android Browser',
17
+ 'bb' => 'BlackBerry Browser',
18
+ 'o.mob' => 'Opera Mobile',
19
19
  'chr.and' => 'Chrome for Android',
20
- 'ff.and' => 'Firefox for Android',
21
- 'ie.mob' => 'Internet Explorer Mobile',
22
- 'uc' => 'UC Browser for android',
23
- 'ss' => 'Samsung Internet',
24
- 'qq' => 'QQ Browser',
25
- 'baidu' => 'Baidu Browser'
20
+ 'ff.and' => 'Firefox for Android',
21
+ 'ie.mob' => 'Internet Explorer Mobile',
22
+ 'uc' => 'UC Browser for android',
23
+ 'ss' => 'Samsung Internet',
24
+ 'qq' => 'QQ Browser',
25
+ 'baidu' => 'Baidu Browser'
26
26
  }.freeze
27
27
 
28
28
  def initialize(attributes = {})
@@ -4,19 +4,19 @@ module Cani
4
4
  attr_reader :title, :status, :spec, :stats, :percent, :name, :browser_note_nums, :notes, :notes_by_num, :description
5
5
 
6
6
  STATUSES = {
7
- 'rec' => 'rc',
7
+ 'rec' => 'rc',
8
8
  'unoff' => 'un',
9
9
  'other' => 'ot'
10
10
  }.freeze
11
11
 
12
12
  TYPES = {
13
- 'y' => {symbol: '+', name: :default, short: :sup},
14
- 'a' => {symbol: '~', name: :partial, short: :prt},
15
- 'n' => {symbol: '-', name: :unsupported, short: :not},
16
- 'p' => {symbol: '#', name: :polyfill, short: :ply},
17
- 'x' => {symbol: '@', name: :prefix, short: :pfx},
18
- 'd' => {symbol: '!', name: :flag, short: :flg},
19
- 'u' => {symbol: '?', name: :unknown, short: :unk}
13
+ 'y' => { symbol: '+', name: :default, short: :sup },
14
+ 'a' => { symbol: '~', name: :partial, short: :prt },
15
+ 'n' => { symbol: '-', name: :unsupported, short: :not },
16
+ 'p' => { symbol: '#', name: :polyfill, short: :ply },
17
+ 'x' => { symbol: '@', name: :prefix, short: :pfx },
18
+ 'd' => { symbol: '!', name: :flag, short: :flg },
19
+ 'u' => { symbol: '?', name: :unknown, short: :unk }
20
20
  }.freeze
21
21
 
22
22
  def initialize(attributes = {})
@@ -2,33 +2,47 @@ module Cani
2
2
  class Api
3
3
  class Feature
4
4
  class Viewer
5
- attr_reader :width, :height, :feature, :browsers, :viewable, :col_width, :table_width
5
+ attr_reader :width, :height, :feature, :browsers, :viewable,
6
+ :col_width, :table_width
6
7
 
7
8
  COLOR_PAIRS = {
8
9
  # foreground colors
9
- 69 => [70, -1], # green on default (legend supported, feature status, percentage counter)
10
- 213 => [208, -1], # orange on default (legend partial, percentage counter)
11
- 195 => [160, -1], # red on default (legend unsupported, percentage counter)
12
- 133 => [134, -1], # magenta on default (legend flag, current feature status)
13
- 12 => [75, -1], # blue on default (legend prefix)
10
+
11
+ # green on default
12
+ # (legend supported, feature status, percentage counter)
13
+ 69 => [70, -1],
14
+
15
+ # orange on default
16
+ # (legend partial, percentage counter)
17
+ 213 => [208, -1],
18
+
19
+ # red on default
20
+ # (legend unsupported, percentage counter)
21
+ 195 => [160, -1],
22
+
23
+ # magenta on default
24
+ # (legend flag, current feature status)
25
+ 133 => [134, -1],
26
+
27
+ 12 => [75, -1], # blue on default (legend prefix)
14
28
  204 => [205, -1], # pink on default (legend polyfill)
15
- 99 => [239, -1], # gray on default (legend unknown)
29
+ 99 => [239, -1], # gray on default (legend unknown)
16
30
 
17
31
  # note background + foreground colors
18
- 71 => [22, 70], # dark green on green (supported feature)
32
+ 71 => [22, 70], # dark green on green (supported feature)
19
33
  209 => [130, 208], # dark orange on orange (partial feature)
20
34
  197 => [88, 160], # dark red on red (unsupported feature)
21
35
  135 => [91, 134], # dark magenta on magenta (flag features)
22
- 13 => [27, 75], # dark blue on blue (prefix feature)
36
+ 13 => [27, 75], # dark blue on blue (prefix feature)
23
37
  101 => [235, 239], # dark gray on gray (unknown features)
24
38
  206 => [127, 205], # dark pink on pink (polyfill features)
25
39
 
26
40
  # background colors
27
- 70 => [7, 70], # white on green (supported feature)
41
+ 70 => [7, 70], # white on green (supported feature)
28
42
  208 => [7, 208], # white on orange (partial feature)
29
43
  196 => [7, 160], # white on red (unsupported feature)
30
44
  134 => [7, 134], # white on magenta (flag features)
31
- 11 => [7, 75], # white on blue (prefix feature)
45
+ 11 => [7, 75], # white on blue (prefix feature)
32
46
  100 => [7, 239], # white on gray (unknown features)
33
47
  205 => [7, 205], # white on pink (polyfill features)
34
48
 
@@ -39,45 +53,48 @@ module Cani
39
53
 
40
54
  COLORS = {
41
55
  # table headers
42
- header: {fg: Curses.color_pair(254), bg: Curses.color_pair(254)},
56
+ header: { fg: Curses.color_pair(254), bg: Curses.color_pair(254) },
43
57
 
44
58
  # current era border
45
- era_border: {fg: Curses.color_pair(239), bg: Curses.color_pair(239)},
59
+ era_border: { fg: Curses.color_pair(239),
60
+ bg: Curses.color_pair(239) },
46
61
 
47
62
  # support types
48
- default: {fg: Curses.color_pair(69), bg: Curses.color_pair(70)},
49
- partial: {fg: Curses.color_pair(213), bg: Curses.color_pair(208)},
50
- prefix: {fg: Curses.color_pair(12), bg: Curses.color_pair(11)},
51
- polyfill: {fg: Curses.color_pair(204), bg: Curses.color_pair(205)},
52
- flag: {fg: Curses.color_pair(133), bg: Curses.color_pair(134)},
53
- unsupported: {fg: Curses.color_pair(195), bg: Curses.color_pair(196)},
54
- unknown: {fg: Curses.color_pair(99), bg: Curses.color_pair(100)},
63
+ default: { fg: Curses.color_pair(69), bg: Curses.color_pair(70) },
64
+ partial: { fg: Curses.color_pair(213), bg: Curses.color_pair(208) },
65
+ prefix: { fg: Curses.color_pair(12), bg: Curses.color_pair(11) },
66
+ polyfill: { fg: Curses.color_pair(204), bg: Curses.color_pair(205) },
67
+ flag: { fg: Curses.color_pair(133), bg: Curses.color_pair(134) },
68
+ unknown: { fg: Curses.color_pair(99), bg: Curses.color_pair(100) },
69
+ unsupported: { fg: Curses.color_pair(195),
70
+ bg: Curses.color_pair(196) },
55
71
 
56
72
  # statuses
57
- un: {fg: Curses.color_pair(213), bg: Curses.color_pair(208)},
58
- ot: {fg: Curses.color_pair(133), bg: Curses.color_pair(134)}
73
+ un: { fg: Curses.color_pair(213), bg: Curses.color_pair(208) },
74
+ ot: { fg: Curses.color_pair(133), bg: Curses.color_pair(134) }
59
75
  }.freeze
60
76
 
61
77
  NOTE_COLORS = {
62
- default: {fg: Curses.color_pair(71), bg: Curses.color_pair(70)},
63
- partial: {fg: Curses.color_pair(209), bg: Curses.color_pair(208)},
64
- prefix: {fg: Curses.color_pair(13), bg: Curses.color_pair(11)},
65
- polyfill: {fg: Curses.color_pair(206), bg: Curses.color_pair(205)},
66
- flag: {fg: Curses.color_pair(135), bg: Curses.color_pair(134)},
67
- unsupported: {fg: Curses.color_pair(197), bg: Curses.color_pair(196)},
68
- unknown: {fg: Curses.color_pair(101), bg: Curses.color_pair(100)},
69
- }
78
+ default: { fg: Curses.color_pair(71), bg: Curses.color_pair(70) },
79
+ partial: { fg: Curses.color_pair(209), bg: Curses.color_pair(208) },
80
+ prefix: { fg: Curses.color_pair(13), bg: Curses.color_pair(11) },
81
+ polyfill: { fg: Curses.color_pair(206), bg: Curses.color_pair(205) },
82
+ flag: { fg: Curses.color_pair(135), bg: Curses.color_pair(134) },
83
+ unknown: { fg: Curses.color_pair(101), bg: Curses.color_pair(100) },
84
+ unsupported: { fg: Curses.color_pair(197),
85
+ bg: Curses.color_pair(196) }
86
+ }.freeze
70
87
 
71
88
  PERCENT_COLORS = {
72
- 70..101 => {fg: Curses.color_pair(69), bg: Curses.color_pair(70)},
73
- 40..70 => {fg: Curses.color_pair(213), bg: Curses.color_pair(208)},
74
- 0..40 => {fg: Curses.color_pair(195), bg: Curses.color_pair(196)}
89
+ 70..101 => { fg: Curses.color_pair(69), bg: Curses.color_pair(70) },
90
+ 40..70 => { fg: Curses.color_pair(213), bg: Curses.color_pair(208) },
91
+ 0..40 => { fg: Curses.color_pair(195), bg: Curses.color_pair(196) }
75
92
  }.freeze
76
93
 
77
- ERAS = 6 # range of eras to show around current era (incl current)
78
- COMPACT = 60 # column width at which to compress the layout
79
- PADDING = 1 # horizontal cell padding
80
- MARGIN = 1 # horizontal cell margin
94
+ ERAS = 6 # range of eras to show around current era (incl current)
95
+ COMPACT = 60 # column width at which to compress the layout
96
+ PADDING = 1 # horizontal cell padding
97
+ MARKET_SHARE_THRESHHOLD = 0.5 # predefined market share threshhold
81
98
 
82
99
  def initialize(feature, browsers = Cani.api.browsers)
83
100
  @feature = feature
@@ -103,7 +120,7 @@ module Cani
103
120
  at_exit(&method(:close))
104
121
  end
105
122
 
106
- def close(*args)
123
+ def close(*_args)
107
124
  Curses.close_screen
108
125
  end
109
126
 
@@ -149,7 +166,8 @@ module Cani
149
166
  end
150
167
 
151
168
  # status positioning and drawing
152
- # when compact? draw it on the second line instead of the first line at the end of the title
169
+ # when compact? draw it on the second line instead of the
170
+ # first line at the end of the title
153
171
  cy += 1
154
172
  status_yp = offset_y + (compact? ? 1 : 0)
155
173
  status_xp = offset_x + (compact? ? table_width - status_format.size
@@ -161,7 +179,8 @@ module Cani
161
179
  end
162
180
 
163
181
  # 'more or less' predict a height that is too small
164
- # since we don't know the entire height but draw it line-by-line at the moment
182
+ # since we don't know the entire height but draw
183
+ # it line-by-line at the moment
165
184
  compact_height = height <= 40
166
185
 
167
186
  # by default, notes are only shown if visible in the actual table
@@ -173,21 +192,28 @@ module Cani
173
192
 
174
193
  # meaty part, loop through browsers to create
175
194
  # the final feature table
176
- browsers.each.with_index do |browser, x|
195
+ relevant_era_count = browsers[0...viewable].map do |browser|
196
+ era_idx = browser.most_popular_era_idx
197
+ era_range = (era_idx - (ERAS / 2.0).floor + 1)..(era_idx + (ERAS / 2.0).ceil)
198
+
199
+ era_range.map do |cur_era|
200
+ era = browser.eras[cur_era].to_s
201
+ browser.usage[era].to_f >= MARKET_SHARE_THRESHHOLD || (!era.empty? && cur_era >= era_idx - 1)
202
+ end.select { |x| x }.size
203
+ end.max
204
+
205
+ browsers[0...viewable].each.with_index do |browser, x|
177
206
  # some set up to find the current era for each browser
178
207
  # and creating a range around that to show past / coming support
179
208
  era_idx = browser.most_popular_era_idx
180
- era_range = (era_idx - (ERAS / 2.0).floor + 1)..(era_idx + (ERAS / 2.0).ceil)
209
+ era_range = (era_idx - (relevant_era_count / 2.0).floor + 1)..(era_idx + (relevant_era_count / 2.0).ceil)
181
210
  bx = offset_x + x * col_width + x
182
211
  by = offset_y + cy
183
- do_draw = x < viewable
184
212
 
185
- if do_draw
186
- # draw browser names
187
- Curses.setpos by, bx
188
- Curses.attron color(:header) do
189
- Curses.addstr browser.name.tr('_', '.').center(col_width)
190
- end
213
+ # draw browser names
214
+ Curses.setpos by, bx
215
+ Curses.attron color(:header) do
216
+ Curses.addstr browser.name.tr('_', '.').center(col_width)
191
217
  end
192
218
 
193
219
  # accordingly increment current browser y for the table header (browser names)
@@ -205,45 +231,45 @@ module Cani
205
231
  bot_pad = compact_height ? 0 : 1
206
232
  ey = by + (y * (2 + top_pad + bot_pad)) + (bot_pad.zero? && past_curr ? 1 : 0)
207
233
  note_nums = feature.browser_note_nums.fetch(browser.name, {})
208
- .fetch(era, [])
234
+ .fetch(era, [])
209
235
 
210
236
  # do not draw era's that exceed screen height
211
237
  break if (ey + (is_current ? 1 : bot_pad) + 1) >= height
212
238
 
213
- if do_draw && is_current
214
- Curses.setpos ey - top_pad - 1, bx - 1
239
+ # draw current era outline before drawing all era cells on top
240
+ if is_current
241
+ Curses.setpos ey - top_pad - 1, [bx - 1, 0].max
215
242
  Curses.attron(color(:era_border)) { Curses.addstr ' ' * (col_width + 2) }
216
243
 
217
- Curses.setpos ey + (is_current ? 1 : bot_pad) + 1, bx - 1
244
+ Curses.setpos ey + (is_current ? 1 : bot_pad) + 1, [bx - 1, 0].max
218
245
  Curses.attron(color(:era_border)) { Curses.addstr ' ' * (col_width + 2) }
219
246
  end
220
247
 
221
248
  # only show visible / relevant browsers
222
- if browser.usage[era].to_i >= 0.5 || (!era.empty? && cur_era >= era_idx - 1)
223
- if do_draw
224
- ((ey - top_pad)..(ey + (is_current ? 1 : bot_pad))).each do |ry|
225
- txt = (bot_pad.zero? && !is_current) ? (ry >= ey + (is_current ? 1 : bot_pad) ? era.to_s : ' ')
226
- : (ry == ey ? era.to_s : ' ')
227
-
228
- Curses.setpos ry, bx
229
- Curses.attron(colr) { Curses.addstr txt.center(col_width) }
230
-
231
- if is_current
232
- Curses.setpos ry, bx - 1
233
- Curses.attron(color(:era_border)) { Curses.addstr ' ' }
234
-
235
- Curses.setpos ry, offset_x + table_width + 2
236
- Curses.attron(color(:era_border)) { Curses.addstr ' ' }
237
- end
249
+ # era's can either be empty or too new to determine
250
+ # their usefulness by usage (when newer than current era).
251
+ if browser.usage[era].to_f >= MARKET_SHARE_THRESHHOLD || (!era.empty? && cur_era >= era_idx - 1)
252
+ ((ey - top_pad)..(ey + (is_current ? 1 : bot_pad))).each do |ry|
253
+ txt = (bot_pad.zero? && !is_current) ? (ry >= ey + (is_current ? 1 : bot_pad) ? era.to_s : ' ')
254
+ : (ry == ey ? era.to_s : ' ')
255
+
256
+ Curses.setpos ry, bx
257
+ Curses.attron(colr) { Curses.addstr txt.center(col_width) }
258
+
259
+ # draw current ara border inbetween the cells
260
+ if is_current
261
+ Curses.setpos ry, bx - 1
262
+ Curses.attron(color(:era_border)) { Curses.addstr ' ' }
263
+
264
+ Curses.setpos ry, offset_x + table_width + 2
265
+ Curses.attron(color(:era_border)) { Curses.addstr ' ' }
238
266
  end
239
267
  end
240
268
 
241
269
  if note_nums.any?
242
270
  notes_visible.concat(note_nums).uniq!
243
- if do_draw
244
- Curses.setpos ey - top_pad, bx
245
- Curses.attron(note_color(supp_type)) { Curses.addstr ' ' + note_nums.join(' ') }
246
- end
271
+ Curses.setpos ey - top_pad, bx
272
+ Curses.attron(note_color(supp_type)) { Curses.addstr ' ' + note_nums.join(' ') }
247
273
  end
248
274
  end
249
275
  end
@@ -253,7 +279,7 @@ module Cani
253
279
  # plus the 4 lines around the current era
254
280
  # plus the 1 line of browser names
255
281
  # plus the 2 blank lines above and below the eras
256
- cy += (ERAS - 1) * (compact_height ? 3 : 4) + ERAS
282
+ cy += (relevant_era_count - 1) * (compact_height ? 3 : 4) + relevant_era_count + (relevant_era_count % 2 == 0 ? 0 : 1)
257
283
 
258
284
  if height > cy + 3
259
285
  # print legend header
@@ -272,6 +298,7 @@ module Cani
272
298
  # showing which label belongs to which color
273
299
  if height > cy + 1
274
300
  Feature::TYPES.values.each_slice viewable do |group|
301
+ # draw legend texts at proper position
275
302
  group.compact.each.with_index do |type, lx|
276
303
  Curses.setpos offset_y + cy, offset_x + lx * col_width + lx
277
304
  Curses.attron color(type[:name], :fg) do
@@ -292,8 +319,8 @@ module Cani
292
319
  filter_vis = Cani.config.notes == 'relevant' ? notes_visible.map(&:to_s) : feature.notes_by_num.keys
293
320
 
294
321
  num_chunked = feature.notes_by_num
295
- .select { |(k, _)| filter_vis.include? k }
296
- .each_with_object({}) { |(k, nt), h| h[k] = nt.chars.each_slice(outer_width - 5).map(&:join).map(&:strip) }
322
+ .select { |(k, _)| filter_vis.include? k }
323
+ .each_with_object({}) { |(k, nt), h| h[k] = nt.chars.each_slice(outer_width - 5).map(&:join).map(&:strip) }
297
324
  notes_total = (notes_chunked.map(&:size) + num_chunked.map(&:size)).reduce(0) { |total, add| total + add }
298
325
 
299
326
  if height > cy + 2 && (notes_chunked.any? || num_chunked.any?)
@@ -308,8 +335,10 @@ module Cani
308
335
  # and one empty line below it
309
336
  cy += 2
310
337
 
338
+ # print global notes, wrapped on terminal width
311
339
  notes_chunked.each do |chunks|
312
340
  break if cy + 1 + chunks.size > height
341
+
313
342
  chunks.each do |part|
314
343
  Curses.setpos offset_y + cy, offset_x
315
344
  Curses.addstr part
@@ -319,8 +348,10 @@ module Cani
319
348
  cy += 1
320
349
  end
321
350
 
351
+ # print numbered notes, wrapped on terminal width
322
352
  num_chunked.each do |num, chunks|
323
353
  break if cy + 1 + chunks.size > height
354
+
324
355
  Curses.setpos offset_y + cy, offset_x
325
356
  Curses.attron color(:header) do
326
357
  Curses.addstr num.center(3)
@@ -367,9 +398,7 @@ module Cani
367
398
  @height, @width = IO.console.winsize
368
399
  @viewable = browsers.size
369
400
 
370
- while tablew > @width
371
- @viewable -= 1
372
- end
401
+ @viewable -= 1 while tablew >= @width
373
402
 
374
403
  @col_width = [colw, Feature::TYPES.map { |(_, h)| h[:short].size }.max + 3].max
375
404
  @table_width = tablew - 2 # vertical padding at start and end of current era line
@@ -10,14 +10,14 @@ module Cani
10
10
  NO_MODIFY_FILE = File.join(DIRECTORY, '.no-modify-shellrc').freeze
11
11
  DEFAULTS = {
12
12
  # data settings
13
- 'expire' => 86_400,
14
- 'source' => 'https://raw.githubusercontent.com/Fyrd/caniuse/master/data.json',
13
+ 'expire' => 86_400,
14
+ 'source' => 'https://raw.githubusercontent.com/Fyrd/caniuse/master/data.json',
15
15
 
16
16
  # usage settings
17
17
  'versions' => 1,
18
18
  'browsers' => %w[ie edge chrome firefox safari ios_saf opera android bb],
19
19
  'navigate' => 'always',
20
- 'notes' => 'relevant'
20
+ 'notes' => 'relevant'
21
21
  }.freeze
22
22
 
23
23
  def initialize(**opts)
@@ -44,7 +44,7 @@ module Cani
44
44
 
45
45
  def self.to_feature_row(ft)
46
46
  pc = format('%.2f%%', ft.percent).rjust 6
47
- cl = {'un' => :yellow, 'ot' => :magenta}.fetch ft.status, :green
47
+ cl = { 'un' => :yellow, 'ot' => :magenta }.fetch ft.status, :green
48
48
 
49
49
  total_len = ft.current_support.map(&:size).reduce(&:+) + pc.size + 6 + (ft.current_support.size + 2) * 3
50
50
  rem_len = [longest_title_size, 50, [dimensions.first - total_len, 24].max].min
@@ -52,19 +52,19 @@ module Cani
52
52
  tt = format("%-#{rem_len}s", ft.title.size > rem_len ? ft.title[0...rem_len].strip + '..'
53
53
  : ft.title)
54
54
 
55
- [{content: "[#{ft.status}]", color: cl}, pc,
56
- {content: tt, color: :default}, *ft.current_support]
55
+ [{ content: "[#{ft.status}]", color: cl }, pc,
56
+ { content: tt, color: :default }, *ft.current_support]
57
57
  end
58
58
 
59
59
  def self.browser_rows
60
60
  @browser_rows ||= Cani.api.browsers.map do |bwsr|
61
- [{content: bwsr.title, color: :default},
61
+ [{ content: bwsr.title, color: :default },
62
62
  'usage: ' + format('%.4f%%', bwsr.usage.values.reduce(0) { |total, add| total + add })]
63
63
  end
64
64
  end
65
65
 
66
66
  def self.browser_usage_rows(brwsr)
67
- brwsr.usage.map { |(v, u)| [{content: v, color: :default}, 'usage: ' + format('%.4f%%', u)] }.reverse
67
+ brwsr.usage.map { |(v, u)| [{ content: v, color: :default }, 'usage: ' + format('%.4f%%', u)] }.reverse
68
68
  end
69
69
 
70
70
  def self.browser_feature_rows(brwsr, version)
@@ -73,9 +73,9 @@ module Cani
73
73
  Api::Feature::TYPES.flat_map do |(status, type)|
74
74
  if (features = features_by_support.fetch(type[:name], nil))
75
75
  features.map do |feature|
76
- color = {'un' => :yellow, 'ot' => :magenta}.fetch feature[:status], :green
77
- [{content: "[#{feature[:status]}]", color: color},
78
- "[#{type[:symbol]}]", {content: feature[:title], color: :default}]
76
+ color = { 'un' => :yellow, 'ot' => :magenta }.fetch feature[:status], :green
77
+ [{ content: "[#{feature[:status]}]", color: color },
78
+ "[#{type[:symbol]}]", { content: feature[:title], color: :default }]
79
79
  end
80
80
  end
81
81
  end.compact
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cani
4
- VERSION = '0.5.8'
4
+ VERSION = '0.5.9'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cani
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.8
4
+ version: 0.5.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sidney Liebrand
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-28 00:00:00.000000000 Z
11
+ date: 2019-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: tty-screen
42
+ name: json
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: json
56
+ name: tty-screen
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '1.16'
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '1.16'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: pry
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -100,28 +100,28 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '10.0'
103
+ version: '12'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '10.0'
110
+ version: '12'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rspec
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
- version: '3.0'
117
+ version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - "~>"
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
- version: '3.0'
124
+ version: '0'
125
125
  description: An interactive TUI (using FZF / Curses) for exploring caniuse.com in
126
126
  your terminal.
127
127
  email:
@@ -133,7 +133,9 @@ extra_rdoc_files: []
133
133
  files:
134
134
  - ".gitignore"
135
135
  - ".rspec"
136
+ - ".rubocop.yml"
136
137
  - ".travis.yml"
138
+ - CHANGELOG.md
137
139
  - CODE_OF_CONDUCT.md
138
140
  - Gemfile
139
141
  - LICENSE.txt
@@ -175,7 +177,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
177
  - !ruby/object:Gem::Version
176
178
  version: '0'
177
179
  requirements: []
178
- rubygems_version: 3.0.3
180
+ rubyforge_project:
181
+ rubygems_version: 2.6.8
179
182
  signing_key:
180
183
  specification_version: 4
181
184
  summary: A simple caniuse CLI.