Move the layer-stack storage codec from tp-stack down to tp-layer
Behavior-preserving relocation of tp--stack-hidden-p, tp--stack-props-to-list and tp--stack-build-props into tp-layer.el, beside their existing dependencies tp--layer-stack-to-list and tp--build-layer-props. The codec's only inputs are dash/seq/plist utilities, so it sits naturally at the layer-definition level, and the move lets the reactive re-render engine (tp-render.el, which may not require tp-stack) read and write stack storage without duplicating format knowledge - the prerequisite for making reactive updates write through to hidden/buried layer storage. tp-stack keeps calling the codec downward; no callers change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
28acdae183
commit
c6fbccf659
62
tp-layer.el
62
tp-layer.el
@ -1429,6 +1429,68 @@ First element is top layer, rest are in tp-layers."
|
||||
(cons top belows)
|
||||
belows))
|
||||
|
||||
;;; Layer stack storage codec
|
||||
;;
|
||||
;; The encoding/decoding of a layer stack into raw text properties
|
||||
;; lives here, beside `tp--build-layer-props' / `tp--layer-stack-to-list',
|
||||
;; so both the stack operations (tp-stack.el) and the reactive
|
||||
;; re-render engine (tp-render.el) can read and write stack storage
|
||||
;; without duplicating format knowledge or requiring each other.
|
||||
|
||||
(defun tp--stack-hidden-p (layer)
|
||||
"Return non-nil when the layer plist LAYER is flagged hidden.
|
||||
A layer is hidden when its plist carries a non-nil `tp-hidden' entry;
|
||||
see `tp-hide-layer'."
|
||||
(and (plist-get layer 'tp-hidden) t))
|
||||
|
||||
(defun tp--stack-props-to-list (props)
|
||||
"Return the ordered layer stack stored in raw text properties PROPS.
|
||||
The result is a list of layer plists, top layer first, including
|
||||
hidden layers (flagged with a non-nil `tp-hidden' entry) at their
|
||||
stack position. Returns nil for bare text.
|
||||
|
||||
This is the inverse of `tp--stack-build-props': when any entry of the
|
||||
`tp-layers' bookkeeping property is hidden, that property holds the
|
||||
whole ordered stack and the direct properties are only a render cache
|
||||
of the topmost non-hidden layer; otherwise the direct properties are
|
||||
the top layer and `tp-layers' holds the layers below it. Direct
|
||||
property edits made outside the stack API (for example `tp-set') are
|
||||
therefore discarded by the next stack operation while any layer is
|
||||
hidden."
|
||||
(let* ((idx (-elem-index 'tp-layers props))
|
||||
(top (if idx
|
||||
(-remove-at-indices (list idx (1+ idx)) props)
|
||||
props))
|
||||
(belows (plist-get props 'tp-layers)))
|
||||
(if (seq-some #'tp--stack-hidden-p belows)
|
||||
belows
|
||||
(tp--layer-stack-to-list top belows))))
|
||||
|
||||
(defun tp--stack-build-props (layer-list)
|
||||
"Build text properties from LAYER-LIST (top layer first).
|
||||
Like `tp--build-layer-props', but the `tp-layers' entry is only added
|
||||
when there are below-layers, so single-layer stacks do not carry a
|
||||
garbage (tp-layers nil) property. Consumers must therefore tolerate
|
||||
an absent `tp-layers' property (both `plist-get' and
|
||||
`tp--stack-map-region' do).
|
||||
|
||||
When any layer in LAYER-LIST is hidden (non-nil `tp-hidden' entry,
|
||||
see `tp-hide-layer'), the storage switches to full-stack mode: the
|
||||
direct properties are those of the topmost non-hidden layer (or no
|
||||
layer properties at all when every layer is hidden) and the
|
||||
`tp-layers' property holds the complete ordered LAYER-LIST.
|
||||
`tp--stack-props-to-list' reverses either representation."
|
||||
(cond
|
||||
((null layer-list) nil)
|
||||
((seq-some #'tp--stack-hidden-p layer-list)
|
||||
(append (seq-find (lambda (layer)
|
||||
(not (tp--stack-hidden-p layer)))
|
||||
layer-list)
|
||||
(list 'tp-layers layer-list)))
|
||||
((null (cdr layer-list)) (copy-sequence (car layer-list)))
|
||||
(t (append (car layer-list)
|
||||
(list 'tp-layers (cdr layer-list))))))
|
||||
|
||||
(defun tp--describe-layer-data (name)
|
||||
"Collect description data for layer NAME as a plist.
|
||||
Returns nil when NAME is not registered in `tp-layer-alist'.
|
||||
|
||||
54
tp-stack.el
54
tp-stack.el
@ -51,41 +51,12 @@ buffers)."
|
||||
(seq-take (cdr rest) n)))
|
||||
(t (error "Invalid layer arguments: %S" (cons start-or-string rest)))))
|
||||
|
||||
(defun tp--stack-hidden-p (layer)
|
||||
"Return non-nil when the layer plist LAYER is flagged hidden.
|
||||
A layer is hidden when its plist carries a non-nil `tp-hidden' entry;
|
||||
see `tp-hide-layer'."
|
||||
(and (plist-get layer 'tp-hidden) t))
|
||||
|
||||
(defun tp--plist-remove (plist key)
|
||||
"Return a copy of PLIST without KEY and its value.
|
||||
Comparison uses `eq'. PLIST itself is not modified."
|
||||
(cl-loop for (k v) on plist by #'cddr
|
||||
unless (eq k key) append (list k v)))
|
||||
|
||||
(defun tp--stack-props-to-list (props)
|
||||
"Return the ordered layer stack stored in raw text properties PROPS.
|
||||
The result is a list of layer plists, top layer first, including
|
||||
hidden layers (flagged with a non-nil `tp-hidden' entry) at their
|
||||
stack position. Returns nil for bare text.
|
||||
|
||||
This is the inverse of `tp--stack-build-props': when any entry of the
|
||||
`tp-layers' bookkeeping property is hidden, that property holds the
|
||||
whole ordered stack and the direct properties are only a render cache
|
||||
of the topmost non-hidden layer; otherwise the direct properties are
|
||||
the top layer and `tp-layers' holds the layers below it. Direct
|
||||
property edits made outside the stack API (for example `tp-set') are
|
||||
therefore discarded by the next stack operation while any layer is
|
||||
hidden."
|
||||
(let* ((idx (-elem-index 'tp-layers props))
|
||||
(top (if idx
|
||||
(-remove-at-indices (list idx (1+ idx)) props)
|
||||
props))
|
||||
(belows (plist-get props 'tp-layers)))
|
||||
(if (seq-some #'tp--stack-hidden-p belows)
|
||||
belows
|
||||
(tp--layer-stack-to-list top belows))))
|
||||
|
||||
(defun tp--stack-map-region (start end object function)
|
||||
"Call FUNCTION over each property run of [START, END) in OBJECT.
|
||||
|
||||
@ -109,31 +80,6 @@ previously property-less text."
|
||||
(funcall function i-start i-end
|
||||
(tp--stack-props-to-list props))))))
|
||||
|
||||
(defun tp--stack-build-props (layer-list)
|
||||
"Build text properties from LAYER-LIST (top layer first).
|
||||
Like `tp--build-layer-props', but the `tp-layers' entry is only added
|
||||
when there are below-layers, so single-layer stacks do not carry a
|
||||
garbage (tp-layers nil) property. Consumers must therefore tolerate
|
||||
an absent `tp-layers' property (both `plist-get' and
|
||||
`tp--stack-map-region' do).
|
||||
|
||||
When any layer in LAYER-LIST is hidden (non-nil `tp-hidden' entry,
|
||||
see `tp-hide-layer'), the storage switches to full-stack mode: the
|
||||
direct properties are those of the topmost non-hidden layer (or no
|
||||
layer properties at all when every layer is hidden) and the
|
||||
`tp-layers' property holds the complete ordered LAYER-LIST.
|
||||
`tp--stack-props-to-list' reverses either representation."
|
||||
(cond
|
||||
((null layer-list) nil)
|
||||
((seq-some #'tp--stack-hidden-p layer-list)
|
||||
(append (seq-find (lambda (layer)
|
||||
(not (tp--stack-hidden-p layer)))
|
||||
layer-list)
|
||||
(list 'tp-layers layer-list)))
|
||||
((null (cdr layer-list)) (copy-sequence (car layer-list)))
|
||||
(t (append (car layer-list)
|
||||
(list 'tp-layers (cdr layer-list))))))
|
||||
|
||||
(defun tp--stack-register-layers (stack object)
|
||||
"Register OBJECT in the reactive buffer registry for every layer in STACK.
|
||||
STACK is a list of layer plists as stored by the stack operations.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user