scryglass 1.1.0 → 2.0.0
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 +4 -4
- data/.irbrc +9 -0
- data/CHANGELOG.md +46 -0
- data/Gemfile.lock +18 -1
- data/README.md +28 -15
- data/example_config.rb +12 -2
- data/lib/refinements/ansiless_string_refinement.rb +145 -0
- data/lib/refinements/array_fit_to_refinement.rb +30 -9
- data/lib/refinements/clip_string_refinement.rb +22 -7
- data/lib/scryglass.rb +78 -49
- data/lib/scryglass/binding_tracker.rb +10 -0
- data/lib/scryglass/config.rb +11 -2
- data/lib/scryglass/lens_helper.rb +52 -7
- data/lib/scryglass/lens_panel.rb +45 -21
- data/lib/scryglass/ro.rb +84 -15
- data/lib/scryglass/ro_builder.rb +95 -16
- data/lib/scryglass/session.rb +333 -126
- data/lib/scryglass/session_manager.rb +154 -0
- data/lib/scryglass/tree_panel.rb +14 -10
- data/lib/scryglass/version.rb +1 -1
- data/lib/scryglass/view_panel.rb +43 -1
- data/scryglass.gemspec +4 -1
- metadata +61 -3
- data/lib/refinements/ansi_slice_string_refinement.rb +0 -65
@@ -6,21 +6,36 @@ module ClipStringRefinement
|
|
6
6
|
def clip_at(clip_length, ignore_ansi_codes: false)
|
7
7
|
length_method = ignore_ansi_codes ? :ansiless_length : :length
|
8
8
|
original_length = send(length_method)
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
|
10
|
+
clipped_string = if ignore_ansi_codes
|
11
|
+
self.ansi_slice(0...clip_length)
|
12
|
+
else
|
13
|
+
self[0...clip_length]
|
14
|
+
end
|
12
15
|
if clipped_string.send(length_method) < original_length
|
13
|
-
clipped_string =
|
16
|
+
clipped_string =
|
17
|
+
clipped_string.mark_as_abbreviated(ignore_ansi_codes: ignore_ansi_codes)
|
14
18
|
end
|
15
19
|
|
16
20
|
clipped_string
|
17
21
|
end
|
18
22
|
|
23
|
+
def ansiless_clip_at(clip_length)
|
24
|
+
self.clip_at(clip_length, ignore_ansi_codes: true)
|
25
|
+
end
|
26
|
+
|
19
27
|
# Warning: Still not going to work nicely if a string ends in an ansi code!
|
20
|
-
def mark_as_abbreviated
|
28
|
+
def mark_as_abbreviated(ignore_ansi_codes: false)
|
21
29
|
self_dup = dup
|
22
|
-
|
23
|
-
|
30
|
+
|
31
|
+
if ignore_ansi_codes
|
32
|
+
self_dup.ansiless_set!(-1, '…') if self_dup.ansiless_pick(-1)
|
33
|
+
self_dup.ansiless_set!(-2, '…') if self_dup.ansiless_pick(-2)
|
34
|
+
else
|
35
|
+
self_dup[-1] = '…' if self_dup[-1]
|
36
|
+
self_dup[-2] = '…' if self_dup[-2]
|
37
|
+
end
|
38
|
+
|
24
39
|
self_dup
|
25
40
|
end
|
26
41
|
end
|
data/lib/scryglass.rb
CHANGED
@@ -1,18 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'stringio'
|
3
2
|
|
4
|
-
## Bookkeeping
|
3
|
+
## Bookkeeping
|
5
4
|
require "scryglass/version"
|
5
|
+
|
6
|
+
## External tools:
|
6
7
|
require 'io/console'
|
8
|
+
require 'stringio'
|
7
9
|
require 'pp'
|
10
|
+
require 'amazing_print' # For use as a lens
|
11
|
+
require 'method_source' # For use in lens_helper
|
12
|
+
require 'binding_of_caller'
|
8
13
|
require 'timeout'
|
9
14
|
|
10
15
|
## Refinements and sub-tools:
|
11
16
|
require 'refinements/ansiless_string_refinement'
|
12
|
-
# require 'refinements/ansi_slice_string_refinement' # Employed soon
|
13
17
|
require 'refinements/clip_string_refinement'
|
14
18
|
require 'refinements/constant_defined_string_refinement'
|
15
19
|
require 'refinements/array_fit_to_refinement'
|
20
|
+
require 'scryglass/lens_helper'
|
16
21
|
require 'hexes'
|
17
22
|
require 'prog'
|
18
23
|
|
@@ -20,7 +25,9 @@ require 'prog'
|
|
20
25
|
require 'scryglass/config'
|
21
26
|
require 'scryglass/ro'
|
22
27
|
require 'scryglass/ro_builder'
|
28
|
+
require 'scryglass/binding_tracker'
|
23
29
|
require 'scryglass/session'
|
30
|
+
require 'scryglass/session_manager'
|
24
31
|
require 'scryglass/view_wrapper'
|
25
32
|
require 'scryglass/view_panel'
|
26
33
|
require 'scryglass/tree_panel'
|
@@ -28,57 +35,67 @@ require 'scryglass/lens_panel'
|
|
28
35
|
|
29
36
|
## Testing and Demoing:
|
30
37
|
require 'example_material.rb'
|
31
|
-
|
38
|
+
#test
|
32
39
|
module Scryglass
|
33
|
-
HELP_SCREEN = <<~
|
34
|
-
|
40
|
+
HELP_SCREEN = <<~"HELPSCREENPAGE"
|
41
|
+
\e[36mq\e[0m : Quit Scry \e[36m?\e[0m : Cycle help panels (1/2)
|
35
42
|
|
36
43
|
BASIC NAVIGATION: · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
37
44
|
· ·
|
38
|
-
·
|
39
|
-
·
|
40
|
-
·
|
45
|
+
· \e[36mUP / DOWN\e[0m : Navigate (To move further, type a number first or use \e[36mSHIFT\e[0m) ·
|
46
|
+
· \e[36mRIGHT\e[0m : Expand current or selected row(s) ·
|
47
|
+
· \e[36mLEFT\e[0m : Collapse current or selected row(s) ·
|
48
|
+
· ·
|
49
|
+
· (\e[36mh/j/k/l\e[0m on the home row can also serve as arrow keys) ·
|
41
50
|
· ·
|
42
|
-
·
|
51
|
+
· \e[36mENTER\e[0m : Close Scry, returning current or selected object(s) (Key or Value) ·
|
43
52
|
· ·
|
44
53
|
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
45
54
|
|
46
55
|
INSPECTING WITH LENS VIEW: · · · · · · · · · · · · · ·
|
47
56
|
· ·
|
48
|
-
·
|
49
|
-
·
|
50
|
-
·
|
57
|
+
· \e[36mSPACEBAR\e[0m : Toggle Lens View ·
|
58
|
+
· \e[36m > \e[0m : Cycle through lens types ·
|
59
|
+
· \e[36m < \e[0m : Toggle subject (Key/Value of row) ·
|
51
60
|
· ·
|
52
61
|
· · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
53
62
|
|
54
63
|
MORE NAVIGATION: · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
55
64
|
· ·
|
56
|
-
·
|
57
|
-
· [a][s][d] (
|
65
|
+
· \e[36m [w] \e[0m : Move view window \e[36m0\e[0m : Reset view location ·
|
66
|
+
· \e[36m[a][s][d]\e[0m (\e[36mALT\e[0m increases speed) (Press again: reset cursor) ·
|
58
67
|
· ·
|
59
68
|
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
60
69
|
HELPSCREENPAGE
|
61
70
|
|
62
|
-
HELP_SCREEN_ADVANCED = <<~
|
63
|
-
|
71
|
+
HELP_SCREEN_ADVANCED = <<~"HELPSCREENADVANCEDPAGE"
|
72
|
+
\e[36mq\e[0m : Quit Scry \e[36m?\e[0m : Cycle help panels (2/2)
|
64
73
|
|
65
74
|
ADVANCED: · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
66
75
|
· DIGGING DEEPER: ·
|
67
76
|
· For current or selected row(s)... ·
|
68
|
-
·
|
69
|
-
·
|
70
|
-
· ( : Attempt to smart-build sub-rows, if Enumerable. Usually '@' is preferable. ·
|
77
|
+
· \e[36m@\e[0m : Build instance variable sub-rows ·
|
78
|
+
· \e[36m.\e[0m : Build ActiveRecord association sub-rows ·
|
79
|
+
· \e[36m(\e[0m : Attempt to smart-build sub-rows, if Enumerable. Usually '@' is preferable. ·
|
80
|
+
· \e[36mo\e[0m : Quick Open: builds the most likely helpful sub-rows ( '.' || '@' || '(' ) ·
|
71
81
|
· ·
|
72
82
|
· SELECTING ROWS: ·
|
73
|
-
·
|
74
|
-
·
|
75
|
-
·
|
83
|
+
· \e[36m*\e[0m : Select/Deselect ALL rows ·
|
84
|
+
· \e[36m|\e[0m : Select/Deselect every sibling row under the same parent row ·
|
85
|
+
· \e[36m-\e[0m : Select/Deselect current row ·
|
86
|
+
· ·
|
87
|
+
· MANAGING MULTIPLE SESSION TABS: ·
|
88
|
+
· \e[36mTab\e[0m : Change session tab (to the right) (\e[36mShift+Tab\e[0m moves left) ·
|
89
|
+
· \e[36mQ\e[0m : Close current session tab ·
|
76
90
|
· ·
|
77
91
|
· TEXT SEARCH: ·
|
78
|
-
·
|
79
|
-
·
|
92
|
+
· \e[36m/\e[0m : Begin a text search (in tree view) ·
|
93
|
+
· \e[36mn\e[0m : Move to next search result ·
|
94
|
+
· ·
|
95
|
+
· ·
|
96
|
+
· \e[36m=\e[0m : Open prompt to type a console handle for current or selected row(s) ·
|
80
97
|
· ·
|
81
|
-
·
|
98
|
+
· \e[36mEsc\e[0m : Resets selection, last search, and number-to-move. (or returns to Tree View) ·
|
82
99
|
· ·
|
83
100
|
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
84
101
|
HELPSCREENADVANCEDPAGE
|
@@ -97,7 +114,8 @@ module Scryglass
|
|
97
114
|
|
98
115
|
def self.load_silently
|
99
116
|
begin
|
100
|
-
|
117
|
+
add_kernel_method
|
118
|
+
create_scryglass_session_manager
|
101
119
|
{ success: true, error: nil }
|
102
120
|
rescue => e
|
103
121
|
{ success: false, error: e }
|
@@ -130,8 +148,7 @@ module Scryglass
|
|
130
148
|
| > my_object.scry
|
131
149
|
|
|
132
150
|
| To resume the previous session: (in same console session)
|
133
|
-
| > scry
|
134
|
-
| > scry_resume (if you're in a breakpoint pry)
|
151
|
+
| > scry
|
135
152
|
\e[0m
|
136
153
|
CONSOLE_HELP
|
137
154
|
|
@@ -140,39 +157,51 @@ module Scryglass
|
|
140
157
|
|
141
158
|
private
|
142
159
|
|
143
|
-
def self.
|
160
|
+
def self.create_scryglass_session_manager
|
161
|
+
$scry_session_manager = Scryglass::SessionManager.new
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.add_kernel_method
|
144
165
|
Kernel.module_eval do
|
145
|
-
def scry(arg = nil,
|
146
|
-
#
|
166
|
+
def scry(arg = nil, _actions = nil)
|
167
|
+
# `actions` can't be a keyword arg due to this ruby issue:
|
168
|
+
# https://bugs.ruby-lang.org/issues/8316
|
147
169
|
|
148
|
-
|
170
|
+
Scryglass.config.validate!
|
171
|
+
|
172
|
+
current_console_binding = binding.of_caller(1)
|
173
|
+
|
174
|
+
receiver_is_just_the_console = self == current_console_binding.receiver
|
175
|
+
receiver = self unless receiver_is_just_the_console
|
149
176
|
# As in: `receiver.scry`,
|
150
177
|
# and no receiver means scry was called on 'main', (unless self is
|
151
178
|
# different in the because you've pry'd into something!)
|
152
179
|
|
153
180
|
seed_object = arg || receiver
|
154
181
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
end
|
162
|
-
|
163
|
-
# For the user, this is mainly just for pry sessions where `self` isn't `main`
|
164
|
-
def scry_resume(actions = nil)
|
165
|
-
Scryglass.config.validate!
|
182
|
+
if seed_object
|
183
|
+
# If it's been given an arg or receiver, create new session!
|
184
|
+
# The global variable is purposeful, and not accessible outside of
|
185
|
+
# the one particular console instance.
|
186
|
+
$scry_session_manager << Scryglass::Session.new(seed_object)
|
187
|
+
end
|
166
188
|
|
167
|
-
|
168
|
-
if no_previous_session
|
189
|
+
unless $scry_session_manager.current_session
|
169
190
|
raise ArgumentError,
|
170
|
-
'`scry` requires either an argument, a receiver, or a past' \
|
191
|
+
'`scry` requires either an argument, a receiver, or a past ' \
|
171
192
|
'session to reopen. try `Scryglass.help`'
|
172
193
|
end
|
173
194
|
|
174
|
-
|
175
|
-
|
195
|
+
$scry_session_manager.track_binding!(current_console_binding)
|
196
|
+
|
197
|
+
begin
|
198
|
+
Hexes.stdout_rescue do
|
199
|
+
$scry_session_manager.run_scry_ui
|
200
|
+
end
|
201
|
+
rescue => e # Here we ensure good visibility in case of errors
|
202
|
+
screen_height, _screen_width = $stdout.winsize
|
203
|
+
$stdout.write "\e[#{screen_height};1H\n" # (Moves console cursor to bottom left corner)
|
204
|
+
raise e
|
176
205
|
end
|
177
206
|
end
|
178
207
|
end
|
data/lib/scryglass/config.rb
CHANGED
@@ -26,16 +26,25 @@ module Scryglass
|
|
26
26
|
self.lenses = [ # Custom lenses can easily be added as name+lambda hashes! Or comment some out to turn them off.
|
27
27
|
{ name: 'Pretty Print (`pp`)',
|
28
28
|
lambda: ->(o) { Hexes.capture_io(char_limit: 20_000) { pp o } } },
|
29
|
+
{ name: 'Amazing Print (`ap`)',
|
30
|
+
lambda: ->(o) { Hexes.capture_io(char_limit: 20_000) { ap o } } }, # This has colors!
|
29
31
|
{ name: 'Inspect (`.inspect`)',
|
30
32
|
lambda: ->(o) { Hexes.capture_io(char_limit: 20_000) { puts o.inspect } } },
|
31
33
|
{ name: 'Yaml Print (`y`)',
|
32
34
|
lambda: ->(o) { Hexes.capture_io(char_limit: 20_000) { require 'yaml' ; y o } } }, # OR: `puts o.to_yaml`
|
33
35
|
{ name: 'Puts (`puts`)',
|
34
36
|
lambda: ->(o) { Hexes.capture_io(char_limit: 20_000) { puts o } } },
|
35
|
-
|
36
|
-
|
37
|
+
{ name: 'Method Showcase',
|
38
|
+
lambda: ->(o) { Scryglass::LensHelper.method_showcase_for(o) } },
|
37
39
|
]
|
38
40
|
|
41
|
+
## AmazingPrint defaults, if the user has not set their own:
|
42
|
+
::AmazingPrint.defaults ||= {
|
43
|
+
index: false, # (Don't display array indices).
|
44
|
+
raw: true, # (Recursively format instance variables).
|
45
|
+
}
|
46
|
+
# See https://github.com/amazing-print/amazing_print
|
47
|
+
|
39
48
|
## Building ActiveRecord association sub-rows:
|
40
49
|
self.include_empty_associations = true
|
41
50
|
self.include_through_associations = false
|
@@ -2,19 +2,64 @@
|
|
2
2
|
|
3
3
|
module Scryglass
|
4
4
|
module LensHelper
|
5
|
-
def method_showcase_for(object)
|
5
|
+
def self.method_showcase_for(object)
|
6
|
+
# method_list = object.methods - Object.methods
|
6
7
|
method_list = object.methods - Object.methods
|
8
|
+
return '' if method_list.empty?
|
9
|
+
|
7
10
|
label_space = [method_list.map(&:length).max, 45].min
|
8
11
|
method_list.sort.map do |method_name|
|
9
|
-
label = method_name.to_s
|
12
|
+
label = method_name.to_s
|
13
|
+
label_padding = ' ' * (label_space - label.length)
|
14
|
+
label = "\e[1;34m#{label}\e[0m" # make blue and bold
|
15
|
+
|
10
16
|
begin
|
11
17
|
method = object.method(method_name)
|
12
|
-
|
13
|
-
|
14
|
-
|
18
|
+
|
19
|
+
method_source_location = method.source_location.to_a.join(':')
|
20
|
+
source_location_line =
|
21
|
+
unless method_source_location.empty?
|
22
|
+
" \e[36m\e[4m#{method_source_location}\e[0m\n" # Cyan, underlined
|
23
|
+
end
|
24
|
+
|
25
|
+
highlighted_space = "\e[7m\s\e[0m"
|
26
|
+
method_lines = Hexes.capture_io { puts method.source }.split("\n")
|
27
|
+
method_lines.prepend('')
|
28
|
+
method_source = method_lines.map do |line|
|
29
|
+
' ' + highlighted_space + line
|
30
|
+
end.join("\n")
|
31
|
+
|
32
|
+
translated_parameters = method.parameters.map do |pair|
|
33
|
+
arg_type = pair[0]
|
34
|
+
arg_name = pair[1]
|
35
|
+
|
36
|
+
case arg_type
|
37
|
+
when :req
|
38
|
+
"#{arg_name}"
|
39
|
+
when :opt
|
40
|
+
"#{arg_name} = ?"
|
41
|
+
when :keyreq
|
42
|
+
"#{arg_name}:"
|
43
|
+
when :key
|
44
|
+
"#{arg_name}: ?"
|
45
|
+
when :rest
|
46
|
+
"*#{arg_name}"
|
47
|
+
when :keyrest
|
48
|
+
"**#{arg_name}"
|
49
|
+
when :block
|
50
|
+
"&#{arg_name}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
arg_preview = "(#{translated_parameters.join(', ')})"
|
55
|
+
|
56
|
+
"#{label} #{arg_preview}\n" +
|
57
|
+
source_location_line +
|
58
|
+
"#{method_source}\n"
|
15
59
|
rescue => e
|
16
|
-
label
|
17
|
-
e.message
|
60
|
+
"#{label}#{label_padding} : " \
|
61
|
+
"Error: \e[31m#{e.message}\n\e[0m" +
|
62
|
+
(source_location_line || '')
|
18
63
|
end
|
19
64
|
end.join("\n")
|
20
65
|
end
|
data/lib/scryglass/lens_panel.rb
CHANGED
@@ -51,29 +51,30 @@ module Scryglass
|
|
51
51
|
|
52
52
|
## Here we cut down the (rectangular) display array in both dimensions (into a smaller rectangle), as needed, to fit the view.
|
53
53
|
sliced_lines = split_lines.map do |string|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
# opacify here, I need to account for nils when the view is fully
|
58
|
-
# beyond the shorter lines.
|
54
|
+
string.ansi_slice(current_view_coords[:x], screen_width) || '' # If I
|
55
|
+
# don't want to opacify here, I need to account for nils when the view
|
56
|
+
# is fully beyond the shorter lines.
|
59
57
|
end
|
60
58
|
sliced_list = sliced_lines[current_view_coords[:y], non_header_view_size]
|
61
59
|
|
62
|
-
sliced_list
|
60
|
+
sliced_list
|
63
61
|
end
|
64
62
|
|
65
63
|
def recalculate_y_boundaries
|
66
|
-
|
64
|
+
number_of_lines = uncut_body_string.count("\n") + 1
|
65
|
+
preview_row = 1
|
66
|
+
self.y_boundaries = 0...(number_of_lines + preview_row)
|
67
67
|
end
|
68
68
|
|
69
69
|
def recalculate_x_boundaries
|
70
70
|
_screen_height, screen_width = $stdout.winsize
|
71
71
|
|
72
72
|
split_lines = uncut_body_string.split("\n")
|
73
|
-
length_of_longest_line = split_lines.map(&:
|
73
|
+
length_of_longest_line = split_lines.map(&:ansiless_length).max || 0
|
74
74
|
max_line_length = [length_of_longest_line, screen_width].max
|
75
|
+
preview_column = 1
|
75
76
|
|
76
|
-
self.x_boundaries = 0...max_line_length
|
77
|
+
self.x_boundaries = 0...(max_line_length + preview_column)
|
77
78
|
end
|
78
79
|
|
79
80
|
def current_ro_subheader
|
@@ -85,10 +86,29 @@ module Scryglass
|
|
85
86
|
row_below_string =
|
86
87
|
current_ro.next_visible_ro_down.to_s if current_ro.next_visible_ro_down
|
87
88
|
|
88
|
-
|
89
|
-
|
89
|
+
tree_preview_related_keys = ::Scryglass::Session::KEY_MAP.slice(
|
90
|
+
:move_cursor_up,
|
91
|
+
:move_cursor_down,
|
92
|
+
:homerow_move_cursor_up,
|
93
|
+
:homerow_move_cursor_down,
|
94
|
+
:homerow_move_cursor_up_fast,
|
95
|
+
:homerow_move_cursor_down_fast,
|
96
|
+
:open_bucket,
|
97
|
+
:close_bucket,
|
98
|
+
:homerow_open_bucket,
|
99
|
+
:homerow_close_bucket,
|
100
|
+
:build_instance_variables,
|
101
|
+
:build_ar_relations,
|
102
|
+
:build_enum_children,
|
103
|
+
:smart_open,
|
104
|
+
:select_siblings,
|
105
|
+
:select_all,
|
106
|
+
:select_current,
|
107
|
+
:continue_search,
|
108
|
+
).values
|
109
|
+
|
90
110
|
ro_view_label =
|
91
|
-
if
|
111
|
+
if tree_preview_related_keys.include?(last_keypress)
|
92
112
|
"\e[7mVIEWING:\e[00m" # Color reversed
|
93
113
|
else
|
94
114
|
'VIEWING:'
|
@@ -109,6 +129,7 @@ module Scryglass
|
|
109
129
|
current_subject_type = scry_session.current_subject_type
|
110
130
|
current_subject = scry_session.current_ro.current_subject
|
111
131
|
last_keypress = scry_session.last_keypress
|
132
|
+
key_map = ::Scryglass::Session::KEY_MAP
|
112
133
|
|
113
134
|
lens_count = LensPanel.lenses.count
|
114
135
|
lens_id = current_lens % lens_count
|
@@ -117,23 +138,26 @@ module Scryglass
|
|
117
138
|
longest_lens_name_length = LensPanel.lenses.map do |lens|
|
118
139
|
lens[:name].length
|
119
140
|
end.max
|
120
|
-
lens_type_header_length =
|
141
|
+
lens_type_header_length = 13 + (lens_count.to_s.length * 2)
|
121
142
|
+ longest_lens_name_length
|
122
|
-
subject_type_header = "SUBJECT: #{current_subject_type}".ljust(
|
143
|
+
subject_type_header = "[<] SUBJECT: #{current_subject_type}".ljust(18, ' ')
|
123
144
|
subject_class_header = " CLASS: #{current_subject.class}"
|
124
|
-
lens_type_header = " LENS #{lens_id + 1}/#{lens_count}: #{lens[:name]}"
|
145
|
+
lens_type_header = " [>] LENS #{lens_id + 1}/#{lens_count}: #{lens[:name]}"
|
125
146
|
.ljust(lens_type_header_length, ' ')
|
126
147
|
|
148
|
+
user_just_switched_lens = last_keypress == key_map[:switch_lens]
|
149
|
+
user_just_switched_subject_type = last_keypress == key_map[:switch_subject_type]
|
150
|
+
|
151
|
+
if user_just_switched_lens
|
152
|
+
lens_type_header = "\e[7m#{lens_type_header}\e[00m" # Color reversed
|
153
|
+
elsif user_just_switched_subject_type
|
154
|
+
subject_type_header = "\e[7m#{subject_type_header}\e[00m" # Color reversed
|
155
|
+
end
|
156
|
+
|
127
157
|
fit_lens_header = [
|
128
158
|
subject_type_header, subject_class_header, lens_type_header
|
129
159
|
].fit_to(screen_width)
|
130
160
|
|
131
|
-
if last_keypress == 'l'
|
132
|
-
fit_lens_header[4] = "\e[7m#{fit_lens_header[4]}" # Format to be ended by Hexes.opacify_screen_string() (using \e[00m)
|
133
|
-
elsif last_keypress == 'L'
|
134
|
-
fit_lens_header[0] = "\e[7m#{fit_lens_header[0]}\e[00m"
|
135
|
-
end
|
136
|
-
|
137
161
|
fit_lens_header.join('')
|
138
162
|
end
|
139
163
|
end
|