Help! I've broken my emacs configuration. I was trying to sort out my messy config.el file by dividing it into multiple .org files.

My init.el file now looks like this

(require 'org)
 (expand-file-name "config.org"
                   (expand-file-name "/Users/ljs46/.emacs.d")))

My config.org contains the following.

#+PROPERTY: header-args:emacs-lisp :tangle config.el

#+begin_src emacs-lisp
#+INCLUDE: personal-info.org
#+INCLUDE: general-settings.org
#+INCLUDE: keybindings.org
#+INCLUDE: package-management.org
#+INCLUDE: functionality.org
#+INCLUDE: ess.org
#+INCLUDE: pdf.org
#+INCLUDE: org.org
#+INCLUDE: spelling.org

Just to give an example of one of my org files, here is my (very basic) ess.org

#+PROPERTY: header-args:emacs-lisp :tangle yes
* ESS Configuration
  :CUSTOM_ID: ess-configuration
  #+BEGIN_SRC emacs-lisp
 ;; Set default R version, (i.e. the one launched by typing M-x R <RET>)
  (setq inferior-R-program-name "/usr/local/bin/R")

  ;; Allow hash to be entered  
  (global-set-key (kbd "M-3") '(lambda () (interactive) (insert "#")))

I am using MaOS 12.0.1 and emacs 29.1 universal binary.

If anyone can help me solve this, I'd be extremely grateful.

  • Solve what? You say nothing about what you mean by "broken".
    – Drew
    Commented Dec 14, 2023 at 3:49

1 Answer 1


First, you should not have an emacs-lisp source block surrounding your includes: they are not emacs-lisp code. But the main problem is that you expect the #INCLUDE:s to be expanded on tangling: they are not, they are only expanded on export. Most "literate" config.org files that I've seen are huge single files: they don't use #+INCLUDE: at all (e.g. https://www.lucacambiaghi.com/vanilla-emacs/readme.org was the first random hit I looked at).

You can use #+INCLUDE: but not in the file that org-babel-load-file will process (first tangle and then load). If your config.org contains #INCLUDE: lines, you will need to expand those lines (i.e. replace them with the contents of the included file). Since that expansion only happens during export, you will need to export your org file to a different file.

Org mode provides an export backend to produce Org mode files: all the transformations (#+INCLUDE: processing, MACRO: processing, etc.) will be done, but the final transcoding will be more or less trivial: the file contents are almost literal copies of the contents of the included files.

So try it: get rid of the emacs-lisp source block markers, and export the config.org file using C-c C-e O o, i.e. to an Org mode file. The resulting file will be called config.org.org to distinguish it from the original, but you should probably rename it to something like post-config.org (or name your original file preconfig.org and then rename the export output file (which would be preconfig.org.org) to config.org. I'll assume you have done the latter for definiteness.

So you started with a preconfig.org (which contains #+INCLUDE:s) and exported it to preconfig.org.org with C-c C-e O o and then renamed that to config.org. This file now does not contain any #+INCLUDE: lines: they have been replaced by the contents of the various files.

You can now give that config.org file to org-babel-load-file: it will tangle it to produce a config.el and then it will load the config.el file. There are many possibilities of more errors, but if you understand the basic flow, you should be able to debug them: look at the preprocessed config.org to familiarize yourself with what it looks like, then look at the tangled config.el (tangle it by hand with C-c C-v C-t first and look at it before going further; if it looks reasonable, try to load it manually using M-x load-file; if that works, then try your three-line init.el file). If something is broken, find out where in the pipeline the breakage occurred and carry it back all the way to your preconfig.org or (more likely) the included file that caused the breakage; fix it and regenerate the config.org file. Then go through the whole sequence, producing the various files by hand and examining them carefully.

  • Thanks. That solves my problem, and clears up some confusion my part. I am going to try and solve it a different way, which is to write an lisp function to load each of the subordinate files. That way I can also make them load conditionally, for example, ess configuration loads only when I visit a .R file, for example.
    – Lindsay
    Commented Dec 15, 2023 at 16:20
  • SInce it solves your problem, please accept the answer.
    – NickD
    Commented Dec 15, 2023 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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