cani 0.5.8 → 0.5.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +1 -1
- data/README.md +10 -18
- data/cani.gemspec +11 -9
- data/lib/cani/api.rb +2 -2
- data/lib/cani/api/browser.rb +16 -16
- data/lib/cani/api/feature.rb +8 -8
- data/lib/cani/api/feature/viewer.rb +108 -79
- data/lib/cani/config.rb +3 -3
- data/lib/cani/fzf.rb +8 -8
- data/lib/cani/version.rb +1 -1
- metadata +18 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bbdbb28b9c3709f04c106775b5d019f7d4e29177
|
4
|
+
data.tar.gz: cb812356aac2f7ad341f8d80fe16db97539813b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 01ffd79c7dcbb0aae80cac9585d687eaf00c2226f617d4a70cb409384d9938373363e5b38d93c8988f6e92a525ce88774cb0aa922a3435cf4381b1dbb203d8f0
|
7
|
+
data.tar.gz: fc4287ccb47965a06f6218af9de4d67d1ff63d677687d5042fd3df9bb9e13e630463727269bb08a89f2c58d31a05ee66739578b9a97a61a329983306e8fdd781
|
data/.rubocop.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
TargetRubyVersion: "2.1"
|
data/CHANGELOG.md
ADDED
@@ -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
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
|
231
|
-
[un] 75.85% Animated PNG (APNG)
|
232
|
-
[ls] 94.32% Video element
|
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**
|
data/cani.gemspec
CHANGED
@@ -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)
|
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(
|
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
|
24
|
-
spec.require_paths
|
25
|
-
|
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'
|
34
|
+
spec.add_development_dependency 'bundler'
|
33
35
|
spec.add_development_dependency 'pry'
|
34
|
-
spec.add_development_dependency 'rake', '~>
|
35
|
-
spec.add_development_dependency 'rspec'
|
36
|
+
spec.add_development_dependency 'rake', '~> 12'
|
37
|
+
spec.add_development_dependency 'rspec'
|
36
38
|
end
|
data/lib/cani/api.rb
CHANGED
@@ -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
|
-
|
70
|
-
|
69
|
+
ft.name.downcase.match(name) ||
|
70
|
+
ft.description.downcase.match(name)
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
data/lib/cani/api/browser.rb
CHANGED
@@ -5,24 +5,24 @@ module Cani
|
|
5
5
|
|
6
6
|
ABBR_MAP = { 'ios' => 'saf.ios' }.freeze
|
7
7
|
LABEL_MAP = {
|
8
|
-
'ie'
|
9
|
-
'edge'
|
10
|
-
'ff'
|
11
|
-
'chr'
|
12
|
-
'saf'
|
13
|
-
'op'
|
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'
|
16
|
-
'and'
|
17
|
-
'bb'
|
18
|
-
'o.mob'
|
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'
|
21
|
-
'ie.mob'
|
22
|
-
'uc'
|
23
|
-
'ss'
|
24
|
-
'qq'
|
25
|
-
'baidu'
|
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 = {})
|
data/lib/cani/api/feature.rb
CHANGED
@@ -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'
|
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,
|
5
|
+
attr_reader :width, :height, :feature, :browsers, :viewable,
|
6
|
+
:col_width, :table_width
|
6
7
|
|
7
8
|
COLOR_PAIRS = {
|
8
9
|
# foreground colors
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
29
|
+
99 => [239, -1], # gray on default (legend unknown)
|
16
30
|
|
17
31
|
# note background + foreground colors
|
18
|
-
71
|
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
|
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
|
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
|
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:
|
56
|
+
header: { fg: Curses.color_pair(254), bg: Curses.color_pair(254) },
|
43
57
|
|
44
58
|
# current era border
|
45
|
-
era_border:
|
59
|
+
era_border: { fg: Curses.color_pair(239),
|
60
|
+
bg: Curses.color_pair(239) },
|
46
61
|
|
47
62
|
# support types
|
48
|
-
default:
|
49
|
-
partial:
|
50
|
-
prefix:
|
51
|
-
polyfill:
|
52
|
-
flag:
|
53
|
-
|
54
|
-
|
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:
|
58
|
-
ot:
|
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:
|
63
|
-
partial:
|
64
|
-
prefix:
|
65
|
-
polyfill:
|
66
|
-
flag:
|
67
|
-
|
68
|
-
|
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),
|
73
|
-
40..70
|
74
|
-
0..40
|
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
|
78
|
-
COMPACT
|
79
|
-
PADDING
|
80
|
-
|
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(*
|
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
|
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
|
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.
|
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 - (
|
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
|
-
|
186
|
-
|
187
|
-
|
188
|
-
Curses.
|
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
|
-
|
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
|
-
|
214
|
-
|
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
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
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
|
-
|
244
|
-
|
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 += (
|
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
|
-
|
296
|
-
|
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
|
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
|
data/lib/cani/config.rb
CHANGED
@@ -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'
|
14
|
-
'source'
|
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'
|
20
|
+
'notes' => 'relevant'
|
21
21
|
}.freeze
|
22
22
|
|
23
23
|
def initialize(**opts)
|
data/lib/cani/fzf.rb
CHANGED
@@ -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
|
data/lib/cani/version.rb
CHANGED
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.
|
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-
|
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:
|
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:
|
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: '
|
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: '
|
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: '
|
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: '
|
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: '
|
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: '
|
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
|
-
|
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.
|