Reputation: 9466
I am trying to set my font for emacsclient like so:
(let ((default-font (cond
((member "Inconsolata" (font-family-list))
"Inconsolata 14")
(t
"monospace 20"))))
(set-default-font default-font)
(add-to-list 'default-frame-alist `(font . ,default-font)))
I C-x C-e
at the cond
sexp and it returns "Inconsolata 14"
. I C-x C-e
at the let
sexp and the font is updated.
When I launch emacs via
$ emacs
it works (the font is set to Inconsolata 14).
However when I launch the application via
$ emacsclient --alternate-editor="" --create-frame "$@"
the font is monospace 20 instead.
Please advise.
EDIT:
I have discovered that by including
(message "%s" (font-family-list))
in my .emacs file that (font-family-list)
returns nil
when emacsclient is starting up.
Unfortunately, also during initialization:
;; Both also print `nil` to the `*Messages*` buffer.
(message "%s" (find-font (font-spec :name "inconsolata")))
(message "%s" (find-font (font-spec :name "Inconsolata")))
;; Throws "error: No fonts being used"
(message "%s" (describe-font "Inconsolata"))
I do not know how to detect if a font is installed during initialization. My question has become: How do I reliably check whether a font is available when emacsclient starts up?
EDIT 2:
Echoing in after-init-hook
, emacs-startup-hook
, window-setup-hook
, before-make-frame-hook
, and after-make-frame-functions
also results in nil
.
Upvotes: 3
Views: 1622
Reputation: 592
I managed to find an answer in this post in emacs subreddit.
Here is the code snippet that I put in in init.el
:
(defun rag-set-face (frame)
"Configure faces on frame creation"
(select-frame frame)
(if (display-graphic-p)
(progn
(when (member "PragmataPro" (font-family-list))
(set-frame-font "PragmataPro-13")))))
Upvotes: 2
Reputation: 17021
Sigh... was annoyed with this problem as well, but I found the Emacs Lisp solution. Here is a straight copy/paste of the respective snippet from my Emacs configuration:
(defun frame-font-setup
(&rest ...)
;; (remove-hook 'focus-in-hook #'frame-font-setup)
(unless (assoc 'font default-frame-alist)
(let* ((font-family (catch 'break
(dolist (font-family
'("Powerline Consolas"
"Consolas for Powerline"
"Consolas"
;;
"Powerline Inconsolata-g"
"Inconsolata-g for Powerline"
"Inconsolata-g"
;;
"Powerline Source Code Pro"
"Source Code Pro for Powerline"
"Source Code Pro"
;;
"Powerline DejaVu Sans Mono"
"DejaVu Sans Mono for Powerline"
"DejaVu Sans Mono"
;;
"Monospace"))
(when (member font-family (font-family-list))
(throw 'break font-family)))))
(font (when font-family (format "%s-12" font-family))))
(when font
(add-to-list 'default-frame-alist (cons 'font font))
(set-frame-font font t t)))))
(add-hook 'focus-in-hook #'frame-font-setup)
Mmmhhh... [Rejoice]
Upvotes: 3
Reputation: 28531
When you start Emacs as a daemon (which is done implicitly by emacsclient on-demand), the .emacs is loaded before Emacs has made a connection to any "display device" (aka "terminal"), i.e. it is not connected to any GUI nor any tty. Instead its terminal is a dummy device which reads from stdin and sends the output to stdout (well, at the beginning and soon after, even that communication link is cut), so there are no fonts there.
One way to get what you want is to do something like:
(add-to-list face-font-family-alternatives '("myfont" "Inconsolata" "Monospace"))
and then to customize the default
face to use the font family myfont
. You may still have problems with the size of the font, in which case you may want to play with face-font-rescale-alist
.
Upvotes: 1
Reputation: 9466
Seems to be pretty much impossible with elisp alone so I've settled for fc-list
. This works.
(let ((default-font (cond
((and
(eq system-type 'gnu/linux)
(null (string= "" (shell-command-to-string "which fc-list")))
(null (string= "" (shell-command-to-string "fc-list inconsolata"))))
"Inconsolata 14")
(t
"monospace 12"))))
(set-default-font default-font)
(add-to-list 'default-frame-alist `(font . ,default-font)))
Upvotes: 0