+ ;; Our overlay is very temporary, so we take the liberty of giving
+ ;; it a high priority.
+ (overlay-put ov 'priority beacon-overlay-priority)
+ (overlay-put ov 'window (selected-window))
+ (while properties
+ (overlay-put ov (pop properties) (pop properties)))
+ (push ov beacon--ovs)
+ ov))
+
+(defun beacon--colored-overlay (color)
+ "Put an overlay at point with background COLOR."
+ (beacon--make-overlay 1 'face (list :background color)))
+
+(defun beacon--ov-put-after-string (overlay colors)
+ "Add an after-string property to OVERLAY.
+The property's value is a string of spaces with background
+COLORS applied to each one.
+If COLORS is nil, OVERLAY is deleted!"
+ (if (not colors)
+ (when (overlayp overlay)
+ (delete-overlay overlay))
+ (overlay-put overlay 'beacon-colors colors)
+ (overlay-put overlay 'after-string
+ (propertize
+ (mapconcat (lambda (c) (propertize " " 'face (list :background c)))
+ colors
+ "")
+ 'cursor 1000))))
+
+(defun beacon--after-string-overlay (colors)
+ "Put an overlay at point with an after-string property.
+The property's value is a string of spaces with background
+COLORS applied to each one."
+ ;; The after-string must not be longer than the remaining columns
+ ;; from point to right window-end else it will be wrapped around.
+ (let ((colors (seq-take colors (- (window-width) (current-column)))))
+ (beacon--ov-put-after-string (beacon--make-overlay 0) colors)))