Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions svg-margin.el
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@ Its `:text', else the character mapped for its `:shape' in
(defun svg-margin--text-face (ind &optional background)
"Return the face for IND's glyph in `text' mode: its colour, plus BACKGROUND.
Uses IND's `:face' as-is, or an anonymous face from its `:color'; BACKGROUND,
when non-nil, is a colour drawn behind the glyph (the hover highlight).
when non-nil, is a colour drawn behind the glyph (hover highlight, a background
tint, or the neutral cell background).
`:font', `:weight' and `:scale' are honoured only by the `svg' renderer."
(let* ((color (plist-get ind :color))
(base (cond (color (list :foreground color))
Expand All @@ -456,11 +457,18 @@ The string spans RCOLS columns, each `svg-margin-column-width' characters wide;
column 0 is nearest the buffer text. Each occupied cell shows its indicator's
glyph (see `svg-margin--cell-glyph') faced with its colour and tagged -- via a
`svg-margin-cell' help-echo property (BUFFER POS SIDE COLUMN) -- so hover
tracking and per-cell tooltips work; empty cells are spaces. A `:background'
indicator tints the whole string's background. HOVERED-COL, when it is a
cell's column, draws the hover background behind that cell."
tracking and per-cell tooltips work; empty cells are spaces. Every cell paints
an explicit `svg-margin-cell' background so a transient highlight on the
underlying line (show-paren, region, hl-line) does not bleed through the margin;
a `:background' indicator tints the cells instead, and HOVERED-COL draws the
hover background behind its cell."
(let ((w (max 1 svg-margin-column-width))
(bg nil)
;; The margin cell's own background, painted behind every cell so a
;; transient highlight on the underlying line (show-paren, region,
;; hl-line) cannot bleed through an empty or glyph-only cell.
(defbg (let ((c (face-attribute 'svg-margin-cell :background nil t)))
(and (stringp c) c)))
Comment on lines +467 to +471
(cells (make-vector rcols nil))
(parts nil))
(dolist (cell packed)
Expand All @@ -476,8 +484,11 @@ cell's column, draws the hover background behind that cell."
(ind (and cell (plist-get cell :indicator)))
(glyph (if ind (svg-margin--cell-glyph ind) " "))
(hov (and hovered-col (eql col hovered-col) (svg-margin--hover-color)))
(face (if ind (svg-margin--text-face ind hov)
(and hov (list :background hov))))
;; Hover wins, then a background-indicator tint, then the neutral
;; cell background -- so every cell paints an explicit background.
(cellbg (or hov bg defbg))
(face (if ind (svg-margin--text-face ind cellbg)
(and cellbg (list :background cellbg))))
(pad (max 0 (- w (string-width glyph))))
(s (concat glyph (make-string pad ?\s))))
(when face (setq s (propertize s 'face face)))
Expand All @@ -493,10 +504,7 @@ cell's column, draws the hover background behind that cell."
(when (or (plist-get ind :action) (plist-get ind :menu))
(setq s (propertize s 'pointer 'hand)))))
(push s parts)))
(let ((str (apply #'concat (nreverse parts))))
(when bg
(add-face-text-property 0 (length str) (list :background bg) t str))
str)))
(apply #'concat (nreverse parts))))

;;;; Overlays
;; ----------------------------------------------------------------
Expand Down
24 changes: 24 additions & 0 deletions test/svg-margin-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,30 @@
(should (equal "•" (svg-margin--text-margin '((:indicator (:color "#fff") :column 0))
'left 1 1 nil)))))

(ert-deftest svg-margin/text-margin-cell-background ()
"Every text cell paints an explicit background so a highlight on the
underlying line (show-paren, region, hl-line) cannot bleed through the margin.
The neutral background is `svg-margin-cell's; a `:background' indicator tints it."
(let ((svg-margin-column-width 1)
(orig (face-attribute 'svg-margin-cell :background nil nil)))
(unwind-protect
(progn
(set-face-attribute 'svg-margin-cell nil :background "#010203")
;; No tint: empty and glyph cells both carry the neutral cell bg.
(let* ((packed '((:indicator (:color "#ff0000" :text "A") :column 0)))
(str (svg-margin--text-margin packed 'left 2 1 nil))
(empty (get-text-property 0 'face str)) ; leftmost = empty lane 1
(glyph (get-text-property (1- (length str)) 'face str))) ; last = glyph lane 0
(should (equal '(:background "#010203") empty))
(should (member '(:background "#010203") glyph))
(should (member '(:foreground "#ff0000") glyph)))
;; A `:background' indicator tints every cell, overriding the neutral bg.
(let* ((packed '((:indicator (:color "#00ff00"))
(:indicator (:text "A") :column 0)))
(str (svg-margin--text-margin packed 'left 2 1 nil)))
(should (equal '(:background "#00ff00") (get-text-property 0 'face str)))))
(set-face-attribute 'svg-margin-cell nil :background orig))))

(ert-deftest svg-margin/renderer-usable-p ()
"The `text' renderer is usable on any frame; `svg' needs a graphical one.
Runs in batch, where `display-graphic-p' is nil (like a terminal)."
Expand Down
Loading