0

I use this code (found here) to highlight a single line in black:

(defun find-overlays-specifying (prop pos)
  (let ((overlays (overlays-at pos))
        found)
    (while overlays
      (let ((overlay (car overlays)))
        (if (overlay-get overlay prop)
            (setq found (cons overlay found))))
      (setq overlays (cdr overlays)))
    found))

(defun highlight-or-dehighlight-line ()
  (if (find-overlays-specifying
       'line-highlight-overlay-marker
       (line-beginning-position))
      (remove-overlays (line-beginning-position) (+ 1 (line-end-position)))
    (let ((overlay-highlight (make-overlay
                              (line-beginning-position)
                              (+ 1 (line-end-position)))))
        (overlay-put overlay-highlight 'face '(:background "black"))
        (overlay-put overlay-highlight 'line-highlight-overlay-marker t))))

(global-set-key [f9] (lambda () (interactive) (highlight-or-dehighlight-line)))

Now I want to make it more generic because I want to be able to use a few different colors. So I added a parameter color to function highlight-or-dehighlight-line, replaced "black" with color, and passed "black" to highlight-or-dehighlight-line:

(defun find-overlays-specifying (prop pos)
  (let ((overlays (overlays-at pos))
        found)
    (while overlays
      (let ((overlay (car overlays)))
        (if (overlay-get overlay prop)
            (setq found (cons overlay found))))
      (setq overlays (cdr overlays)))
    found))

(defun highlight-or-dehighlight-line (color)
  (if (find-overlays-specifying
       'line-highlight-overlay-marker
       (line-beginning-position))
      (remove-overlays (line-beginning-position) (+ 1 (line-end-position)))
    (let ((overlay-highlight (make-overlay
                              (line-beginning-position)
                              (+ 1 (line-end-position)))))
        (overlay-put overlay-highlight 'face '(:background color))
        (overlay-put overlay-highlight 'line-highlight-overlay-marker t))))

(global-set-key [f9] (lambda () (interactive) (highlight-or-dehighlight-line "black")))

However, this does not seem to do anything and I cannot find my mistake. What's wrong with this code?

Drew
  • 75,699
  • 9
  • 109
  • 225
UTF-8
  • 885
  • 6
  • 22
  • https://emacs.stackexchange.com/tags/elisp/info – Drew Dec 02 '21 at 18:04
  • 2
    Does this answer your question? [How to evaluate the variables before adding them to a list?](https://emacs.stackexchange.com/questions/7481/how-to-evaluate-the-variables-before-adding-them-to-a-list) – Drew Dec 02 '21 at 18:06

1 Answers1

2

The mistake is here: '(:background color). This is quoted, so it is simply treated literally. The result is a list containing two elements, the keyword :background and the symbol color. One solution is to use a backquote, or quasi–quote, so that you can interpolate values into the list:

`(:background ,color)

Another solution is to call a function instead, since the arguments to the function will be evaluated:

(list :background color)

The first is more idiomatic, but both will get you a list containing the keyword :background followed by the value assigned to the variable named color, rather than the literal symbol color.

See chapter 10.4 Backquote in the Emacs Lisp manual. You can open the Info viewer inside of Emacs to read this manual with C-h i.

db48x
  • 15,741
  • 1
  • 19
  • 23