scryglass 1.1.0 → 2.1.1
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 +86 -0
- data/Gemfile.lock +18 -1
- data/README.md +31 -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 +82 -49
- data/lib/scryglass/binding_tracker.rb +10 -0
- data/lib/scryglass/config.rb +11 -2
- data/lib/scryglass/lens_helper.rb +74 -12
- data/lib/scryglass/lens_panel.rb +45 -21
- data/lib/scryglass/ro.rb +140 -24
- data/lib/scryglass/ro_builder.rb +153 -16
- data/lib/scryglass/session.rb +408 -130
- data/lib/scryglass/session_manager.rb +175 -0
- data/lib/scryglass/tree_panel.rb +16 -10
- data/lib/scryglass/version.rb +1 -1
- data/lib/scryglass/view_panel.rb +43 -1
- data/scryglass.gemspec +5 -2
- metadata +62 -4
- 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,71 @@ 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 ( '.' || '@' || '(' ) ·
|
|
81
|
+
· · ·
|
|
82
|
+
· \e[36mc\e[0m : Enter method text to call on object(s), results becomes navigable sub-rows ·
|
|
71
83
|
· ·
|
|
72
84
|
· SELECTING ROWS: ·
|
|
73
|
-
·
|
|
74
|
-
·
|
|
75
|
-
·
|
|
85
|
+
· \e[36m*\e[0m : Select/Deselect ALL rows ·
|
|
86
|
+
· \e[36m|\e[0m : Select/Deselect every sibling row under the same parent row ·
|
|
87
|
+
· \e[36m-\e[0m : Select/Deselect current row ·
|
|
88
|
+
· ·
|
|
89
|
+
· MANAGING MULTIPLE SESSION TABS: ·
|
|
90
|
+
· \e[36mTab\e[0m : Change session tab (to the right) (\e[36mShift+Tab\e[0m moves left) ·
|
|
91
|
+
· \e[36mQ\e[0m : Close current session tab ·
|
|
92
|
+
· \e[36mt\e[0m : [Open new]... session tab with current or selected row(s) as the seed ·
|
|
93
|
+
· \e[36mT\e[0m : [Restart]... session tab with current or selected row(s) as the seed ·
|
|
76
94
|
· ·
|
|
77
95
|
· TEXT SEARCH: ·
|
|
78
|
-
·
|
|
79
|
-
·
|
|
96
|
+
· \e[36m/\e[0m : Begin a text search (in tree view) ·
|
|
97
|
+
· \e[36mn\e[0m : Move to next search result ·
|
|
98
|
+
· ·
|
|
99
|
+
· ·
|
|
100
|
+
· \e[36m=\e[0m : Open prompt to type a console handle for current or selected row(s) ·
|
|
80
101
|
· ·
|
|
81
|
-
·
|
|
102
|
+
· \e[36mEsc\e[0m : Resets selection, last search, and number-to-move. (or returns to Tree View) ·
|
|
82
103
|
· ·
|
|
83
104
|
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
|
84
105
|
HELPSCREENADVANCEDPAGE
|
|
@@ -97,7 +118,8 @@ module Scryglass
|
|
|
97
118
|
|
|
98
119
|
def self.load_silently
|
|
99
120
|
begin
|
|
100
|
-
|
|
121
|
+
add_kernel_method
|
|
122
|
+
create_scryglass_session_manager
|
|
101
123
|
{ success: true, error: nil }
|
|
102
124
|
rescue => e
|
|
103
125
|
{ success: false, error: e }
|
|
@@ -130,8 +152,7 @@ module Scryglass
|
|
|
130
152
|
| > my_object.scry
|
|
131
153
|
|
|
|
132
154
|
| To resume the previous session: (in same console session)
|
|
133
|
-
| > scry
|
|
134
|
-
| > scry_resume (if you're in a breakpoint pry)
|
|
155
|
+
| > scry
|
|
135
156
|
\e[0m
|
|
136
157
|
CONSOLE_HELP
|
|
137
158
|
|
|
@@ -140,39 +161,51 @@ module Scryglass
|
|
|
140
161
|
|
|
141
162
|
private
|
|
142
163
|
|
|
143
|
-
def self.
|
|
164
|
+
def self.create_scryglass_session_manager
|
|
165
|
+
$scry_session_manager = Scryglass::SessionManager.new
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def self.add_kernel_method
|
|
144
169
|
Kernel.module_eval do
|
|
145
|
-
def scry(arg = nil,
|
|
146
|
-
#
|
|
170
|
+
def scry(arg = nil, _actions = nil)
|
|
171
|
+
# `actions` can't be a keyword arg due to this ruby issue:
|
|
172
|
+
# https://bugs.ruby-lang.org/issues/8316
|
|
147
173
|
|
|
148
|
-
|
|
174
|
+
Scryglass.config.validate!
|
|
175
|
+
|
|
176
|
+
current_console_binding = binding.of_caller(1)
|
|
177
|
+
|
|
178
|
+
receiver_is_just_the_console = self == current_console_binding.receiver
|
|
179
|
+
receiver = self unless receiver_is_just_the_console
|
|
149
180
|
# As in: `receiver.scry`,
|
|
150
181
|
# and no receiver means scry was called on 'main', (unless self is
|
|
151
182
|
# different in the because you've pry'd into something!)
|
|
152
183
|
|
|
153
184
|
seed_object = arg || receiver
|
|
154
185
|
|
|
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!
|
|
186
|
+
if seed_object
|
|
187
|
+
# If it's been given an arg or receiver, create new session!
|
|
188
|
+
# The global variable is purposeful, and not accessible outside of
|
|
189
|
+
# the one particular console instance.
|
|
190
|
+
$scry_session_manager << Scryglass::Session.new(seed_object)
|
|
191
|
+
end
|
|
166
192
|
|
|
167
|
-
|
|
168
|
-
if no_previous_session
|
|
193
|
+
unless $scry_session_manager.current_session
|
|
169
194
|
raise ArgumentError,
|
|
170
|
-
'`scry` requires either an argument, a receiver, or a past' \
|
|
195
|
+
'`scry` requires either an argument, a receiver, or a past ' \
|
|
171
196
|
'session to reopen. try `Scryglass.help`'
|
|
172
197
|
end
|
|
173
198
|
|
|
174
|
-
|
|
175
|
-
|
|
199
|
+
$scry_session_manager.track_binding!(current_console_binding)
|
|
200
|
+
|
|
201
|
+
begin
|
|
202
|
+
Hexes.stdout_rescue do
|
|
203
|
+
$scry_session_manager.run_scry_ui
|
|
204
|
+
end
|
|
205
|
+
rescue => e # Here we ensure good visibility in case of errors
|
|
206
|
+
screen_height, _screen_width = $stdout.winsize
|
|
207
|
+
$stdout.write "\e[#{screen_height};1H\n" # (Moves console cursor to bottom left corner)
|
|
208
|
+
raise e
|
|
176
209
|
end
|
|
177
210
|
end
|
|
178
211
|
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, char_limit: 20_000) } },
|
|
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,21 +2,83 @@
|
|
|
2
2
|
|
|
3
3
|
module Scryglass
|
|
4
4
|
module LensHelper
|
|
5
|
-
|
|
5
|
+
using ClipStringRefinement
|
|
6
|
+
|
|
7
|
+
def self.method_showcase_for(object, char_limit: nil)
|
|
8
|
+
# method_list = object.methods - Object.methods
|
|
6
9
|
method_list = object.methods - Object.methods
|
|
10
|
+
return '' if method_list.empty?
|
|
11
|
+
|
|
7
12
|
label_space = [method_list.map(&:length).max, 45].min
|
|
8
|
-
method_list.sort
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
method_list.sort!
|
|
14
|
+
running_method_showcase = ''.dup
|
|
15
|
+
|
|
16
|
+
method_list.each do |method_name|
|
|
17
|
+
label = method_name.to_s
|
|
18
|
+
label_padding = ' ' * [(label_space - label.length), 0].max
|
|
19
|
+
label = "\e[1;34m#{label}\e[0m" # make blue and bold
|
|
20
|
+
|
|
21
|
+
if char_limit && running_method_showcase.length >= char_limit
|
|
22
|
+
break
|
|
18
23
|
end
|
|
19
|
-
|
|
24
|
+
|
|
25
|
+
running_method_showcase <<
|
|
26
|
+
begin
|
|
27
|
+
method = object.method(method_name)
|
|
28
|
+
|
|
29
|
+
method_source_location = method.source_location.to_a.join(':')
|
|
30
|
+
source_location_line =
|
|
31
|
+
unless method_source_location.empty?
|
|
32
|
+
" \e[36m\e[4m#{method_source_location}\e[0m\n" # Cyan, underlined
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
highlighted_space = "\e[7m\s\e[0m"
|
|
36
|
+
method_lines = Hexes.capture_io { puts method.source }.split("\n")
|
|
37
|
+
method_lines.prepend('')
|
|
38
|
+
method_source = method_lines.map do |line|
|
|
39
|
+
' ' + highlighted_space + line
|
|
40
|
+
end.join("\n")
|
|
41
|
+
|
|
42
|
+
translated_parameters = method.parameters.map do |pair|
|
|
43
|
+
arg_type = pair[0]
|
|
44
|
+
arg_name = pair[1]
|
|
45
|
+
|
|
46
|
+
case arg_type
|
|
47
|
+
when :req
|
|
48
|
+
"#{arg_name}"
|
|
49
|
+
when :opt
|
|
50
|
+
"#{arg_name} = ?"
|
|
51
|
+
when :keyreq
|
|
52
|
+
"#{arg_name}:"
|
|
53
|
+
when :key
|
|
54
|
+
"#{arg_name}: ?"
|
|
55
|
+
when :rest
|
|
56
|
+
"*#{arg_name}"
|
|
57
|
+
when :keyrest
|
|
58
|
+
"**#{arg_name}"
|
|
59
|
+
when :block
|
|
60
|
+
"&#{arg_name}"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
arg_preview = "(#{translated_parameters.join(', ')})"
|
|
65
|
+
|
|
66
|
+
"#{label} #{arg_preview}\n" +
|
|
67
|
+
source_location_line +
|
|
68
|
+
"#{method_source}\n\n"
|
|
69
|
+
rescue => e
|
|
70
|
+
"#{label}#{label_padding} : " \
|
|
71
|
+
"Error: \e[31m#{e.message}\n\e[0m" +
|
|
72
|
+
(source_location_line || '') +
|
|
73
|
+
"\n"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
if char_limit
|
|
78
|
+
running_method_showcase.ansiless_clip_at(char_limit)
|
|
79
|
+
else
|
|
80
|
+
running_method_showcase
|
|
81
|
+
end
|
|
20
82
|
end
|
|
21
83
|
end
|
|
22
84
|
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
|