Class: Typr::Text
Overview
A vertically scrollable text viewer with word-wrapping, header bar, row selection via hint characters, and search.
Accepts String, IO, or StringIO input. Content is split into display rows by newlines and line width, then rendered as a sliding window.
Example
text = Typr::Text.new(
input: StringIO.new("Hello\nworld"),
header: "My Doc",
top: 2, left: 0.1, right: 0.9, bottom: -4,
border: :round,
colors: { header: [:yellow, :grey30] }
)
text.draw
Constant Summary
Constants included from Typr
COLORS, INPUT, KEY_DELETE, KEY_ENTER, KEY_ESCAPE, KEY_INSERT, KEY_PAGEDOWN, KEY_PAGEUP, KEY_RETURN, KEY_TAB, MIMETYPES, MODES, OUTPUT
Instance Attribute Summary collapse
-
#tabspace ⇒ Object
Tabstop width in spaces.
Attributes inherited from Stack
#header, #hints, #hints_start, #keymap, #selected, #separator, #start
Attributes inherited from Space
#borders, #bottom, #colors, #interval, #left, #margin, #right, #top
Instance Method Summary collapse
-
#build(input = nil) ⇒ Object
(also: #<<)
Rebuilds the internal line buffer from
input. -
#draw ⇒ Object
Full draw cycle: rebuilds on resize, computes visible lines, and renders the viewport with borders and hints.
-
#initialize(args = {}) ⇒ Text
constructor
Creates a new Text widget.
-
#positions(row) ⇒ Object
Returns word-boundary column offsets for a given page row.
-
#print(row = nil) ⇒ Object
Renders a single display row.
-
#rows ⇒ Object
Total number of text lines in the buffer.
-
#search(query) ⇒ Object
Placeholder for text search.
Methods inherited from Stack
#cycle, #down, #draw_hints, #headspace, #height, #page, #page_down, #page_up, #pick, #reset, #send, #to_bottom, #to_top, #up
Methods inherited from Space
#border=, #draw_border, #height, #start, #stop, #width
Methods included from Typr
#background, clear, #color, #color_code, column, exit, #fade, #foreground, #get_background, #get_foreground, height, init, #mode, #mode_code, #move, #move_code, position, #prepare, #printables, read, #real_size, row, #show, size, width
Constructor Details
Instance Attribute Details
#tabspace ⇒ Object
Tabstop width in spaces. Default: 2.
30 31 32 |
# File 'lib/text.rb', line 30 def tabspace @tabspace end |
Instance Method Details
#build(input = nil) ⇒ Object Also known as: <<
Rebuilds the internal line buffer from input.
Splits text at newlines and word boundaries to fit the current width.
Pass nil to re-parse from the existing buffer (triggered on resize).
text.build("one\ntwo three") # => #<Typr::Text ...>
text << "appended line" # alias for build
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/text.rb', line 39 def build input=nil ( @lines = [0]; input = "" ) if rebuild = !input return self if rebuild && input == "" input = StringIO.new( input.to_s.dup ) unless input.respond_to?(:read) @tail = "" until input.closed? or input.eof? capacity = width - @margin.size - @tail.length chunk = (capacity < 1) ? "x" : capacity line = @tail + input.read(chunk) if line.empty? break else wrap_idx = line.index("\n") || line.rindex(" ") || line.length wrap = [wrap_idx, line.length].min + 1 @data += line[0...wrap] if wrap < line.length @tail = line[wrap..-1] @lines << @data.length else @tail = "" end end break if rebuild && line[-1] == "\n" end until @tail.empty? wrap_idx = @tail.index("\n") || @tail.rindex(" ") || @tail.length wrap = [wrap_idx, @tail.length].min + 1 @data += @tail[0...wrap] if wrap < @tail.length @lines << @data.length @tail = @tail[wrap..-1] else @tail = "" end end @lines << @data.length unless @lines.last == @data.length end |
#draw ⇒ Object
Full draw cycle: rebuilds on resize, computes visible lines, and renders the viewport with borders and hints.
text.draw
104 105 106 107 108 109 110 |
# File 'lib/text.rb', line 104 def draw (build; @lastwidth = width) if width != @lastwidth range = @lines[@start..@start+height] page = StringIO.new @data[range.first..range.last] @page=range[1..-1].map{|pos| page.read(pos-range.first-page.pos).rstrip} super end |
#positions(row) ⇒ Object
Returns word-boundary column offsets for a given page row. Used internally to place hint markers between words.
text.positions(2) # => [0, 6, 10, ...]
95 96 97 |
# File 'lib/text.rb', line 95 def positions row [0] + @page[row-1].chars.map.with_index{|c,i| i+1 if c == @separator}.compact end |
#print(row = nil) ⇒ Object
Renders a single display row. Pass an Integer for a content row
or :header for the header bar.
text.print(:header) # renders the header bar
text.print(3) # renders row 3 of the current page
84 85 86 87 88 |
# File 'lib/text.rb', line 84 def print row=nil header = ( row == :header ) return super unless row and @lines[ row + 1 ] unless header show prepare( ( header ? @header : @page[ row-@start ] ), width ) end |
#rows ⇒ Object
Total number of text lines in the buffer.
text.rows # => 42
116 |
# File 'lib/text.rb', line 116 def rows; @lines.count end |
#search(query) ⇒ Object
Placeholder for text search. Currently unimplemented.
text.search("query") # => nil
122 123 |
# File 'lib/text.rb', line 122 def search query end |