Class: Tuile::Component::TextView::Region
- Inherits:
-
Object
- Object
- Tuile::Component::TextView::Region
- Defined in:
- lib/tuile/component/text_view.rb
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
readonly
Number of hard lines this region owns.
Instance Method Summary collapse
-
#add_line(str) ⇒ void
Appends ‘str` as a new entry in this region: starts a fresh hard line first (when the region is non-empty), then appends `str`.
-
#append(str) ⇒ void
(also: #<<)
Verbatim append into this region’s tail.
-
#attached? ⇒ Boolean
‘true` while the region is owned by its Tuile::Component::TextView.
-
#empty? ⇒ Boolean
True iff the region owns zero hard lines.
-
#initialize(view, line_count = 0) ⇒ Region
constructor
A new instance of Region.
-
#insert(at, str) ⇒ void
Inserts ‘str` at region-relative hard-line index `at`.
-
#range ⇒ Range
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 ‘n` hard 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
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
Returns a new instance of Region.
920 921 922 923 |
# File 'lib/tuile/component/text_view.rb', line 920 def initialize(view, line_count = 0) @view = view @line_count = line_count end |
Instance Attribute Details
#line_count ⇒ Integer
Returns number of hard lines this region owns. Safe to read on a detached region (no error raised).
929 930 931 |
# File 'lib/tuile/component/text_view.rb', line 929 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.
1018 1019 1020 1021 1022 1023 1024 1025 1026 |
# File 'lib/tuile/component/text_view.rb', line 1018 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 to the region: embedded ‘“n”` creates new hard lines within the region, no-leading-newline input extends the region’s last hard line. Empty / ‘nil` input is a no-op (but still raises when detached). When the region is the spatial tail of the view, this uses the incremental Tuile::Component::TextView#append path; mid-document regions splice the affected slice of the physical-row buffer (lines outside the region are not re-wrapped).
974 975 976 977 |
# File 'lib/tuile/component/text_view.rb', line 974 def append(str) check_attached @view.send(:append_to_region, self, str) end |
#attached? ⇒ Boolean
Returns ‘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).
934 935 936 |
# File 'lib/tuile/component/text_view.rb', line 934 def attached? !@view.nil? end |
#empty? ⇒ Boolean
Returns 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.
941 |
# File 'lib/tuile/component/text_view.rb', line 941 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.
1055 1056 1057 |
# File 'lib/tuile/component/text_view.rb', line 1055 def insert(at, str) replace(at...at, str) end |
#range ⇒ Range
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.
986 987 988 989 990 |
# File 'lib/tuile/component/text_view.rb', line 986 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?.
1005 1006 1007 1008 1009 |
# File 'lib/tuile/component/text_view.rb', line 1005 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.
1070 1071 1072 1073 1074 1075 1076 1077 |
# File 'lib/tuile/component/text_view.rb', line 1070 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.
1042 1043 1044 1045 |
# File 'lib/tuile/component/text_view.rb', line 1042 def replace(range, str) check_attached @view.send(:replace_in_region, self, range, str) end |
#text ⇒ StyledString
Returns the joined content of just this region’s hard lines. Empty regions return StyledString::EMPTY.
946 947 948 949 |
# File 'lib/tuile/component/text_view.rb', line 946 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.
957 958 959 960 |
# File 'lib/tuile/component/text_view.rb', line 957 def text=(value) check_attached @view.send(:set_region_text, self, value) end |