scryglass 1.1.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|