5

How can I change the color of the fill-column-indicator and have the changes visible immediately?

(defun my:change-fci-color (color)
  (setq fci-rule-color color)
  (fci-redraw-frame))

The previous code doesn't change the color in existing buffers until the major mode is changed or I reload the buffer.

The following code works but feels like a gross hack.

(with-current-buffer "fill-column-indicator.el"
  (when fci-mode
    (turn-off-fci-mode)
    (turn-on-fci-mode)))

Ultimately, I want to change fci-rule-color based on the current theme's background color. So, when I change from a light theme to a dark theme, fci-rule-color remains a subtle shade off of the background color.

2
  • Since after collecting karma points one gets some mod's privileges, I can see you wanted to edit lawlist's answer. Why not post it as a separate answer instead of editing the existing one?
    – wvxvw
    Oct 8, 2016 at 14:34
  • I didn't know it was a better option. I've moved my edits to a separate answer.
    – Joe
    Oct 9, 2016 at 17:53

3 Answers 3

4

The following three lines of code in this specific order will immediately visibly update the fci-rule-color -- in this example, I am using the color "red".

(setq fci-rule-color "red")
(fci-make-overlay-strings)
(fci-update-all-windows t)
3
  • After a little bit more experimentation, this doesn't work for buffers that aren't visible when the code is run. I fell back to the turn-on, turn-off hack.
    – Joe
    Oct 6, 2016 at 5:36
  • In addition to the window-list, you can loop through all buffers and operate on the ones where fci-mode is active. You would need to look at fci-upate-all-windows to see what makes it tick. You may wish to consider posting an alternative answer, or edit your question to contain a custom solution (e.g., underneath the question), rather than substantially modifying my own answer. My schedule is booked today and tomorrow, but if you need additional help, just let me know and I'll be able to lend a hand over the next few days as time permits.
    – lawlist
    Oct 6, 2016 at 15:33
  • Thank you for the tip. I made an alternate answer so the proposed edit can get rejected.
    – Joe
    Oct 9, 2016 at 17:54
3

Here's the complete end-to-end solution I ended up with based on lawlist's answer.

(defun my:color-is-closer-to-white-p (color)
  "Returns t if COLOR is closer to white than black."
  (< (color-distance color "white") (color-distance color "black")))

(defun my:get-subtle-color-from-background (percent-difference)
  "Gets a shade PERCENT-DIFFERENCE from the current background color.
If the color is closer to white, multiply percent-difference by 2
so it's easier to see."
  (let* ((current-background-color (face-background 'default)))
    (if (my:color-is-closer-to-white-p current-background-color)
        (color-darken-name current-background-color (* 2 percent-difference))
      (color-lighten-name current-background-color percent-difference))))

(defun my:change-fci-color (&rest args)
  "Change the fill-column-indicator based on the background.
ARGS is only used because we use this function as advice after
`load-theme'."
  (setq fci-rule-color (my:get-subtle-color-from-background 10))
  (let* ((wins (window-list (selected-frame) 'no-minibuf))
        (bufs (delete-dups (mapcar #'window-buffer wins))))
    (dolist (buf bufs)
      (with-current-buffer buf
        (when fci-mode
          (fci-make-overlay-strings)
          (fci-update-all-windows t))))))

(advice-add 'load-theme :after 'my:change-fci-color)
2

I was looking for an example of setting fill-column-indicator font color in Emacs 27.1, and this page keeps coming up. As I eventually worked out what I needed I'm posting the answer here.

(set-face-foreground 'fill-column-indicator "salmon")

See (info "(emacs) Displaying Boundaries") for more information on the built-in display-fill-column-indicator-mode.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.