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.

Joe
  • 1,312
  • 1
  • 8
  • 19
  • 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 08 '16 at 14:34
  • I didn't know it was a better option. I've moved my edits to a separate answer. – Joe Oct 09 '16 at 17:53

3 Answers3

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)
lawlist
  • 18,826
  • 5
  • 37
  • 118
  • 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 06 '16 at 05: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 06 '16 at 15:33
  • Thank you for the tip. I made an alternate answer so the proposed edit can get rejected. – Joe Oct 09 '16 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)
Joe
  • 1,312
  • 1
  • 8
  • 19
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.

Basil
  • 12,019
  • 43
  • 69
alls0rts
  • 346
  • 3
  • 9