Go to file
copilot-swe-agent[bot] bca7d4a41c Reorganize tp.el code to match API Quick Reference order
Functions are now organized in the following order:
1. Core Property Functions: tp-set, tp-reset, tp-add, tp-set-face, tp-set-display, tp-get, tp-at, tp-remove, tp-clear
2. Pattern Matching Functions: tp-match, tp-match-reset, tp-match-add, tp-regexp, tp-regexp-reset, tp-regexp-add
3. Search & Navigation Functions: tp-search-forward, tp-search-backward, tp-forward, tp-backward, tp-forward-do, tp-backward-do, tp-search, tp-search-do
4. Query Functions: tp-intervals, tp-empty-p, tp-plist
5. Layer Definition Functions: tp-define-layer, tp-layer-props, tp-group-props, tp-layer-undefine, tp-group-undefine, tp-layer-reset
6. Layer Placement Functions: tp-put-layer, tp-push-layer
7. Layer Deletion Functions: tp-delete-layer, tp-pop-layer
8. Layer Movement Functions: tp-raise-layer, tp-rotate-layer, tp-pin-layer, tp-switch-layer
9. Layer Merging Functions: tp-merge-layers, tp-flatten-layers
10. Layer Query Functions: tp-layer-list, tp-layer-count, tp-layer-exists-p, tp-layer-top

Co-authored-by: Kinneyzhang <38454496+Kinneyzhang@users.noreply.github.com>
2025-12-15 08:08:59 +00:00
.gitignore Refactor: Extract helper functions to reduce code duplication in match/regexp functions and single-property setters 2025-12-14 11:42:07 +00:00
LICENSE Initial commit 2025-10-13 00:13:38 +08:00
README_CN.md Implement new text property search and navigation functions 2025-12-15 07:35:41 +00:00
README.md Implement new text property search and navigation functions 2025-12-15 07:35:41 +00:00
tp-tests.el Implement new text property search and navigation functions 2025-12-15 07:35:41 +00:00
tp.el Reorganize tp.el code to match API Quick Reference order 2025-12-15 08:08:59 +00:00

tp.el - Text Properties Library for Emacs

A powerful text properties manipulation library with an innovative layer system

FeaturesInstallationQuick StartAPI ReferenceLayer System中文文档


tp.el provides a convenient and unified API for manipulating Emacs text properties. Inspired by ov.el for overlays, tp.el offers:

  • Unified API: All property-setting functions work on both strings and buffers
  • Layer System: Stack multiple property sets on the same text region
  • Pattern Matching: Apply properties to text matching strings or regexps

Features

  • Unified Object Support: Functions like tp-set, tp-match, tp-regexp work on both strings and buffers
  • Clear Semantics: tp-reset (replace all), tp-set (replace specified), tp-add (deep merge)
  • Nested Property Access: Get/set/remove nested sub-properties with path syntax
  • Innovative Layer System: Stack, rotate, and manage multiple layers of properties
  • Layer Groups: Define reusable sets of related layers
  • Search & Navigation: Find and navigate through propertized text
  • Pattern Matching: Apply properties to string/regexp matches with reset/add variants
  • Clean API: Consistent naming and calling conventions

Requirements

  • Emacs 28.1+ (uses object-intervals function)
  • dash.el (list manipulation utilities)

Installation

