Fix tp-text reactive variable synchronization when initial value is nil
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
This commit is contained in:
parent
842482245b
commit
094f8f0f88
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,3 +7,4 @@ dash.el
|
||||
# Backup files
|
||||
*~
|
||||
\#*\#
|
||||
dash.el
|
||||
|
||||
43
tp-tests.el
43
tp-tests.el
@ -3044,6 +3044,49 @@ preserving the native text property behavior."
|
||||
;; Cleanup
|
||||
(makunbound 'tp-test-reactive-text))))
|
||||
|
||||
(ert-deftest tp-test-tp-text-reactive-nil-initializes-variable ()
|
||||
"Test tp-text with nil reactive variable initializes the variable to source text.
|
||||
When tp-text is bound to a reactive variable and that variable is nil,
|
||||
the source text should be used and the reactive variable should be updated."
|
||||
(tp-test-with-temp-buffer
|
||||
(defvar tp-test-text-var nil "Test variable for tp-text initialization.")
|
||||
(setq tp-test-text-var nil)
|
||||
(unwind-protect
|
||||
(progn
|
||||
;; Define layer with tp-text bound to a reactive variable
|
||||
(tp-define-layer 'test-init-text-layer
|
||||
:props '(face bold tp-text $tp-test-text-var))
|
||||
;; Apply layer to string - variable is nil, so source text should be used
|
||||
(let ((result (tp-set "2" 'test-init-text-layer)))
|
||||
;; Result should be the source text "2"
|
||||
(should (equal result "2"))
|
||||
;; tp-test-text-var should now be "2"
|
||||
(should (equal tp-test-text-var "2"))
|
||||
;; tp-text property should be "2"
|
||||
(should (equal (tp-at 0 'tp-text result) "2")))
|
||||
;; Now set the variable to a different value and test again
|
||||
(setq tp-test-text-var "18")
|
||||
;; Redefine layer to reset resolved props
|
||||
(tp-define-layer 'test-init-text-layer
|
||||
:props '(face bold tp-text $tp-test-text-var))
|
||||
(let ((result (tp-set "2" 'test-init-text-layer)))
|
||||
;; Result should be the variable value "18", not source "2"
|
||||
(should (equal result "18"))
|
||||
;; Variable should remain "18"
|
||||
(should (equal tp-test-text-var "18"))))
|
||||
;; Cleanup
|
||||
(makunbound 'tp-test-text-var))))
|
||||
|
||||
(ert-deftest tp-test-tp-text-direct-string-uses-specified-text ()
|
||||
"Test tp-text with direct string value uses that string, not source text.
|
||||
When tp-text is set directly to a string (not a reactive variable),
|
||||
the inserted text should be that string, not the source text."
|
||||
(let ((result (tp-set "2" 'tp-text "23")))
|
||||
;; Result should be "23", not "2"
|
||||
(should (equal result "23"))
|
||||
;; tp-text property should be "23"
|
||||
(should (equal (tp-at 0 'tp-text result) "23"))))
|
||||
|
||||
(ert-deftest tp-test-tp-text-reactive-computed ()
|
||||
"Test tp-text with computed reactive variable."
|
||||
(tp-test-with-temp-buffer
|
||||
|
||||
31
tp.el
31
tp.el
@ -576,6 +576,26 @@ WHERE specifies which buffers to update:
|
||||
;;; Layer 4: Reactive Text (tp-text property)
|
||||
;;;============================================================================
|
||||
|
||||
(defun tp--find-tp-text-reactive-var (layer-name)
|
||||
"Find the reactive variable symbol used for tp-text in LAYER-NAME.
|
||||
Returns the variable symbol (e.g., tp-test-counter) if tp-text uses a
|
||||
reactive variable (e.g., $tp-test-counter), or nil if not found.
|
||||
Searches through `tp-reactive-deps' to find the original reactive props."
|
||||
(catch 'found
|
||||
(dolist (dep tp-reactive-deps)
|
||||
(let* ((var-sym (car dep))
|
||||
(layer-entry (assoc layer-name (cdr dep))))
|
||||
(when layer-entry
|
||||
(let ((reactive-props (cdr layer-entry)))
|
||||
;; Check if tp-text in reactive-props uses this variable
|
||||
(when (plist-member reactive-props 'tp-text)
|
||||
(let ((tp-text-val (plist-get reactive-props 'tp-text)))
|
||||
;; Check if tp-text-val is a reactive symbol for this variable
|
||||
(when (and (tp--reactive-symbol-p tp-text-val)
|
||||
(eq (tp--reactive-var-symbol tp-text-val) var-sym))
|
||||
(throw 'found var-sym))))))))
|
||||
nil))
|
||||
|
||||
(defun tp--update-reactive-text (layer-name &optional where)
|
||||
"Update text regions that have tp-text property with LAYER-NAME applied.
|
||||
This is called when a reactive variable bound to tp-text changes.
|
||||
@ -644,6 +664,17 @@ NEW-OBJECT is the new string object (only different for strings with tp-text)."
|
||||
(with-current-buffer object
|
||||
(buffer-substring-no-properties start end))
|
||||
(buffer-substring-no-properties start end)))))
|
||||
;; If tp-text uses a reactive variable, update that variable to match
|
||||
;; This ensures the reactive variable and buffer text stay in sync
|
||||
(when-let ((layer-name (plist-get props 'tp-name)))
|
||||
(when-let ((reactive-var (tp--find-tp-text-reactive-var layer-name)))
|
||||
;; Update the reactive variable with the current text (buffer-local)
|
||||
(set reactive-var current-text)
|
||||
;; Also update the layer definition so future accesses see the new value
|
||||
(let ((layer-props (cdr (assoc layer-name tp-layer-alist))))
|
||||
(when layer-props
|
||||
(setf (cdr (assoc layer-name tp-layer-alist))
|
||||
(plist-put layer-props 'tp-text current-text))))))
|
||||
(list (plist-put props 'tp-text current-text) end object)))
|
||||
;; tp-text has a string value - replace the text in the region
|
||||
((stringp tp-text-val)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user