Skip to content

Commit 1f64506

Browse files
committed
Improve overlay highlight
1 parent c60d30c commit 1f64506

File tree

1 file changed

+58
-4
lines changed

1 file changed

+58
-4
lines changed

eca-rewrite.el

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
:type 'hook
4646
:group 'eca)
4747

48-
(defface eca-rewrite-highlight-face
48+
(defface eca-rewrite-overlay-face
4949
'((((class color) (min-colors 88) (background dark))
5050
:background "#041117" :extend t)
5151
(((class color) (min-colors 88) (background light))
@@ -54,6 +54,11 @@
5454
"Face to highlight pending rewrite regions."
5555
:group 'eca)
5656

57+
(defface eca-rewrite-overlay-hover-face
58+
'((t (:inherit eca-rewrite-overlay-face :weight semi-bold)))
59+
"Face used for rewrite overlay content when point is inside it."
60+
:group 'eca)
61+
5762
(defface eca-rewrite-in-progress-prefix-face
5863
'((t (:inherit shadow)))
5964
"Face to show in the in progress prefix text."
@@ -79,6 +84,9 @@
7984
(defvar-local eca-rewrite--overlays nil
8085
"Active rewrite overlays in this buffer.")
8186

87+
(defvar-local eca-rewrite--hovered-ov nil
88+
"Currently hovered rewrite overlay (point inside), or nil.")
89+
8290
(defvar-keymap eca-rewrite-actions-map
8391
:doc "Keymap for rewrite overlay actions."
8492
"a" #'eca-rewrite-accept
@@ -121,6 +129,41 @@ LABEL is the base text prefix."
121129
(propertize " " 'display `(space :align-to (- right ,(1+ (length model-str)))))
122130
(propertize model-str 'face 'eca-rewrite-model-face))))
123131

132+
(defun eca-rewrite--apply-display-face (ov face)
133+
"Apply FACE to OV's display string, preserving syntax faces.
134+
If the overlay is currently hidden (no display), do nothing."
135+
(when (and (overlay-get ov 'display)
136+
(overlay-get ov 'eca-rewrite--display-base))
137+
(let* ((base (overlay-get ov 'eca-rewrite--display-base))
138+
(disp (copy-sequence base)))
139+
(add-face-text-property 0 (length disp) face 'append disp)
140+
(overlay-put ov 'display disp))))
141+
142+
(defun eca-rewrite--apply-normal-face (ov)
143+
"Restore normal highlight face to OV."
144+
(if (overlay-get ov 'eca-rewrite--display-base)
145+
(eca-rewrite--apply-display-face ov 'eca-rewrite-overlay-face)
146+
(overlay-put ov 'face 'eca-rewrite-overlay-face)))
147+
148+
(defun eca-rewrite--apply-hover-face (ov)
149+
"Apply hover face to OV."
150+
(if (overlay-get ov 'eca-rewrite--display-base)
151+
(eca-rewrite--apply-display-face ov 'eca-rewrite-overlay-hover-face)
152+
(overlay-put ov 'face 'eca-rewrite-overlay-hover-face)))
153+
154+
(defun eca-rewrite--hover-update ()
155+
"Update hover styling based on point location."
156+
(let ((current-ov (eca-rewrite--overlay-at-point)))
157+
(unless (eq current-ov eca-rewrite--hovered-ov)
158+
;; Remove hover face from previous overlay
159+
(when (overlayp eca-rewrite--hovered-ov)
160+
(eca-rewrite--apply-normal-face eca-rewrite--hovered-ov))
161+
;; Update hovered overlay reference
162+
(setq eca-rewrite--hovered-ov current-ov)
163+
;; Apply hover face to the new overlay, if present
164+
(when (overlayp current-ov)
165+
(eca-rewrite--apply-hover-face current-ov)))))
166+
124167
(defun eca-rewrite--setup-overlay (id start end text path prompt model)
125168
"Create an overlay for ID from START to END.
126169
TEXT is the original selected text
@@ -138,14 +181,15 @@ MODEL is the LLM model used."
138181
(overlay-put ov 'eca-rewrite--path path)
139182
(overlay-put ov 'eca-rewrite--prompt prompt)
140183
(overlay-put ov 'eca-rewrite--model model)
141-
(overlay-put ov 'face 'eca-rewrite-highlight-face)
184+
(overlay-put ov 'face 'eca-rewrite-overlay-face)
142185
(overlay-put ov 'priority 2000)
143186
(overlay-put ov 'keymap eca-rewrite-actions-map)
144187
(overlay-put ov 'help-echo "ECA rewrite")
145188
(overlay-put ov 'before-string (eca-rewrite--overlay-menu-str
146189
ov
147190
(propertize "Requesting LLM..." 'face 'eca-rewrite-in-progress-prefix-face)))
148191
(push ov eca-rewrite--overlays)
192+
(add-hook 'post-command-hook #'eca-rewrite--hover-update nil t)
149193
ov))
150194

151195
(defun eca-rewrite--show-overlay-actions (ov)
@@ -173,7 +217,12 @@ overlay, remove it from the internal tracking list
173217
No confirmation is asked; a nil OVS is ignored. Returns nil."
174218
(dolist (ov (ensure-list ovs))
175219
(setq eca-rewrite--overlays (delq ov eca-rewrite--overlays))
176-
(delete-overlay ov)))
220+
(when (eq ov eca-rewrite--hovered-ov)
221+
(setq eca-rewrite--hovered-ov nil))
222+
(delete-overlay ov))
223+
(when (null eca-rewrite--overlays)
224+
(remove-hook 'post-command-hook #'eca-rewrite--hover-update t)
225+
(setq eca-rewrite--hovered-ov nil)))
177226

178227
(defun eca-rewrite--accept (ov)
179228
"Accept rewrite overlay OV."
@@ -367,7 +416,12 @@ so shorter rewrites don't leave leftover original text in the overlay."
367416
;; Move the highlight to the display string so show-paren-mode
368417
;; overlays on buffer text don't repaint the whole overlay.
369418
(let ((disp (copy-sequence propertized)))
370-
(overlay-put ov 'display disp))))))
419+
;; Keep a base version (syntax faces only) to compose with our faces.
420+
(overlay-put ov 'eca-rewrite--display-base disp)
421+
;; Initial (non-hover) display uses the normal highlight face.
422+
(let ((initial (copy-sequence disp)))
423+
(add-face-text-property 0 (length initial) 'eca-rewrite-overlay-face 'append initial)
424+
(overlay-put ov 'display initial)))))))
371425

372426
;; Public
373427

0 commit comments

Comments
 (0)