I'd like the size of the default face be read in an environment variable.

Currently my .emacs reads the frame size from the EMACS_HEIGHT var thanks to the following code in the (custom-set-variables ...) list:

       (cons (quote height) (string-to-int (getenv "EMACS_HEIGHT")))
       (quote ((menu-bar-lines . 1) (tool-bar-lines . 0) (width . 82)))))

I tried to adapt it to "insert" a similar getenv directive into the line which sets the default face (in (custom-set-faces ...)):

'(default ((t (:inherit nil :stipple nil :background "grey80" :foreground "black"
               :inverse-video nil :box nil :strike-through nil :overline nil 
               :underline nil :slant normal :weight normal :height 110 
               :width normal foundry :"unknown" :family "Droid Sans Mono"))))

but didn't succeed. Or, rather, I may achieve my goal with something like

(cons ':inherit (cons nil (cons ':weight (cons 'normal (cons ':height (cons
(string-to-int (getenv "EMACS_HEIGHT")) '(:foundry "unknown")))))))

but using one cons per item looks like much ado (and a waste of parentheses).


It's a wonder it should work in the first example. The ' (is a macro that) translates into (quote ...), so it inserts everything verbatim, without evaluating it. (i.e. without executing the cons forms.)

If you want to evaluate part of a quoted template, you can use quasiquote (aka backquote) using the ``` character, and "unquoting" the respective parts with ,. For your example that means (tested and works for me):

(setenv "EMACS_FRAME_HEIGHT" "100") ;for easier testing
(setenv "EMACS_FONT_HEIGHT" "110")

(setq default-frame-alist
      `((height . ,(string-to-int(getenv "EMACS_FRAME_HEIGHT")))
        (menu-bar-lines . 1) (tool-bar-lines . 0) (width . 82) ))

(custom-set-faces `(default ((t (:inherit nil :stipple nil :background "grey80" :foreground "black"
               :inverse-video nil :box nil :strike-through nil :overline nil 
               :underline nil :slant normal :weight normal
               :height ,(string-to-int (getenv "EMACS_FONT_HEIGHT"))
               :width normal foundry :"unknown" :family "Droid Sans Mono")))))  

If you edit the part inserted by configure into your init files, it will likely mess with your changes if you use configure later. On the other hand, you can also set it somewhere else (in your init files or elsewhere.)

  • The first example definitely works, it is inside the (custom-set-variables ...) "section" if that matters (it probably does). The (custom-set-faces ...) section in .emacs has this comment: "Your init file should contain only one such instance. If there is more than one, they won't work right.". So where do I put your code? When you say "configure will likely mess with your changes if you use it later", do you mean "use it on the default face", or "use it on any face"? – L. Levrel Jan 20 '17 at 13:18
  • 1
    Even worse: Custom will overwrite the line when used on any option, not only faces! So I really need to know what "somewhere else" you're referring to, and how I should proceed. I also tried to play with set-face-attribute to avoid the "Custom" problem but couldn't make it work. – L. Levrel Jan 23 '17 at 14:22

I worked around my problem by using themes (I only need two different font sizes). I used this opportunity to apply default-frame settings in the same way.

In .emacs:

(if (string-equal "foo" (getenv "PROFILE"))
  (load-theme 'foo t)
  (load-theme 'bar t))

In .emacs.d/foo-theme.el:

(deftheme foo
  "Created 2017-02-16.")

   (quote ((height . 57) (menu-bar-lines . 1)
           (tool-bar-lines . 0) (width . 82)))))

 '(default ((t (:height 113))) t ))

(provide-theme 'foo)

And similar commands in .emacs.d/bar-theme.el.

Thanks to Benoît Izac for the hint (posted on Usenet group fr.comp.applications.emacs on January 24, 2017).

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.