lib/scryglass/session.rb in scryglass-2.0.2 vs lib/scryglass/session.rb in scryglass-2.1.0
- old
+ new
@@ -7,37 +7,38 @@
attr_accessor :all_ros, :current_ro, :special_command_targets
attr_accessor :current_view_coords, :current_lens, :current_subject_type,
:view_panels, :current_panel_type,
- :progress_bar, :current_warning_messages
+ :progress_bar, :current_warning_messages,
+ :content_shape_changed,
+ :previous_screen_dimensions
attr_accessor :user_signals, :last_search, :number_to_move
attr_accessor :session_manager, :signal_to_manager, :session_is_current,
:tab_icon, :session_view_start_time
CURSOR_CHARACTER = '–' # These are en dashes (alt+dash), not hyphens or em dashes.
-
SEARCH_PROMPT = "\e[7mSearch for (regex, case-sensitive): /\e[00m"
-
VARNAME_PROMPT = "\e[7mName your object(s): @\e[00m"
-
+ METHOD_NAME_PROMPT = "\e[7mMethod(s) to call on object(s): object\e[00m"
SUBJECT_TYPES = [
:value,
:key
].freeze
-
CSI = "\e[" # "(C)ontrol (S)equence (I)ntroducer" for ANSI sequences
KEY_MAP = {
escape: 'esc', # Not a normal keystroke, see: genuine_escape_key_press
ctrl_c: "\u0003",
quit_session: 'q',
delete_session_tab: 'Q',
change_session_right: "\t", # Tab
change_session_left: 'Z', # Shift+Tab (well, one of its signals, after "\e" and "[")
+ start_new_session_from_target: 't',
+ restart_session_from_target: 'T',
digit_1: '1',
digit_2: '2',
digit_3: '3',
digit_4: '4',
digit_5: '5',
@@ -48,16 +49,16 @@
digit_0: '0',
move_cursor_up: 'A', # Up arrow (well, one of its signals, after "\e" and "[")
move_cursor_down: 'B', # Down arrow (well, one of its signals, after "\e" and "[")
open_bucket: 'C', # Right arrow (well, one of its signals, after "\e" and "[")
close_bucket: 'D', # Left arrow (well, one of its signals, after "\e" and "[")
- homerow_move_cursor_up: 'k', # To be like VIM arrow keys
+ homerow_move_cursor_up: 'k', # To be like VIM arrow keys
homerow_move_cursor_up_fast: 'K', # To be like VIM arrow keys
- homerow_move_cursor_down: 'j', # To be like VIM arrow keys
+ homerow_move_cursor_down: 'j', # To be like VIM arrow keys
homerow_move_cursor_down_fast: 'J', # To be like VIM arrow keys
- homerow_open_bucket: 'l', # To be like VIM arrow keys
- homerow_close_bucket: 'h', # To be like VIM arrow keys
+ homerow_open_bucket: 'l', # To be like VIM arrow keys
+ homerow_close_bucket: 'h', # To be like VIM arrow keys
# Note, shift-UP and shift-DOWN are not here, as those work very
# differently: by virtue of the type-a-number-first functionality.
toggle_view_panel: ' ',
switch_lens: '>',
switch_subject_type: '<',
@@ -72,10 +73,11 @@
control_screen: '?',
build_instance_variables: '@',
build_ar_relations: '.',
build_enum_children: '(',
smart_open: 'o',
+ build_method_results: 'c',
select_siblings: '|',
select_all: '*',
select_current: '-',
start_search: '/',
continue_search: 'n',
@@ -102,10 +104,12 @@
self.session_manager = nil
self.signal_to_manager = nil
self.tab_icon = nil
self.session_is_current = false
self.session_view_start_time = nil
+ self.content_shape_changed = true
+ self.previous_screen_dimensions = $stdout.winsize
top_ro = roify(seed, parent_ro: nil, depth: 1)
top_ro.has_cursor = true
self.current_ro = top_ro
@@ -126,11 +130,11 @@
last_two_signals.last || last_two_signals.first
end
def run_scry_ui
redraw = true
- signal_to_manager = nil
+ self.signal_to_manager = nil
self.session_view_start_time = Time.now # For this particular tab/session
## On hold: Record/Playback Functionality:
# case actions
# when :record
@@ -278,20 +282,28 @@
when KEY_MAP[:move_view_right_fast]
current_view_panel.move_view_right(50)
when KEY_MAP[:build_instance_variables]
build_instance_variables_for_target_ros
+ self.content_shape_changed = true
tree_view.slide_view_to_cursor # Just a nice-to-have
when KEY_MAP[:build_ar_relations]
build_activerecord_relations_for_target_ros
+ self.content_shape_changed = true
tree_view.slide_view_to_cursor # Just a nice-to-have
when KEY_MAP[:build_enum_children]
build_enum_children_for_target_ros
+ self.content_shape_changed = true
tree_view.slide_view_to_cursor # Just a nice-to-have
when KEY_MAP[:smart_open]
smart_open_target_ros
+ self.content_shape_changed = true
tree_view.slide_view_to_cursor # Just a nice-to-have
+ when KEY_MAP[:build_method_results]
+ build_method_result_ros
+ self.content_shape_changed = true
+ tree_view.slide_view_to_cursor # Just a nice-to-have
when KEY_MAP[:select_siblings]
sibling_ros = if current_ro.top_ro?
[top_ro]
else
@@ -321,30 +333,34 @@
end
when KEY_MAP[:start_search]
initiate_search
when KEY_MAP[:continue_search]
+ # TODO: extract in separate commit
if last_search
go_to_next_search_result
else
message = { text: 'No Search has been entered', end_time: Time.now + 2 }
self.current_warning_messages << message
end
-
+ when KEY_MAP[:start_new_session_from_target]
+ self.signal_to_manager = :start_new_session_from_target
+ return subjects_of_target_ros
+ when KEY_MAP[:restart_session_from_target]
+ self.signal_to_manager = :restart_session_from_target
+ return subjects_of_target_ros
when KEY_MAP[:change_session_right]
self.signal_to_manager = :change_session_right
return
when KEY_MAP[:change_session_left]
self.signal_to_manager = :change_session_left
return
when KEY_MAP[:name_objects]
name_subjects_of_target_ros
when KEY_MAP[:return_objects]
self.signal_to_manager = :return
- subjects = subjects_of_target_ros
- self.special_command_targets = []
- return subjects
+ return subjects_of_target_ros
end
beep_if_user_had_to_wait(wait_start_time)
end
end
@@ -412,18 +428,22 @@
action_count ||= !number_to_move.empty? ? number_to_move.to_i : 1
navigate_up_multiple(action_count)
self.number_to_move = ''
tree_view.slide_view_to_cursor
+
+ self.content_shape_changed = true if current_panel_type == :lens
end
def move_cursor_down_action(action_count = nil)
action_count ||= !number_to_move.empty? ? number_to_move.to_i : 1
navigate_down_multiple(action_count)
self.number_to_move = ''
tree_view.slide_view_to_cursor
+
+ self.content_shape_changed = true if current_panel_type == :lens
end
def clear_tracked_values
self.special_command_targets = []
self.last_search = nil
@@ -505,12 +525,11 @@
while scanning_ro.parent_ro
expand!(scanning_ro.parent_ro)
scanning_ro = scanning_ro.parent_ro
end
- tree_view.recalculate_boundaries # Yes, necessary :)
- lens_view.recalculate_boundaries # Yes, necessary :)
+ self.content_shape_changed = true # Needed here even if ros weren't expanded.
tree_view.current_view_coords = { y: 0, x: 0 }
tree_view.slide_view_to_cursor
else
message = { text: 'No Match Found', end_time: Time.now + 2 }
self.current_warning_messages << message
@@ -591,10 +610,11 @@
elsif current_ro.parent_ro
collapse!(current_ro.parent_ro)
end
move_cursor_to(current_ro.parent_ro) until current_ro.visible?
+ self.content_shape_changed = true
tree_view.slide_view_to_cursor
end
def expand_targets
if special_command_targets.any?
@@ -604,10 +624,12 @@
target_ros.each { |target_ro| expand!(target_ro) }
self.special_command_targets = []
else
expand!(current_ro)
end
+
+ self.content_shape_changed = true
end
def reset_the_view_or_cursor
if current_view_panel.current_view_coords != { x: 0, y: 0 }
current_view_panel.current_view_coords = { x: 0, y: 0 }
@@ -615,12 +637,21 @@
move_cursor_to(top_ro)
end
end
def draw_screen
- current_view_panel.recalculate_boundaries # This now happens at every screen
- # draw to account for the user changing the screen size. Otherwise glitch.
+ current_screen_dimensions = $stdout.winsize
+ screen_size_changed = current_screen_dimensions != previous_screen_dimensions
+ self.previous_screen_dimensions = current_screen_dimensions
+
+ if content_shape_changed || screen_size_changed
+ current_view_panel.recalculate_boundaries
+ # ^This no longer happens at every screen draw, but only when
+ # determined necessary.
+ self.content_shape_changed = false
+ end
+
current_view_panel.ensure_correct_view_coords
screen_string = current_view_panel.screen_string
Hexes.overwrite_screen(screen_string)
$stdout.write "#{CSI}1;1H" # Moves terminal cursor to top left corner,
@@ -638,10 +669,45 @@
$stdout.write "#{CSI}1;#{VARNAME_PROMPT.ansiless_length + 1}H" # (Moves
# console cursor to just after the varname prompt, before user types)
$stdin.gets.chomp
end
+ def get_method_text_from_user
+ _screen_height, screen_width = $stdout.winsize
+ $stdout.write "#{CSI}1;1H" # (Moves console cursor to top left corner)
+ $stdout.print ' ' * screen_width
+ $stdout.write "#{CSI}1;1H" # (Moves console cursor to top left corner)
+ $stdout.print METHOD_NAME_PROMPT
+ $stdout.write "#{CSI}1;#{METHOD_NAME_PROMPT.ansiless_length + 1}H" # (Moves
+ # console cursor to just after the search prompt, before user types)
+ $stdin.gets.chomp
+ end
+
+ def build_method_result_ros
+ method_text = get_method_text_from_user
+
+ if method_text.empty?
+ message = { text: 'Call text cannot be blank',
+ end_time: Time.now + 2 }
+ self.current_warning_messages << message
+ print "\a" # (Audio 'beep')
+ return
+ end
+
+ if method_text[0] =~ /[a-z]|[A-Z]/
+ message = { text: 'Call text must start with \'.\' or other symbol',
+ end_time: Time.now + 3 }
+ self.current_warning_messages << message
+ print "\a" # (Audio 'beep')
+ return
+ end
+
+ build_method_results_for_target_ros(method_text)
+
+ self.special_command_targets = []
+ end
+
def name_subjects_of_target_ros
typed_name = get_subject_name_from_user
typed_name = typed_name.tr(' ', '')
if typed_name.empty?
@@ -720,23 +786,28 @@
when :tree
:lens
when :lens
:tree
end
+
+ self.content_shape_changed = true
end
def toggle_current_subject_type
self.current_subject_type =
case current_subject_type
when :value
:key
when :key
:value
end
+
+ self.content_shape_changed = true
end
def scroll_lens_type
self.current_lens += 1
+ self.content_shape_changed = true
end
def move_cursor_to(new_ro)
current_ro.has_cursor = false
new_ro.has_cursor = true