3

Since there is a chance that this is another XY problem I'll provide a context as to how I arrived at the problem in the first place.

I'm writing a package that let the user highlight any text with their selected color and also add fringe with the same color as the highlight on the right of the window. Here are all the simplified version of what I'd tried to achieve. Try evaluating all these and call my/highlight-this-region on any text (doesn't work in terminal also, disabling font-lock helps if you can't see the highlight.)

This is the bitmap for the fringe, (it looks like a solid vertical bar)

(define-fringe-bitmap 'my/highlight-fringe-bitmap
  [#b11000000
   #b11000000
   #b11000000
   #b11000000
   #b11000000
   #b11000000
   #b11000000
   #b11000000]
  nil nil '(center t))

This is the command that prompts user for color, then add text properties based on it,

(defun my/highlight-this-region (region-beg region-end)
  "Highlight the current active region with user selected color."
  (interactive"r")
  (let ((color (read-color "Color for highlight: ")))
    (add-text-properties region-beg region-end (my/build-highlight-plist color))))

This helps the previous command to build an appropriate property list based on color.

(defun my/build-highlight-plist (highlight-color)
  "Build a property list for my highlighted region with fringe the same color."
  ;; fringe-text is a dummy text for our display property
  (let ((fringe-text (my/propertize-fringe-text highlight-color)))
    ;; Assign an anonymous face
    (list 'face (list :background highlight-color)
      'line-prefix fringe-text
      'wrap-prefix fringe-text)))

Read more on line-prefix, wrap prefix at

Here lies the problem, the display property's spec. At this stage, the fringe-color will be a string of a name of user selected color (like "red", "spring green", "lime green", "gold4", etc.) Calling list-colors-display on Emacs gives you all the possible names.

(defun my/propertize-fringe-text (fringe-color)
  (propertize "x" 'display (list 'right-fringe 'my/highlight-fringe-bitmap fringe-color)))

Here's the documentation for the spec (right-fringe)

(left-fringe BITMAP [FACE])
(right-fringe BITMAP [FACE])
     This display specification on any character of a line of text
     causes the specified BITMAP be displayed in the left or right
     fringes for that line, instead of the characters that have the
     display specification.  The optional FACE specifies the face whose
     colors are to be used for the bitmap display. See Fringe
     Bitmaps, for the details.

so 'my/highlight-fringe-bitmap I've defined earlier will be the BITMAP no problems here, the fringe-color will be used as FACE, let's see the result of this on a sample text.

[1]

So the highlighting is functional, the fringe is all white this means that fringe-color doesn't work.

Here is what I've tried: Make fringe-color be an anonymous face,

(defun my/propertize-fringe-text (fringe-color)
  (propertize "x" 'display (list 'right-fringe 'my/highlight-fringe-bitmap
                 (list 'face
                       :foreground fringe-color
                       :background fringe-color))))

The fringe is still all white. After some research I discovered that the FACE argument has to be a defined face accordingly to the answer at Change the color of the wrap around arrow So I define a new dummy face to the code,

(defface my/highlight-fringe nil
  "A face used for displaying fringe in with `my/highlight-this-region'.

The actual styling of the face is done by `my/propertize-fringe-text'")

and I redefine the new function,

(defun my/propertize-fringe-text (fringe-color)
     (set-face-foreground 'my/highlight-fringe fringe-color) ; Styling the dummy fringe.
     (propertize "x" 'display (list 'right-fringe 'my/highlight-fringe-bitmap 'my/highlight-fringe)))

This works! But all the fringes will change to the same color of the current highlight which defeats the whole purpose of my package.

The surefire way to to deal with the fringes is defining new faces for every possible color names, this is extremely undesirable.

Q:How can I assign multiple faces for fringes?

Drew
  • 75,699
  • 9
  • 109
  • 225
C11g
  • 333
  • 1
  • 7

0 Answers0