Description
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:
- Text properties don't interact naturally with standard Emacs editing operations
- Property stickiness creates ambiguous cases during editing
- Yanked text carries properties that can cause confusion
- 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:
-
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
-
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
-
Reliable editing operations:
- Cut/paste works naturally
- Undo/redo maintains role boundaries
- No property stickiness issues
-
Better user experience:
- Clear visual distinction of responses
- Predictable editing behaviour
- Compatible with standard Emacs commands
- Non-intrusive highlighting
-
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:
- Enable gptel-mode in a buffer with existing responses
- Verify properties convert to delimiters correctly
- Test editing operations (especially cut/paste)
- Verify overlay highlighting
- Disable mode and verify cleanup
- 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.