Class: Tuile::Component::TextView::Region
- Inherits:
-
Object
- Object
- Tuile::Component::TextView::Region
- Defined in:
- lib/tuile/component/text_view.rb,
sig/tuile.rbs
Overview
A logical section of a Tuile::Component::TextView's text — a contiguous run of hard lines the app wants to address as a unit (e.g. an LLM's "thinking" output vs. its assistant message). The view always has at least one region, an internal default that owns whatever hard lines aren't claimed by an app-created region.
Apps don't construct regions directly; call #create_region to get one. The handle stays valid as long as the region is attached — i.e. until #text= (or #clear) wipes the slate and installs a fresh internal default. Detached regions raise RuntimeError on every mutator and reader.
A region's position is derived from its sibling order and counts,
so growing or shrinking an earlier region implicitly shifts the
ranges of all later regions. Empty regions occupy zero rows but
still hold a position in the sequence; region.text = "" collapses
a region's visible footprint without detaching it. Pre-creating
empty placeholder regions is supported and is the natural pattern
for "I'll fill this in later" layouts.
Instance Attribute Summary collapse
-
#line_count ⇒ Integer, untyped
@return — number of hard lines this region owns.
Instance Method Summary collapse
-
#add_line(str) ⇒ void
Appends
stras a new entry in this region: starts a fresh hard line first (when the region is non-empty), then appendsstr. -
#append(str) ⇒ void
(also: #<<)
Verbatim append into this region's tail.
-
#attached? ⇒ Boolean
@return —
truewhile the region is owned by its Tuile::Component::TextView. - #check_attached ⇒ void
- #detach! ⇒ void
-
#empty? ⇒ Boolean
@return — true iff the region owns zero hard lines.
-
#initialize(view, line_count = 0) ⇒ Region
constructor
@param
view— the owning view (nevernilat construction). -
#insert(at, str) ⇒ void
Inserts
strat region-relative hard-line indexat. -
#range ⇒ ::Range[untyped]
@return — the hard-line indices this region currently occupies —
start...(start + line_count). -
#remove ⇒ void
Removes this region from its view.
-
#remove_last_n_lines(n) ⇒ void
Drops the last
nhard lines from this region's tail. -
#replace(range, str) ⇒ void
Replaces a contiguous range of this region's hard lines with the parsed content of
str. -
#text ⇒ StyledString
@return — the joined content of just this region's hard lines.
-
#text=(value) ⇒ void
Replaces all of this region's hard lines with the parsed content of
value.
Constructor Details
#initialize(view, line_count = 0) ⇒ Region
@param view — the owning view (never nil at construction).
@param line_count — number of hard lines this region owns.
864 865 866 867 |
# File 'lib/tuile/component/text_view.rb', line 864 def initialize(view, line_count = 0) @view = view @line_count = line_count end |
Instance Attribute Details
#line_count ⇒ Integer, untyped
@return — number of hard lines this region owns. Safe to read on a detached region (no error raised).
873 874 875 |
# File 'lib/tuile/component/text_view.rb', line 873 def line_count @line_count end |
Instance Method Details
#add_line(str) ⇒ void
This method returns an undefined value.
Appends str as a new entry in this region: starts a fresh
hard line first (when the region is non-empty), then appends
str. Scoped equivalent of Tuile::Component::TextView#add_line. On an empty
region behaves like #append.
@param str
957 958 959 960 961 962 963 964 965 |
# File 'lib/tuile/component/text_view.rb', line 957 def add_line(str) check_attached parsed = StyledString.parse(str) if empty? append(parsed) else append(StyledString.plain("\n") + parsed) end end |
#append(str) ⇒ void Also known as: <<
This method returns an undefined value.
Verbatim append into this region's tail. Same semantics as
Tuile::Component::TextView#append but scoped: embedded "\n" creates new hard lines
within the region, other input extends the region's last hard line.
Empty / nil is a no-op (but still raises when detached).
@param str
913 914 915 916 |
# File 'lib/tuile/component/text_view.rb', line 913 def append(str) check_attached @view.send(:append_to_region, self, str) end |
#attached? ⇒ Boolean
@return — true while the region is owned by its
Tuile::Component::TextView. Becomes false permanently once detached
(typically by Tuile::Component::TextView#text= / Tuile::Component::TextView#clear).
878 879 880 |
# File 'lib/tuile/component/text_view.rb', line 878 def attached? !@view.nil? end |
#check_attached ⇒ void
This method returns an undefined value.
1028 1029 1030 |
# File 'lib/tuile/component/text_view.rb', line 1028 def check_attached raise "region is detached" unless attached? end |
#detach! ⇒ void
This method returns an undefined value.
1023 1024 1025 |
# File 'lib/tuile/component/text_view.rb', line 1023 def detach! @view = nil end |
#empty? ⇒ Boolean
@return — true iff the region owns zero hard lines. Empty regions render nothing — they still hold a position in the sequence, so subsequent mutations route to them as usual.
885 |
# File 'lib/tuile/component/text_view.rb', line 885 def empty? = @line_count.zero? |
#insert(at, str) ⇒ void
This method returns an undefined value.
Inserts str at region-relative hard-line index at.
Equivalent to replace(at...at, str). Region-scoped counterpart
of Tuile::Component::TextView#insert; at == line_count is allowed and appends
at the region's tail.
@param at — region-relative index in [0, line_count].
@param str
994 995 996 |
# File 'lib/tuile/component/text_view.rb', line 994 def insert(at, str) replace(at...at, str) end |
#range ⇒ ::Range[untyped]
@return — the hard-line indices this region currently
occupies — start...(start + line_count). Empty regions
return a degenerate exclusive range at their position (e.g.
5...5). The result is computed on each call and so always
reflects sibling mutations.
925 926 927 928 929 |
# File 'lib/tuile/component/text_view.rb', line 925 def range check_attached start = @view.send(:region_start_index, self) start...(start + @line_count) end |
#remove ⇒ void
This method returns an undefined value.
Removes this region from its view. The region's hard lines (if
any) are deleted from the buffer — subsequent regions' ranges
shift up by line_count — and the handle detaches permanently.
The view keeps its always-≥1-region invariant: if this was the
only remaining region, a fresh internal default is installed
(the app doesn't get a handle to it; call
Tuile::Component::TextView#create_region again to start tracking).
Idempotent: calling remove on an already-detached region is a
silent no-op (unlike the other mutators, which raise). This
lets cleanup paths blindly call remove without first checking
#attached?.
944 945 946 947 948 |
# File 'lib/tuile/component/text_view.rb', line 944 def remove return unless attached? @view.send(:remove_region, self) end |
#remove_last_n_lines(n) ⇒ void
This method returns an undefined value.
Drops the last n hard lines from this region's tail.
Subsequent regions' ranges shift up by the number actually
dropped. n is clamped to #line_count, so passing a large
n empties the region — the handle stays attached (use
#remove when the goal is to drop the region itself).
n == 0 and an already-empty region are no-ops.
@param n
1009 1010 1011 1012 1013 1014 1015 1016 |
# File 'lib/tuile/component/text_view.rb', line 1009 def remove_last_n_lines(n) check_attached raise TypeError, "expected Integer, got #{n.inspect}" unless n.is_a?(Integer) raise ArgumentError, "n must not be negative, got #{n}" if n.negative? return if n.zero? || empty? @view.send(:remove_last_n_from_region, self, n) end |
#replace(range, str) ⇒ void
This method returns an undefined value.
Replaces a contiguous range of this region's hard lines with the
parsed content of str. Region-scoped counterpart of
Tuile::Component::TextView#replace: indices are 0-based within the region
(so replace(0, "x") rewrites the region's first line, not
the buffer's). Same range conventions apply — Integer,
inclusive/exclusive Range, empty range as insertion at
begin, and begin == line_count for end-insertion.
@param range — region-relative hard-line indices.
@param str — replacement content.
981 982 983 984 |
# File 'lib/tuile/component/text_view.rb', line 981 def replace(range, str) check_attached @view.send(:replace_in_region, self, range, str) end |
#text ⇒ StyledString
@return — the joined content of just this region's hard lines. Empty regions return StyledString::EMPTY.
890 891 892 893 |
# File 'lib/tuile/component/text_view.rb', line 890 def text check_attached @view.send(:text_for_region, self) end |
#text=(value) ⇒ void
This method returns an undefined value.
Replaces all of this region's hard lines with the parsed content
of value. Accepts the same inputs as Tuile::Component::TextView#text=; empty
or nil content collapses the region to zero hard lines.
@param value
901 902 903 904 |
# File 'lib/tuile/component/text_view.rb', line 901 def text=(value) check_attached @view.send(:set_region_text, self, value) end |