Replace the physical ekp-region renderer with ekp-buffer text-property projection backed by shared semantic layout plans and stable live-edit transactions. Optimize the C-backed resize hot path, and add deterministic performance, ERT, GUI, fuzz, release, and documentation coverage for task017 through task032. BREAKING CHANGE: require ekp-buffer instead of ekp-region and rename module-owned ekp-region-* settings to ekp-buffer-*.
7.6 KiB
7.6 KiB
Issue: Logical Text API Boundary 2026-07-28
issue011 [ ] Direct Elisp buffer APIs observe physical layout text
- Status: Runtime fix and complete repository gate implemented by
task019–task022. The issue remains open only until the user accepts the visible behavior. - Summary: The former buffer renderer wrote synthesized glue spaces, soft newlines, discretionary hyphens, and hidden payload text into the real buffer. Boundary adapters made save/copy/search appear logical, but ordinary Elisp character APIs still observed the physical layout.
- Environment: Text-property renderer and synchronous live flow after
task021; Emacs 30.2. - Historical Repro:
- Insert text into a temporary buffer.
- Run the pre-
task020ekp-justify-regionwith a narrow width. - Compare the original text with
buffer-stringorbuffer-substring-no-properties. - Compare the same region through
filter-buffer-substring.
- Historical Evidence: The pre-fix batch probe produced a 39-character
physical representation from a 30-character logical string.
buffer-stringdid not equal the original, while the boundary-filtered substring did. - Expected vs Current:
- Expected: Ordinary Elisp buffer-text APIs observe the original character sequence while EKP's justified presentation remains visible and editable.
- Current implementation:
buffer-string,buffer-substring-no-properties, direct character access, ordinary search, syntax, markers, and saving operate on the unchanged source characters. APIs that preserve or inspect text properties may still observe EKP's display metadata; copy/kill strips that owned metadata.
- Investigation:
- The former
ekp-justify-regiondeleted source text and inserted the physical rendered string. - Reversible
ekp-glue,ekp-soft-break,ekp-soft-hyphen, andekp-hiddenmarkers made restoration possible but did not keep direct buffer reads logical. - Save/copy/isearch adapters compensated at individual boundaries and could not cover arbitrary Elisp consumers.
- The correct owner is the buffer representation: source characters must remain authoritative, and layout must be presentational state only.
- The former
- 2026-07-29 Design Evidence:
- The user ruled out overlays and selected text properties on existing source characters as the only projection mechanism.
(min-width ((PIXELS)))can add an exact absolute-pixel minimum width without adding buffer characters.(space-width FACTOR)can shrink or stretch existing ASCII spaces. Combined withmin-width, it rendered a natural 7px space at exact 3px and 20px targets in a clean GUI Emacs 30.2 probe while source text remained"a b".line-prefixcan provide display-only indentation for non-continuation lines. Native continuation lines still requirewrap-prefix.- A replacing
displaystring on an existing grapheme can show the grapheme followed by a discretionary hyphen and visual newline. A GUI probe displayedd-\nfrom the sourcedinabcdefgh; the source stayed eight characters, two screen lines were produced, onevertical-motionlanded on source position 5, and a 20pxline-prefixapplied to both rows. - The proposed Latin hyphen owner is the complete grapheme immediately
before the selected break. Its display string reproduces that grapheme,
appends the hyphen and newline, and uses the
cursorproperty to keep point on the source glyph. - Full reasoning, source links, limitations, and verification gates are
recorded in
tech-refer_text_property_layout_20260729.md.
- Root Cause: Logical document state and rendered layout shared one mutable character sequence. Reversible markers made the physical representation recoverable, not logical.
- Required Outcome: Remove the leak at the representation owner rather than adding per-command adapters. Ordinary Elisp character consumers must see logical content without losing justified display, exact round-trip, or seamless editing.
- Implemented Design:
- Logical source characters stay in the real buffer.
- The buffer renderer creates no overlay and inserts no layout character.
- Existing ASCII spaces use combined
space-widthand absolute-pixelmin-width; zero-source CJK/mixed glue usesmin-widthon the preceding complete grapheme; indentation usesline-prefix. - CJK breaks and Latin discretionary hyphens use replacing display strings on an existing complete grapheme.
- Projection values have exact EKP owner properties, are nonsticky, and
update under
with-silent-modifications. - Foreign
display,line-prefix,wrap-prefix,composition, andinvisibleowners make only the affected hard paragraph natural and diagnostic. - One buffer uses the narrowest live window as its authoritative width; simultaneous independent per-window plans are not claimed.
- Live editing uses a natural unfinished line, bounded overflow/pullback, a stable active-flow anchor, line-signature convergence, IME deferral, stale-generation rejection, and bounded automatic paragraph work.
- Fix:
ekp.elnow exposes a reusable semantic layout plan while retaining the compatible returned-string API.ekp-buffer.elconsumes that plan as a source-clean text-property projection and runs a distinct synchronous live-flow state machine. - Verification to Date:
- Buffer ERT passes 79/79, including unchanged source/tick/undo/modified state, direct logical reads, save/copy/isearch, foreign ownership, no-overlay checks, exact property forms, overflow, deletion pullback, exact type/delete break restoration, immediate active-line edge whitespace, active/inactive mark preservation, anchor lifecycle, IME, undo, resize, multiwindow width, and overload behavior.
- A clean Emacs 30.2 static probe passes exact 1–64px ASCII and
zero-source CJK glue, display-only breaks/hyphens,
line-prefix, point, vertical motion, region, mouse, unchanged source, and zero overlays. The seven-case scale/remap/fringe/width matrix passes. - A 31.71s dynamic recording passes before/immediate/settled overflow and deletion checkpoints. Immediate and settled source/projection hashes match; deletion restores the original source/projection hashes and break count; every assertion is true and temporal review passes.
- Final-source default and seeded-permuted ERT pass 170/170; every one of the 170 tests passes in a fresh Emacs process; C/Elisp fuzz passes 300/300.
- Warning-as-error Elisp compilation, checkdoc, pinned package-lint, release/dictionary/static gates, all four C build profiles, full diff review, and anti-slop cleanup pass.
- Independent final code review returns
APPROVEwith no findings; independent architecture review returnsCLEAR.
- User Confirmation: On 2026-07-28, the user explicitly defined the
target as clean text through Elisp APIs and requested recording only,
with implementation deferred. On 2026-07-29, the user resumed design,
excluded overlays, selected text properties, identified
min-width,space-width, andline-prefix, requested a non-polluting hyphen implementation, then explicitly requested complete implementation under the persistent goal model. Final visible-behavior acceptance is pending. - Resolved At: Unresolved.
- Resolved By: Pending.
- Commit: Pending.
- Related:
ekp.el,ekp-buffer.el,task017–task022,spec_text_property_layout_engine_20260729.md,tech-refer_text_property_layout_20260729.md,postmortem/20260729-text-property-live-layout.md.