Class: MiniReadline::EditWindow

Inherits:
Object
  • Object
show all
Defined in:
lib/mini_readline/read_line/edit/edit_window.rb,
lib/mini_readline/read_line/edit/edit_window/sync_cursor.rb,
lib/mini_readline/read_line/edit/edit_window/sync_window.rb

Overview

Keeping the screen in sync.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ EditWindow

Determine the edit window limits.



14
15
16
17
18
19
20
# File 'lib/mini_readline/read_line/edit/edit_window.rb', line 14

def initialize(options)
  @options      = options
  @base_width   = window_width - @options[:base_prompt].length
  @scroll_width = window_width - @options[:scroll_prompt].length

  @left_margin, @window_buffer, @show_prompt = 0, "", true
end

Instance Attribute Details

#base_widthObject (readonly)

The width of the window with the base prompt



39
40
41
# File 'lib/mini_readline/read_line/edit/edit_window.rb', line 39

def base_width
  @base_width
end

#left_marginObject (readonly)

What is the offset of the window’s left margin?



23
24
25
# File 'lib/mini_readline/read_line/edit/edit_window.rb', line 23

def left_margin
  @left_margin
end

#scroll_widthObject (readonly)

The width of the window with the alternate prompt



42
43
44
# File 'lib/mini_readline/read_line/edit/edit_window.rb', line 42

def scroll_width
  @scroll_width
end

#window_bufferObject (readonly)

The shadow copy of what is actually on the screen?



36
37
38
# File 'lib/mini_readline/read_line/edit/edit_window.rb', line 36

def window_buffer
  @window_buffer
end

Instance Method Details

#active_widthObject

How wide is the active region of the window now?



50
51
52
# File 'lib/mini_readline/read_line/edit/edit_window.rb', line 50

def active_width
  window_scrolled? ? scroll_width : base_width
end

#build_screen_image(edit_buffer) ⇒ Object

Compute what should be on the screen.



37
38
39
40
41
42
43
44
45
# File 'lib/mini_readline/read_line/edit/edit_window/sync_window.rb', line 37

def build_screen_image(edit_buffer)
  working_region = edit_buffer[left_margin..right_margin]

  if (mask = @options[:secret_mask])
    mask[0] * working_region.length
  else
    working_region
  end.ljust(active_width)
end

#check_margins(length, edit_posn) ⇒ Object

Verify/update the window margins. Returns true if they’re fine.



22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/mini_readline/read_line/edit/edit_window/sync_window.rb', line 22

def check_margins(length, edit_posn)
  old_margins = [left_margin, right_margin]

  if length < base_width
    set_left_margin(0)
  elsif edit_posn < left_margin
    set_left_margin([edit_posn - scroll_step, 0].max)
  elsif edit_posn > right_margin
    set_right_margin(edit_posn + scroll_step)
  end

  old_margins == [left_margin, right_margin]
end

#promptObject

What is the current prompt?



55
56
57
# File 'lib/mini_readline/read_line/edit/edit_window.rb', line 55

def prompt
  window_scrolled? ? @options[:scroll_prompt] : @options[:base_prompt]
end

#right_marginObject

What is the offset of the window’s right margin?



26
27
28
# File 'lib/mini_readline/read_line/edit/edit_window.rb', line 26

def right_margin
  left_margin + active_width - 1
end

#scroll_stepObject

What is the scroll step?



60
61
62
# File 'lib/mini_readline/read_line/edit/edit_window.rb', line 60

def scroll_step
   @options[:scroll_step]
end

#sync_cursor(edit_posn) ⇒ Object

Keep the cursor in sync!



10
11
12
# File 'lib/mini_readline/read_line/edit/edit_window/sync_cursor.rb', line 10

def sync_cursor(edit_posn)
  MiniTerm.set_posn(column: edit_posn - left_margin + prompt.length)
end

#sync_window(edit_buffer, edit_posn) ⇒ Object

Keep the edit window in sync!



10
11
12
13
14
15
16
17
18
19
# File 'lib/mini_readline/read_line/edit/edit_window/sync_window.rb', line 10

def sync_window(edit_buffer, edit_posn)
  unless check_margins(edit_buffer.length, edit_posn)
    window_buffer.clear
    @show_prompt = true
  end

  image = build_screen_image(edit_buffer)
  update_screen(image)
  @window_buffer = image
end

#update_screen(image) ⇒ Object

Bring the screen into agreement with the image.



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/mini_readline/read_line/edit/edit_window/sync_window.rb', line 48

def update_screen(image)
  if @show_prompt
    MiniTerm.print("\r#{prompt.text}\r")
    @show_prompt = false
  end

  (0...active_width).each do |index|
    if (image_char = image[index]) != window_buffer[index]
      MiniTerm.set_posn(column: prompt.length + index)
      MiniTerm.print(image_char)
    end
  end
end

#window_scrolled?Boolean

Is the window currently in the scrolled state?

Returns:

  • (Boolean)


31
32
33
# File 'lib/mini_readline/read_line/edit/edit_window.rb', line 31

def window_scrolled?
  left_margin > 0
end

#window_widthObject

What is the full window width?



45
46
47
# File 'lib/mini_readline/read_line/edit/edit_window.rb', line 45

def window_width
  @options[:window_width]
end