Solaire changes buffer-face-mode-face
trbjo opened this issue · 6 comments
I use two different fonts – one for org-mode and one for everything else. I believe the relevant part of my .emacs looks like this:
(set-face-attribute 'default nil :font "Fantasque Sans Mono-11")
(add-hook 'org-mode-hook (lambda () (setq buffer-face-mode-face '(:family "Roboto")) (buffer-face-mode)))
Now, everytime I first open an org-mode file and then switch to e.g. a source code file, the source code file is now set with the Roboto font.
If I open the source code file first, however, the text is shown with Fantasque Sans Mono as it should.
I've tried playing around with the suggested lines to put in .emacs, and the culprit is this:
(add-hook 'after-change-major-mode-hook #'turn-on-solaire-mode)
If I comment it out, the faces change just fine, but it renders solaire-mode unusable.
I've tried using a different "definition" than buffer-face-mode-face, namely variable-pitch instead, and it's the same result. (I'm sorry if this sentence is non-sensical to you, my elisp is abysmally bad).
What to do?
The problem is that buffer-face-mode
and solaire-mode
both try to remap the default
face, and only one can succeed, without some face-remapping voodoo.
Give this a try:
(add-hook 'org-mode-hook
(lambda () (face-remap-add-relative 'solaire-default-face :family "Roboto")))
This is definitely better than before. Thank you!
The problem with the fonts is solved. The only thing solaire interferes with now is the background of the initial (scratch) buffer and the echo-area/minibuffer-prompt area below the modeline in the bottom of the frame. I've been unable to set it playing around with the different options you mention in the readme.
This is what I mean (I usually have no mode line in org-mode):
Do you know if there is a way to change the color depending on whether the mode-line is shown/hidden?
The scratch buffer isn't considered a "real" buffer by solaire-mode, hence its background. i.e. "Real" buffers get highlighted. The default heuristic for what makes a buffer real is if buffer-file-name
is non-nil (i.e. if it's a file-visiting buffer).
You can change this by setting solaire-mode-real-buffer-fn
to a function that returns t
for the scratch buffer. Something like:
(defun real-buffer-p (buffer)
(or (solaire-mode--real-buffer-fn buffer) ; is BUFFER a file visiting buffer?
(string= (buffer-name buffer) "*scratch*")))
(setq solaire-mode-real-buffer-fn #'real-buffer-p)
There is no solution for the echo-area, however, because there's no way to give the whole minibuffer a (permanent) buffer-local background. This is a limitation of Emacs, unfortunately. The closest you'll get is (add-hook 'minibuffer-setup-hook #'solaire-mode-in-minibuffer)
, which gives it a background only while it's active.
Alternatively, you could change solaire-mode-real-buffer-fn
to return nil for org buffers (or buffers where mode-line-format
is nil), then they'll share the same background as the echo-area.
I'll assume I've answered your question and can close this issue. Feel free to reopen this otherwise!
@hlissner Thank you for answering this question. I've long done a similar thing, using this in my org-mode-hook
:
(buffer-face-set :family (face-attribute 'variable-pitch :family))
Then when I tried solaire-mode
, I noticed that all of my source code buffers were using variable pitch, and I couldn't find any apparent reason, even when checking every face that was applied to some text.
Thankfully I found this issue. So I replaced that code with:
(face-remap-add-relative 'default :inherit 'variable-pitch)
And after restarting Emacs, it seems to have fixed the problem, and I still get variable pitch in Org buffers!
BTW, I don't understand exactly how buffer-face-mode
and face-remap
work and how they differ. Could you explain it simply, if it's possible? :) If you can, I'll add it to https://github.com/alphapapa/emacs-package-dev-handbook for future reference.
Apparently I spoke too soon, as after restarting Emacs again, the problem returns. That is:
- I start Emacs with this code in my
org-mode-hook
:
(face-remap-add-relative 'default :inherit 'variable-pitch)
- Load an Org file. It's in variable pitch.
- Load an elisp file. It's in monospace.
- Load solaire with this code:
(use-package solaire-mode
:hook
((change-major-mode after-revert ediff-prepare-buffer) . turn-on-solaire-mode)
(minibuffer-setup . solaire-mode-in-minibuffer))
- Load another Org file.
- Load another elisp file. It's in variable pitch!
Trying to follow @hlissner's example, I added this to my `org-mode-hook' before the code in step 1:
(face-remap-add-relative 'solaire-default-face :family (face-attribute 'default :family))
But that didn't make any difference.
I guess either I'm doing something wrong, or solaire isn't compatible with any other code that does face remapping...?