;; Add to your load-path
(add-to-list 'load-path "/path/to/tp")
(require 'tp)

Or with use-package:

(use-package tp
  :load-path "/path/to/tp")

API Reference

API Quick Reference

A complete overview of all tp.el functions organized by category:

Core Property Functions

Function Description
tp-set Set text properties (replaces specified properties only)
tp-reset Replace ALL text properties
tp-add Add/merge properties with deep merge support
tp-set-face Set only the face property
tp-set-display Set only the display property
tp-get Get property value(s) from position or range
tp-at Get all properties at a position
tp-remove Remove a property or sub-property
tp-clear Clear all text properties from a region

Pattern Matching Functions

Function Description
tp-match Set properties on string pattern matches
tp-match-reset Reset all properties on string matches
tp-match-add Add/merge properties on string matches
tp-regexp Set properties on regexp matches
tp-regexp-reset Reset all properties on regexp matches
tp-regexp-add Add/merge properties on regexp matches

Search & Navigation Functions

Function Description
tp-search-forward Raw wrapper for text-property-search-forward
tp-search-backward Raw wrapper for text-property-search-backward
tp-forward Search forward N times for text with property
tp-backward Search backward N times for text with property
tp-forward-do Apply function to N forward matches
tp-backward-do Apply function to N backward matches
tp-search Search all matching properties in range or string
tp-search-do Apply function to all matching properties

Query Functions

Function Description
tp-intervals Get property intervals in a region
tp-empty-p Check if object has no properties
tp-plist Get merged plist of all properties

Layer Definition Functions

Function Description
tp-define-layer Define a layer or layer group
tp-layer-props Get properties for a layer
tp-group-props Get properties for all layers in a group
tp-layer-undefine Remove layer definition
tp-group-undefine Remove group definition
tp-layer-reset Clear all layer/group definitions

Layer Placement Functions

Function Description
tp-put-layer Set layer at specific index position
tp-push-layer Push layer to top of stack

Layer Deletion Functions

Function Description
tp-delete-layer Delete layer by name or index
tp-pop-layer Remove top layer

Layer Movement Functions

Function Description
tp-raise-layer Move layer up/down by N positions
tp-rotate-layer Cycle layers (top goes to bottom)
tp-pin-layer Pin a layer to top (make visible)
tp-switch-layer Swap positions of two layers

Layer Merging Functions

Function Description
tp-merge-layers Merge specified layers into a new layer
tp-flatten-layers Flatten all layers into a single layer

Layer Query Functions

Function Description
tp-layer-list List all layer names in region
tp-layer-count Count layers in region
tp-layer-exists-p Check if layer exists in region
tp-layer-top Get name of top (visible) layer

Core Property Functions

tp-set - Set Text Properties

Set text properties on a string or buffer region. Replaces only the specified properties, preserving others.

;; Current buffer (properties as a list)
(tp-set START END '(PROPERTY VALUE ...))

;; Specific buffer or string
(tp-set START END '(PROPERTY VALUE ...) OBJECT)

;; Entire string (flat properties)
(tp-set STRING PROPERTY VALUE ...)

Examples:

;; Set face on buffer region
(tp-set 1 10 '(face bold))  ; => (1 . 10)

;; Set multiple properties
(tp-set 1 10 '(face bold help-echo "Click me"))

;; Set on specific buffer
(tp-set 1 10 '(face italic) my-buffer)

;; Set properties on a string (0-indexed)
(setq my-string (tp-set 0 5 '(face italic) "Hello World"))
;; => #("Hello World" 0 5 (face italic))

;; Set properties on entire string
(tp-set "Hello" 'face 'bold 'mouse-face 'highlight)
;; => #("Hello" 0 5 (face bold mouse-face highlight))

tp-reset - Replace All Properties

Completely replace ALL text properties with the specified ones.

(tp-reset START END '(PROPERTY VALUE ...) &optional OBJECT)
(tp-reset STRING PROPERTY VALUE ...)

Examples:

;; Replace all properties in region
(tp-reset 1 10 '(face bold))  ; Any existing properties are removed

;; On string
(tp-reset "Hello" 'face 'italic)

tp-add - Add/Merge Properties

Add or update properties with deep merge support for nested plists.

(tp-add START END '(PROPERTY VALUE ...) &optional OBJECT)
(tp-add STRING PROPERTY VALUE ...)

Examples:

;; Add properties (preserves existing, merges nested)
(tp-add 1 10 '(help-echo "tooltip"))

;; Deep merge face properties
(tp-set 1 10 '(face (:foreground "red")))
(tp-add 1 10 '(face (:background "blue")))
;; Result: face is (:foreground "red" :background "blue")

;; Face prepending - symbol faces are prepended to face list
(tp-set "Hello" 'face 'bold)
(tp-add "Hello" 'face 'shadow)
;; Result: face is (shadow bold)

tp-set-face - Set Face Property

Set only the face property, preserving other properties.

(tp-set-face START END FACE &optional OBJECT)
(tp-set-face STRING FACE)

Examples:

(tp-set-face 1 10 'bold)
(tp-set-face 1 10 '(:foreground "red" :weight bold))
(tp-set-face "Hello" 'italic)

tp-set-display - Set Display Property

Set only the display property, preserving other properties.

(tp-set-display START END DISPLAY &optional OBJECT)
(tp-set-display STRING DISPLAY)

Examples:

(tp-set-display 1 10 '(space :width 10))
(tp-set-display "  " '(space :width 20))

tp-get - Get Property Value

Get property value(s) from position or range, with support for nested sub-properties.

For range and entire string queries, returns a list of (START END VALUE) intervals, allowing you to see all property values across the range.

;; Single position
(tp-get POSITION PROPERTY)
(tp-get POSITION PROPERTY OBJECT)

;; Nested sub-property access
(tp-get POSITION PROPERTY SUB-KEY ...)

;; Range - specific property (returns list of intervals)
(tp-get START END PROPERTY)
(tp-get START END PROPERTY OBJECT)

;; Range with property path as list
(tp-get START END '(PROPERTY) OBJECT)
(tp-get START END '(PROPERTY SUB-KEY ...) OBJECT)

;; Range with deeply nested property path
(tp-get START END '(PROPERTY SUB-KEY SUB-SUB-KEY ...) OBJECT)

;; Range extracting multiple keys from nested property
(tp-get START END '(PROPERTY SUB-KEY (KEY1 KEY2 ...)) OBJECT)

;; Range - all properties (returns list of intervals)
(tp-get START END)
(tp-get START END OBJECT)

;; Entire string (returns list of intervals)
(tp-get STRING)
(tp-get STRING PROPERTY)
(tp-get STRING PROPERTY SUB-KEY ...)
(tp-get STRING PROPERTY SUB-KEY '(KEY1 KEY2 ...))
(tp-get STRING '(PROPERTY SUB-KEY ...))

Examples:

;; Get from current buffer
(tp-get 5 'face)           ; => bold

;; Get nested sub-property
(tp-get 5 'face :foreground)      ; => "red"
(tp-get 5 'face :box :color)      ; => "blue"
(tp-get 5 'display :width)        ; => 10

;; Get from string (0-indexed)
(tp-get 0 'face my-string) ; => italic

;; Get from range - returns list of (START END VALUE) intervals
(tp-get 1 10 'face)        ; => ((1 6 bold))

;; Get with multiple intervals
(tp-set 0 5 '(face bold) str)
(tp-set 12 17 '(face italic) str)
(tp-get 0 17 'face str)    ; => ((0 5 bold) (12 17 italic))

;; Get with property path as list
(tp-get 5 20 '(face :underline :style) my-string)  ; => ((5 20 wave))

;; Get deeply nested property from entire string
(tp-get str 'face :underline :color)  ; => ((0 5 "green") (6 11 "yellow"))

;; Get multiple keys from nested property
(tp-get str 'face :underline '(:color :style))
;; => ((0 5 (:color "green" :style wave)) (6 11 (:color "yellow" :style line)))

;; Get all properties from range
(tp-get 1 10)              ; => ((1 6 (face bold help-echo "test")))

;; Get from entire string - returns list of intervals
(tp-get str)               ; => ((0 5 (face bold)) (12 17 (face italic)))
(tp-get str 'face)         ; => ((0 5 bold) (12 17 italic))
(tp-get str 'face :foreground)    ; => ((0 5 "red") (12 17 "blue"))
(tp-get str '(face :foreground))  ; => ((0 5 "red") (12 17 "blue"))

tp-at - Get All Properties

(tp-at &optional POINT OBJECT)

Get all text properties at POINT as a plist.

Examples:

(tp-at 5)  ; => (face bold help-echo "test")
(tp-at 0 my-string)  ; Get from string

tp-remove - Remove Property

Remove a property or nested sub-property from a region or entire string.

;; Remove entire property (buffer)
(tp-remove START END PROPERTY &optional OBJECT)

;; Remove sub-property (buffer)
(tp-remove START END '(PROPERTY SUB-KEY) &optional OBJECT)

;; Remove nested sub-properties (buffer)
(tp-remove START END '(PROPERTY SUB-KEY (NESTED-KEYS...)) &optional OBJECT)

;; Remove from entire string
(tp-remove STRING PROP1 PROP2 ...)
(tp-remove STRING PROPERTY SUB-KEY)
(tp-remove STRING PROPERTY SUB-KEY '(NESTED-KEYS...))

Examples:

;; Remove entire property
(tp-remove 1 10 'face)

;; Remove sub-property from face
(tp-remove 1 10 '(face :underline))

;; Remove specific nested keys, keep others
(tp-remove 1 10 '(face :underline (:style :position)))
;; Removes :style and :position from :underline
;; If :color exists in :underline, it's preserved

;; Remove from entire string
(tp-remove "Hello World" 'face 'help-echo)  ; Remove multiple properties
(tp-remove "Hello World" 'face :underline)  ; Remove sub-property
(tp-remove "Hello World" 'face :underline '(:style :position))  ; Remove nested

tp-clear - Clear All Properties

(tp-clear &optional START END OBJECT)

Clear all text properties from a region.

Examples:

(tp-clear 1 10)     ; Clear region
(tp-clear)          ; Clear entire buffer

Pattern Matching Functions

tp-match - Match String

;; Buffer
(tp-match PATTERN '(PROPERTY VALUE ...))

;; String or Buffer object
(tp-match PATTERN OBJECT '(PROPERTY VALUE ...))

;; Pattern as (PATTERN STRING) format
(tp-match '(PATTERN STRING) '(PROPERTY VALUE ...))

Set properties on all occurrences of a string pattern.

Examples:

;; In buffer - returns list of (START . END) pairs
(tp-match "TODO" '(face warning))
;; => ((10 . 14) (50 . 54) ...)

;; On string - returns modified string
(tp-match "o" "Hello World" '(face bold))
;; => #("Hello World" 4 5 (face bold) 7 8 (face bold))

;; Using (PATTERN STRING) format
(tp-match '("world" "Hello world") '(face bold))
;; => #("Hello world" 6 11 (face bold))

tp-match-reset - Match and Reset

Reset (completely replace) all properties on matches.

(tp-match-reset PATTERN '(PROPERTY VALUE ...) &optional OBJECT)

Examples:

(tp-match-reset "TODO" '(face warning))
;; Replaces ALL properties on matched text

tp-match-add - Match and Add

Add/merge properties on matches with deep merge support.

(tp-match-add PATTERN '(PROPERTY VALUE ...) &optional OBJECT)

Examples:

(tp-match-add "TODO" '(face (:underline t)))
;; Merges with existing properties

tp-regexp - Match Regexp

;; Buffer
(tp-regexp PATTERN '(PROPERTY VALUE ...))

;; String or Buffer object
(tp-regexp PATTERN OBJECT '(PROPERTY VALUE ...))

Set properties on all matches of a regular expression.

Examples:

;; Highlight all numbers in buffer
(tp-regexp "[0-9]+" '(face font-lock-number-face))

;; On string
(tp-regexp "[A-Z]+" "Hello WORLD" '(face bold))
;; => #("Hello WORLD" 6 11 (face bold))

tp-regexp-reset - Regexp and Reset

Reset (completely replace) all properties on regexp matches.

(tp-regexp-reset PATTERN '(PROPERTY VALUE ...) &optional OBJECT)

tp-regexp-add - Regexp and Add

Add/merge properties on regexp matches with deep merge support.

(tp-regexp-add PATTERN '(PROPERTY VALUE ...) &optional OBJECT)

Search & Navigation Functions

tp-search-forward / tp-search-backward

(tp-search-forward PROPERTY &optional VALUE PREDICATE NOT-CURRENT)
(tp-search-backward PROPERTY &optional VALUE PREDICATE NOT-CURRENT)

Raw wrappers for Emacs's text-property-search-forward and text-property-search-backward. These are low-level search functions that work directly with prop-match objects.


tp-forward / tp-backward

(tp-forward PROPERTY &optional VALUE OBJECT N)
(tp-backward PROPERTY &optional VALUE OBJECT N)

Search forward/backward N times for text with PROPERTY.

  • N is the number of searches, defaulting to 1.
  • VALUE is the optional value to match.
  • OBJECT can be a buffer; nil defaults to current buffer.
  • Returns the prop-match object from the last successful search.

Examples:

;; Find next text with 'marker property
(tp-forward 'marker)

;; Find next text where 'type equals 'heading
(tp-forward 'type 'heading)

;; Search forward 3 times
(tp-forward 'marker nil nil 3)

tp-forward-do / tp-backward-do

(tp-forward-do FUNCTION PROPERTY &optional VALUE OBJECT N)
(tp-backward-do FUNCTION PROPERTY &optional VALUE OBJECT N)

Search forward/backward N times for text with PROPERTY and apply FUNCTION to each match.

  • FUNCTION receives two arguments: the prop-match object and OBJECT.
  • N is the number of searches, defaulting to 1.
  • Returns the number of successful matches.

Examples:

;; Apply function to next 3 markers
(tp-forward-do
 (lambda (match obj)
   (message "Found at %d" (prop-match-beginning match)))
 'marker nil nil 3)

tp-search - Search All Matches

;; Buffer/string region
(tp-search START END PROPERTY &optional VALUE OBJECT)

;; Entire string
(tp-search STRING PROPERTY &optional VALUE)

Search for all text with PROPERTY in a buffer/string range or entire string.

Returns a list of (START END VALUE) for all matching regions.

Examples:

;; Find all 'marker properties in buffer range
(tp-search 1 100 'marker)
;; => ((5 10 t) (20 25 t) ...)

;; Find all 'type properties with value 'heading in string
(tp-search my-string 'type 'heading)
;; => ((0 10 heading) (50 60 heading) ...)

;; Filter by value
(tp-search 1 100 'type 'heading)

tp-search-do - Apply Function to All Matches

;; Buffer/string region
(tp-search-do FUNCTION START END PROPERTY &optional VALUE OBJECT)

;; Entire string
(tp-search-do FUNCTION STRING PROPERTY &optional VALUE)

Execute FUNCTION on all matches of PROPERTY in a buffer/string range or entire string.

  • FUNCTION receives two arguments: the match (list of START END VALUE) and OBJECT.
  • Returns the number of matches processed.

Examples:

;; Process all markers in buffer range
(tp-search-do
 (lambda (match obj)
   (message "Found at %d-%d with value %s"
            (car match) (cadr match) (caddr match)))
 1 100 'marker)

;; Process all headings in string
(tp-search-do
 (lambda (match obj)
   (upcase (substring obj (car match) (cadr match))))
 my-string 'type 'heading)

Query Functions

tp-intervals - Get Property Intervals

(tp-intervals START END &optional OBJECT)

Get all text property intervals in a region.


tp-empty-p - Check for Properties

(tp-empty-p &optional OBJECT)

Return t if OBJECT has no text properties.

  • OBJECT can be a string or buffer; nil defaults to current buffer.

Examples:

;; Check current buffer
(tp-empty-p)
(tp-empty-p nil)

;; Check specific string
(tp-empty-p "plain string")  ; => t
(tp-empty-p (propertize "styled" 'face 'bold))  ; => nil

;; Check specific buffer
(tp-empty-p my-buffer)

tp-plist - Get Merged Properties

;; Buffer/string region
(tp-plist START END &optional OBJECT)

;; Entire string
(tp-plist STRING)

Get a merged plist of all properties in a region or entire string.

Examples:

;; Get properties from buffer region
(tp-plist 1 10)

;; Get properties from string region
(tp-plist 0 5 my-string)

;; Get properties from entire string
(tp-plist my-string)

The Layer System

The layer system is tp.el's innovative feature that allows stacking multiple sets of properties on the same text region. Only the top layer is visible, but lower layers are preserved and can be revealed through rotation or pinning.

Layer Concept

┌─────────────────────────────┐
│   TOP LAYER (visible)       │  ← idx=0, What you see
├─────────────────────────────┤
│   Middle Layer (hidden)     │  ← idx=1, Preserved
├─────────────────────────────┤
│   Bottom Layer (hidden)     │  ← idx=-1, Preserved
└─────────────────────────────┘

Layer Definition

tp-define-layer - Define Layer(s)

Define a single layer or a group of multiple layers.

Single Layer:

(tp-define-layer layer-name
  (face (:background "cyan") line-prefix ">>"))

Multiple Layers (Layer Group):

(tp-define-layer my-group
  layer-1                                    ; Reference existing layer
  (face (:background "red") line-prefix ">>")    ; Anonymous layer
  (face (:background "green" :weight bold)))     ; Another anonymous layer

The first layer in the definition is the top layer (visible by default).

Examples:

;; Define individual layers
(tp-define-layer highlight
  (face (:background "yellow" :foreground "black")))

(tp-define-layer error
  (face (:background "red" :foreground "white")
   help-echo "Error!"))

(tp-define-layer info
  (face (:background "blue" :foreground "white")))

;; Define a layer group
(tp-define-layer status-colors
  highlight
  error
  info)

tp-layer-props / tp-group-props

(tp-layer-props LAYER-NAME)
(tp-group-props GROUP-NAME)

Get properties for a layer or all layers in a group.


tp-layer-undefine / tp-group-undefine

(tp-layer-undefine NAME)
(tp-group-undefine NAME)

Remove layer or group definition.


tp-layer-reset

(tp-layer-reset)

Clear all layer and group definitions.


Layer Placement

tp-put-layer - Set Layer at Index

;; Buffer/string region
(tp-put-layer START END LAYER IDX OBJECT)

;; Entire string
(tp-put-layer STRING LAYER IDX)

Set layer(s) at a specific index position in the layer stack.

  • IDX = 0: Top (visible layer)
  • IDX = -1: Bottom
  • Other values insert at that position

Examples:

(tp-define-layer base (face default))
(tp-define-layer highlight (face (:background "yellow")))

;; Put base layer at top
(tp-put-layer 1 10 'base 0)

;; Put highlight at index 1 (below top)
(tp-put-layer 1 10 'highlight 1)

;; Put layer at bottom
(tp-put-layer 1 10 'info -1)

tp-push-layer - Push Layer to Top

;; Buffer/string region
(tp-push-layer START END LAYER OBJECT)

;; Entire string
(tp-push-layer STRING LAYER)

Push a layer to the top of the stack (equivalent to tp-put-layer ... 0).

Examples:

(tp-define-layer base (face default))
(tp-define-layer highlight (face (:background "yellow")))

;; Push base layer first
(tp-push-layer 1 10 'base)

;; Push highlight on top (now visible)
(tp-push-layer 1 10 'highlight)

Layer Deletion

tp-delete-layer - Delete Layer by Name/Index

;; Buffer/string region
(tp-delete-layer START END LAYER-NAME/IDX OBJECT)

;; Entire string
(tp-delete-layer STRING LAYER-NAME/IDX)

Delete a layer from anywhere in the stack by name or index.

Examples:

;; Remove by name
(tp-delete-layer 1 10 'highlight)

;; Remove top layer (idx=0)
(tp-delete-layer 1 10 0)

;; Remove bottom layer
(tp-delete-layer 1 10 -1)

tp-pop-layer - Pop Top Layer

;; Buffer/string region
(tp-pop-layer START END OBJECT)

;; Entire string
(tp-pop-layer STRING)

Remove the top layer (equivalent to tp-delete-layer ... 0).


Layer Movement

tp-raise-layer - Move Layer Up/Down

;; Buffer/string region
(tp-raise-layer START END IDX/LAYER-NAME N OBJECT)

;; Entire string
(tp-raise-layer STRING IDX/LAYER-NAME N)

Raise a layer by N positions. Positive N moves toward top, negative moves toward bottom.

Examples:

;; Move layer1 up by 2 positions
(tp-raise-layer 1 10 'layer1 2)

;; Move layer at idx 2 down by 1 position
(tp-raise-layer 1 10 2 -1)

tp-rotate-layer - Cycle Layers

;; Buffer/string region
(tp-rotate-layer START END OBJECT)

;; Entire string
(tp-rotate-layer STRING)

Rotate layers - top goes to bottom, next becomes visible.

Examples:

;; Stack: highlight (top) -> base (bottom)
(tp-rotate-layer 1 10)
;; Stack: base (top) -> highlight (bottom)

tp-pin-layer - Pin Layer to Top

;; Buffer/string region
(tp-pin-layer START END IDX/LAYER-NAME OBJECT)

;; Entire string
(tp-pin-layer STRING IDX/LAYER-NAME)

Move a specific layer to the top (make it visible).

Examples:

;; Make 'base the top layer
(tp-pin-layer 1 10 'base)

tp-switch-layer - Switch Two Layers

;; Buffer/string region
(tp-switch-layer START END IDX1/NAME1 IDX2/NAME2 OBJECT)

;; Entire string
(tp-switch-layer STRING IDX1/NAME1 IDX2/NAME2)

Swap positions of two layers.

Examples:

;; Switch layer1 and layer2
(tp-switch-layer 1 10 'layer1 'layer2)

Layer Merging

tp-merge-layers - Merge Multiple Layers

;; Buffer/string region
(tp-merge-layers START END NEW-LAYER-NAME '(IDX1 LAYER-NAME1 IDX2 ...) OBJECT)

;; Entire string
(tp-merge-layers STRING NEW-LAYER-NAME '(IDX1 LAYER-NAME1 IDX2 ...))

Merge specified layers into a new layer. Earlier layers in the list take precedence.

Examples:

;; Merge layer1 and layer2 into merged-layer
(tp-merge-layers 1 10 'merged-layer '(layer1 layer2))

;; Merge by index
(tp-merge-layers 1 10 'merged '(0 1 2))

tp-flatten-layers - Flatten All Layers

;; Buffer/string region
(tp-flatten-layers START END NAME OBJECT)

;; Entire string
(tp-flatten-layers STRING NAME)

Flatten all layers into a single layer with the given name.

Examples:

;; Flatten all layers into 'flat-layer
(tp-flatten-layers 1 10 'flat-layer)

;; Flatten with nil name (unnamed layer)
(tp-flatten-layers 1 10 nil)

Layer Query Functions

tp-layer-list - List All Layers

(tp-layer-list START END &optional OBJECT)

Get list of all layer names in region.

Examples:

(tp-layer-list 1 10)  ; => (highlight base)

tp-layer-count

(tp-layer-count START END &optional OBJECT)

Count layers in region.


tp-layer-exists-p

(tp-layer-exists-p START END NAME &optional OBJECT)

Check if layer exists in region.


tp-layer-top

(tp-layer-top START END &optional OBJECT)

Get name of the top (visible) layer.


Practical Examples

Syntax Highlighting with Multiple Layers

;; Define layers for different highlighting purposes
(tp-define-layer code-base
  (face font-lock-keyword-face))

(tp-define-layer code-error
  (face (:underline (:color "red" :style wave))
   help-echo "Syntax error"))

(tp-define-layer code-debug
  (face (:background "dark blue")))

;; Apply base highlighting
(tp-push-layer 1 100 'code-base)

;; Add error highlight on problematic code
(tp-push-layer 50 60 'code-error)

;; Toggle between error and normal view
(defun toggle-error-view ()
  (interactive)
  (tp-rotate-layer 50 60))

Status Indicator

;; Define status layers as a group
(tp-define-layer status-todo (face (:foreground "gray")))
(tp-define-layer status-progress (face (:foreground "yellow")))
(tp-define-layer status-done (face (:foreground "green")))
(tp-define-layer task-status status-todo status-progress status-done)

;; Cycle through statuses
(defun cycle-task-status ()
  (interactive)
  (tp-rotate-layer (line-beginning-position) (line-end-position)))

Temporary Highlights

(tp-define-layer temp-highlight
  (face (:background "yellow")))

(defun flash-region (start end)
  "Flash a region temporarily."
  (tp-push-layer start end 'temp-highlight)
  (run-with-timer 0.5 nil
                  (lambda ()
                    (tp-delete-layer start end 'temp-highlight))))

Aliases

For convenience, tp.el provides these aliases:

Alias Original Function
tp-layer-properties tp-layer-props
tp-layer-group-properties tp-group-props
tp-layer-group-undefine tp-group-undefine

License

GNU General Public License v2 or later.


Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.


tp.el - Making text properties powerful and easy to use