Commit Graph

309 Commits

Author SHA1 Message Date
Kinneyzhang
ca2f02dcdf Add tp-doctest.el: README examples as executable tests
63 assertions reproduce README code blocks and compare against the
exact documented outputs; make doctest runs them in batch and exits
non-zero on any mismatch, so docs and code cannot silently drift
again. Wired into the Makefile and mentioned in both READMEs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 21:18:44 +08:00
Kinneyzhang
ecdd952b55 Unify -do shortfall to all-or-nothing on strings and buffers
tp-forward-do/tp-backward-do target the TIMES-th match specifically;
when fewer matches exist the string paths applied FUNCTION to the last
available match -- the wrong target -- while buffer paths applied
nothing. Both now apply nothing on shortfall and return the available
count. Updates the two legacy with-range tests that codified the
string behavior, adds four shortfall/exact-count regression tests, and
documents the contract in both READMEs and the docstrings. Suite
443/443 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 21:16:56 +08:00
Kinneyzhang
2b33495898 Align README (EN/CN) and docs/ with modular architecture and 0.2.0 semantics
README.md/README_CN.md: new verified Quick Start (fixes the dead
#quick-start nav link); Installation rewritten for the tp-*.el module
family; every broken or drifted example fixed and executed in batch
Emacs (mandatory () ARGLIST and quoted reactive keywords in all
define-tp/define-tps calls, corrected tp-search-map argument order,
interval-list returns, stacked duplicate-face results, gap intervals,
last-wins tp-plist, non-destructive string forms, per-pattern match
ordering, case-fold regexp outputs, rewired end-to-end theme example);
documents the symmetric tp-backward contract, the length-changing
replacement rules, all four tp-put-layer layer specs, and the
previously-missing tp-member, buffer/display macros, and palette
system; state resets now use tp-layer-reset; license corrected to
GPLv3+. CN mirrors EN exactly (119 headings / 258 fences each; code
blocks identical, comments translated).

docs/ARCHITECTURE.md rewritten around the real nine-module layering
and hook-variable inversions; nonexistent helper names removed.
docs/CODE-ANALYSIS.md marked as pre-split historical analysis with
locations/counts corrected. Reactive docs aligned with the fixed
engine semantics (replace-not-accumulate, buffer-local isolation,
nil computed values, batching union, first-render transform).

287 fenced blocks from both READMEs executed: 0 failures; 56-example
assertion suite passes; combined ERT suite 439/439 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 21:01:01 +08:00
Kinneyzhang
9aca18979b Reject length-changing string replacements instead of corrupting
tp--replace-match-text's string branch silently truncated longer
replacements and left residue on shorter ones ("<foo>" into a 3-char
match yielded "<fo"). Strings cannot change length in place, so the
honest contract is: same-length replacements mutate in place as before;
a different-length replacement signals a clear error directing the
caller to a buffer OBJECT. Buffer paths (delete+insert) are unchanged.
Updates the five tests that codified truncation/residue and adds a
same-length regression test; suite 439/439 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 20:12:37 +08:00
Kinneyzhang
ceb0dfb0bc Fix confirmed bugs in layer, stack, search, and reactive-render modules
35 fixes across tp-layer.el, tp-stack.el, tp-search.el, tp-reactive.el
and tp-render.el, each empirically reproduced before and after:
layer-definition resolution/cycles/copying/cleanup, clipped region-local
stack mutators, symmetric backward search matching, length-changing
replacements, and reactive re-render correctness (replace-not-accumulate,
buffer-local isolation, batching union, per-interval props).

Adds four per-module regression suites (100 new tests); combined suite
is 438/438 green. tp-test-backward updated to the now-symmetric backward
matching contract it previously codified inverted. The string-vs-buffer
shortfall divergence in tp-forward-do/tp-backward-do is documented in
CHANGELOG as a known divergence rather than changed. Adds CHANGELOG.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 20:01:20 +08:00
Kinneyzhang
08b5d9aa1c Add tp-member: plist-member-style property lookup
Like tp-at but distinguishes a property present with value nil from an
absent property, returning (PROPERTY VALUE) or nil.  Covered by four
new tests in tp-ops-tests.el; full suite 338/338 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 19:33:34 +08:00
Kinneyzhang
49cb8d8062 Fix confirmed bugs in core ops and builtins/palette modules
ops/core (B1-B8): tp-remove no longer drops 3rd+ properties; string
removal is per-interval via tp--map-intervals instead of smearing
position-0 props; tp-clear defaults bounds from OBJECT; (tp-get STR N N)
works like the buffer region form; no bogus (:key nil) from trailing
bare keywords; region form signals immediately on flat PROP/VAL args;
face-family prepend semantics extended to font-lock-face/mouse-face.

builtins/palette (B45-B51): Emacs 28.1 compat for plistp/subr-x;
display-buffer macros use a minor-mode keymap instead of mutating the
major-mode map; tp-link resolves palette colors lazily (theme-correct);
tp-palette-alist is the single source of truth (stale defvars dropped);
tp-headline handles integer heights; tp-space matches its documented
pixel spec; tp-parse-color accepts one-sided cons colors.

Test infra: fixture gains unwind-protect teardown via tp-layer-reset
(incl. transforms); file header/provide renamed to tp-tests; suite is
order-independent (verified with shuffled runs). Adds Makefile with
test/compile/clean targets.

334 tests green (280 legacy + 54 new regression tests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 18:31:59 +08:00
Kinneyzhang
5e5017a726 Split tp.el monolith into layered modules (behavior-preserving)
tp.el (4866 lines) is now an umbrella over nine modules with an
enforceable dependency order: tp-core -> tp-reactive -> tp-layer ->
tp-ops -> tp-search -> tp-render -> tp-stack -> tp-palette ->
tp-builtins.  Upward dependencies are inverted through four hook
variables installed by tp-render.el.

Also: require text-property-search (fixes tp-backward void-function),
clip tp-intervals to the requested range, add the shared clipping
interval walker tp--map-intervals and tp-face-properties, remove
synced-conflict junk files, byte-compilation now succeeds (define-tp
macroexpansion previously failed at compile time).

All 280 legacy tests pass plus 8 new tp-core tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 17:13:44 +08:00
Kinneyzhang
af0980efef update 2026-07-26 16:31:36 +08:00
Kinneyzhang
29b2ee54d3 update 2026-01-13 18:11:40 +08:00
copilot-swe-agent[bot]
9aace2f6fe Update docs/CODE-ANALYSIS.md to include self-reference in file structure
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-10 09:31:01 +00:00
copilot-swe-agent[bot]
715ceaac1e Add comprehensive code analysis report for developers
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-10 09:29:32 +00:00
copilot-swe-agent[bot]
ce06c76089 Initial plan 2026-01-10 09:22:55 +00:00
Kinneyzhang
a1ce94c0dd add heatmap tp-palette 2026-01-08 15:48:34 +08:00
Kinneyzhang
5d75ff434c update tests 2026-01-08 11:52:16 +08:00
copilot-swe-agent[bot]
6b96d8575f Simplify reactive text replacement to directly reset properties with new values
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-08 03:43:55 +00:00
copilot-swe-agent[bot]
7d7979c54c Revert changes to tp--replace-reactive-text-in-buffer to fix checkbox strikethrough toggle
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-08 03:17:05 +00:00
copilot-swe-agent[bot]
89d76fa0cc Address code review feedback: improve docstring and null handling
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-08 03:00:59 +00:00
copilot-swe-agent[bot]
3a0f774c70 Optimize tp--replace-reactive-text-in-buffer to preserve all original text properties
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-08 02:58:45 +00:00
copilot-swe-agent[bot]
e383882a74 Initial plan 2026-01-08 02:53:22 +00:00
Kinneyzhang
041f53025e fix tp 'pointer 'hander 2026-01-08 10:43:21 +08:00
copilot-swe-agent[bot]
9d97430d62 Improve documentation for merge-mode parameter in tp--handle-tp-text-property
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-07 09:24:35 +00:00
copilot-swe-agent[bot]
148b255456 Fix tp-reset and tp-set to preserve embedded text properties from tp-text
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-07 09:22:32 +00:00
copilot-swe-agent[bot]
39f38018a4 Initial plan 2026-01-07 09:15:18 +00:00
Kinneyzhang
9bcf14b2b3 delete tests 2026-01-07 11:53:05 +08:00
copilot-swe-agent[bot]
710e52c67f Fix tp-parse-color to handle unknown background-mode
When (frame-parameter nil 'background-mode) returns nil (e.g., in
batch mode or certain configurations), both tp-theme-light-p and
tp-theme-dark-p return nil, causing color parsing to fail for
cons cell ("light" . "dark") and plist (:light "l" :dark "d") formats.

Added default fallback to light color when background-mode is unknown.
This is the root cause of tp-palette settings not taking effect.

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-07 03:51:28 +00:00
copilot-swe-agent[bot]
6c111dfd2b Fix pcase syntax error in tp-palette-pure function
Fixed the pcase branches for tp-palette-bg-p and tp-palette-fbg-p
predicates which had an extra `symbol` keyword incorrectly placed
between the pattern and the return expression. This caused these
branches to return the original symbol instead of the processed
intern result, leading to tp-palette settings not taking effect
when using palettes with -bg or -fbg suffixes.

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-07 03:43:33 +00:00
copilot-swe-agent[bot]
150d4e149c Initial plan 2026-01-07 03:40:16 +00:00
copilot-swe-agent[bot]
347abb601e Improve tp--apply-props-to-string to handle partial range correctly
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-07 03:26:47 +00:00
copilot-swe-agent[bot]
6392be848e Fix: Use propertize directly to preserve text property intervals
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-07 03:23:08 +00:00
copilot-swe-agent[bot]
fe0594c575 Fix: tp-match-set and tp-regexp-set now create a copy instead of modifying original string
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-07 03:00:25 +00:00
copilot-swe-agent[bot]
3621fbb92c Initial plan 2026-01-07 02:50:10 +00:00
Kinneyzhang
4dff70cd59 improve code 2026-01-07 02:20:38 +08:00
Kinneyzhang
676d41aba6 Merge remote-tracking branch 'origin/copilot/fix-tp-remove-custom-attributes' 2026-01-07 02:11:09 +08:00
Kinneyzhang
02ffc7f70f fix bug 2026-01-07 02:11:06 +08:00
copilot-swe-agent[bot]
aa53dc1b99 Improve variable naming: rename face-to-subtract to remaining-face for clarity
Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-06 18:04:21 +00:00
copilot-swe-agent[bot]
18b85e446a Fix duplicate function name and test corrections
- Rename second tp--remove-nested-keys to tp--remove-nested-sub-keys
- Fix logic in tp--remove-props-from-string to properly handle nil face subtraction result
- Fix tests to properly use return values from tp-set and tp-remove
- Add face-was-modified tracking variable

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-06 18:02:35 +00:00
copilot-swe-agent[bot]
b062eb30fd Fix tp-remove for custom layers and complex face sub-properties
- Add tp--remove-sub-from-face-value to handle complex face structures
- Add tp--subtract-face-from-face-value to remove layer face contributions
- Add tp--get-layer-face-contribution helper function
- Update tp--remove-props-from-string to handle layer face subtraction
- Update tp--remove-sub-from-string to use new helper
- Update tp--expand-layer-to-props-list to detect layer properties
- Fix missing closing paren in tp--remove-property function
- Update tests to match expected behavior

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-06 17:52:57 +00:00
copilot-swe-agent[bot]
c223723d9a Initial plan 2026-01-06 17:21:38 +00:00
Kinneyzhang
25a8daa36e Merge remote-tracking branch 'origin/copilot/optimize-string-properties' 2026-01-07 01:15:18 +08:00
Kinneyzhang
f28c9ba7b3 fix bug 2026-01-07 01:15:16 +08:00
copilot-swe-agent[bot]
6ee2473327 Support layer name removal in tp-remove for custom text properties
When tp-remove is called with a layer name (defined with define-tp),
it now correctly identifies and removes all properties that the layer
adds, plus the tp-name property.

Example:
  (define-tp tp-delete (color)
    `(face (:strike-through ,color)))

  (let ((str "emacs"))
    (setq str (tp-set str 'face 'bold 'tp-delete t))
    (insert (tp-remove str 'tp-delete)))

Changes:
- Added tp--expand-layer-to-props-list helper function
- Added tp--expand-props-to-remove helper function
- Modified tp--remove-props-from-string to expand layer names
- Modified tp--remove-property for buffer regions to handle layer names
- Added tests for custom layer removal

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-06 17:13:22 +00:00
copilot-swe-agent[bot]
d81bf6de18 Update Chinese documentation with string modification behavior details
Added detailed behavior table and examples to README_CN.md:
- tp-set, tp-reset, tp-add, tp-remove sections now explain:
  - Entire string form creates a NEW string (non-destructive)
  - Region form with string modifies in-place
  - Underlying implementation (propertize vs put-text-property)
- Updated return value documentation
- Updated tp-add-to-layers and tp-add-to-all-layers sections

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-06 17:00:44 +00:00
copilot-swe-agent[bot]
a48a523120 Address code review: improve pattern matching and readability
- Collect all match positions before applying transformations to avoid
  string-match position invalidation issues
- Use list* instead of nested cons for better readability
- Improve plist building efficiency by iterating instead of copy-sequence
- Add detailed comment explaining :reset mode usage with tp-text

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-06 16:24:35 +00:00
copilot-swe-agent[bot]
98f807993a Refine string modification behavior: region form modifies in-place, entire string form creates copy
Updated the implementation to clearly distinguish:
- (tp-set/add/reset START END PROPS STRING): Modifies original string in-place
- (tp-set/add/reset "string" PROP VAL ...): Creates NEW string using propertize

Also fixed code review issues:
- Removed unused 'offset' variable
- Made tp--remove-nested-keys non-destructive

Updated documentation with detailed behavior table and examples.

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-06 16:18:38 +00:00
copilot-swe-agent[bot]
70f60f1a25 Use propertize for non-destructive string operations in tp-set/add/reset/remove
This change makes tp-set, tp-add, tp-reset, and tp-remove return a NEW
propertized string when operating on strings, rather than modifying the
original string in-place. This is more idiomatic for Emacs Lisp and
prevents unintended side effects.

For buffer operations, the existing in-place modification behavior is
preserved.

Key changes:
- Added tp--apply-props-to-string helper function that uses propertize
- Updated tp-set, tp-add, tp-reset to use the new helper for strings
- Updated tp-remove with new helper functions for non-destructive removal
- Updated tp--match-apply and tp--regexp-apply to accumulate changes
- Added tests verifying original strings are not modified
- Updated documentation to reflect the new behavior

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2026-01-06 16:05:58 +00:00
copilot-swe-agent[bot]
ba1f3f26c3 Initial plan 2026-01-06 15:56:14 +00:00
Kinneyzhang
319109ef54 Merge remote-tracking branch 'origin/copilot/update-tp-el-external-properties' 2026-01-06 04:08:58 +08:00
Kinneyzhang
e6a14e124f update 2026-01-06 04:08:26 +08:00
copilot-swe-agent[bot]
a75820dc20 Initial plan 2026-01-05 19:59:21 +00:00