Skip to content

Use zero-width delimiters for role tracking in gptel-mode #565

Open
@lispy-ai

Description

@lispy-ai

Title: Use zero-width delimiters for role tracking with overlay-based highlighting in gptel-mode buffers

This is a proposal for a new approach to tracking and visually distinguishing assistant/user roles in gptel buffers that addresses several long-standing issues (#321, #343) while maintaining compatibility with the existing system.

The Problem

Currently gptel uses text properties to track which sections of text are assistant responses. This approach has proven problematic because:

  1. Text properties don't interact naturally with standard Emacs editing operations
  2. Property stickiness creates ambiguous cases during editing
  3. Yanked text carries properties that can cause confusion
  4. Visual feedback about roles is difficult to implement reliably

Proposed Solution

Use zero-width Unicode characters as role delimiters with overlay-based highlighting, but only when gptel-mode is active:

  • U+200B (zero-width space) marks response start
  • U+200C (zero-width non-joiner) marks response end
  • Overlays provide visual distinction for responses

Key aspects:

  • Delimiters are invisible and don't affect buffer display
  • Standard editing operations work naturally
  • Cut/paste preserves role boundaries correctly
  • Overlays provide clean visual feedback
  • Works with all major modes

Implementation

The solution uses two phases:

  1. When gptel-mode is enabled:

    • Convert existing gptel text properties to delimiter pairs
    • Remove gptel properties
    • Enable delimiter-based role tracking
    • Create overlays for responses
  2. When gptel-mode is disabled:

    • Convert delimiters back to gptel properties
    • Remove delimiters
    • Remove overlays
    • Restore property-based tracking

Response Highlighting

Use overlays for visual distinction:

  • Clean visual distinction
  • No interference with text properties
  • Preserves other modes' fontification
  • Easy to customize appearance

Benefits

  1. Reliable editing operations:

    • Cut/paste works naturally
    • Undo/redo maintains role boundaries
    • No property stickiness issues
  2. Better user experience:

    • Clear visual distinction of responses
    • Predictable editing behaviour
    • Compatible with standard Emacs commands
    • Non-intrusive highlighting
  3. Technical improvements:

    • Simple to parse conversation history
    • Clean visual feedback via overlays
    • Works with all major modes
    • Separation of tracking and display

Testing

To test this change:

  1. Enable gptel-mode in a buffer with existing responses
  2. Verify properties convert to delimiters correctly
  3. Test editing operations (especially cut/paste)
  4. Verify overlay highlighting
  5. Disable mode and verify cleanup
  6. Check property restoration

Notes

  • Only affects buffers with gptel-mode active
  • Zero-width characters don't affect buffer display or export
  • Maintains compatibility with existing gptel features
  • Solves long-standing editing issues
  • Provides clean visual distinction via overlays

Caveat

There is an obvious caveat here. Enabling the mode mutates the buffer. The characters I have chosen are highly unlikely to appear in regular text. One solution might be that instead of predefining two characters, allow these characters to be configurable via buffer local variables or customisation, or have them automatically selected from a set of candidate characters which characters do not appear in the buffer when scanned upon entering gptel-mode.

Related issues: #321, #343

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions