Skip to main content

max / quasi

State that a field's described state is its value and the caret is the renderer's
Author: Max Johnson <me@maxj.phd> · 2026-08-13 13:33 UTC
Signed with PGP, not checked
Commit: 7367f737fb0a9868aa45379f45e9a78dada1ed49
Parent: fb42934
3 files changed, +43 insertions, -8 deletions
M Cargo.lock +8 -8
@@ -5159,14 +5159,6 @@
5159 5159 source = "registry+https://github.com/rust-lang/crates.io-index"
5160 5160 checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
5161 5161
5162 - [[patch.unused]]
5163 - name = "synckit-client"
5164 - version = "0.8.0"
5165 -
5166 - [[patch.unused]]
5167 - name = "synckit-config"
5168 - version = "0.2.0"
5169 -
5170 5162 [[patch.unused]]
5171 5163 name = "kberg"
5172 5164 version = "0.1.0"
@@ -5182,3 +5174,11 @@
5182 5174 [[patch.unused]]
5183 5175 name = "tagtree"
5184 5176 version = "0.4.0"
5177 +
5178 + [[patch.unused]]
5179 + name = "synckit-client"
5180 + version = "0.8.0"
5181 +
5182 + [[patch.unused]]
5183 + name = "synckit-config"
5184 + version = "0.2.0"
@@ -710,6 +710,32 @@
710 710 /// the buffer never went anywhere, so nothing is lost and there is nothing to
711 711 /// re-offer. This is the layer where the loss happens, so this is the layer that
712 712 /// repairs it.
713 + ///
714 + /// # A field's described state is its value, and the caret is the renderer's
715 + ///
716 + /// `d52884b0`, decided 2026-08-12. Nothing here carries a caret position, and
717 + /// nothing in [`layout::FieldKind`] does either. A description names the field
718 + /// and, where it has one, its completion source. Where the caret sits is how a
719 + /// renderer decides what to offer from that source.
720 + ///
721 + /// The question came from goingson's `search.js`, whose completion list depends
722 + /// on which token the caret is inside rather than on the value: it reads
723 + /// `selectionStart`, listens for caret moves that change nothing else, and
724 + /// writes the caret back when a suggestion is applied. That is a real
725 + /// dependency, and it still does not belong here. A caret is where the user is
726 + /// pointing inside a control, the same class of fact as a scroll offset and a
727 + /// focus position, and this stack already puts those in the renderer's view
728 + /// rather than in the description (`quasi-tui`'s `View`).
729 + ///
730 + /// Growing this struct to (value, caret) was rejected: it is the most-consumed
731 + /// member in the vocabulary, every renderer would owe it an answer, and a
732 + /// terminal's answer would be a second cursor concept beside the one the runtime
733 + /// already holds. The measured demand was one file.
734 + ///
735 + /// Reversible if a second consumer appears that needs the caret described rather
736 + /// than held, such as a completion that has to survive a fragment swap. That is
737 + /// a member here and a cascade, the same shape as every other addition.
738 + ///
713 739 /// No `Hash`, for the reason [`Tag`] has none: it can hold an [`Action`], which
714 740 /// holds [`Params`], which is a `Vec`.
715 741 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -27,6 +27,15 @@
27 27 //! because it turns out to be the same discovery four times: what is typed,
28 28 //! what has focus, how far a pane is scrolled, and where the back button goes.
29 29 //! None of the four is in a description and none of them should be.
30 + //!
31 + //! One more is of the same kind and is deliberately not held here: where the
32 + //! caret sits inside a field. `d52884b0`, decided 2026-08-12. It belongs on
33 + //! this list by nature, and it is absent because no described screen
34 + //! needs it yet: the one measured consumer is goingson's `search.js`, whose
35 + //! completion list depends on which token the caret is inside, and that file
36 + //! stays JS. Saying so here keeps the boundary explicit, so the next screen that
37 + //! wants caret-dependent completion knows this is where it would land rather
38 + //! than re-asking whether a description should carry one. It should not.
30 39
31 40 use std::collections::{BTreeMap, BTreeSet};
32 41