3

As per title, I'm attempting my first config as I would like to start small and build it as I learn, rather then being overwhelmed by something like Doom or Spacemacs.

I took Protesilaos basic configuration and I tried to embed it the same way Sophie Bosio does because it looks like and efficient and beautiful way to also document my configuration as I work on it.

However, I've barely managed to write a first draft that I've already encountered an error I can't overcome.

The error is:

⛔ Warning (initialization): An error occurred while loading ‘/home/moka/.emacs.d/init.el’:

error: Recursive load, /home/moka/.emacs.d/init.el, /home/moka/.emacs.d/init.el, /home/moka/.emacs.d/init.el, /home/moka/.emacs.d/init.el, /home/moka/.emacs.d/init.el

And for context: my init.el and init.org.

What is causing the recursive load and how can I fix it?

5
  • 1
    Welcome to Emacs and to this stack. I submitted an edit suggestion, the primary intent of which was to make the title more descriptive for potential future querents and to change the code formatting to a quote. I also changed a couple minor things for phrasing in a way that I hope still aligns with your intentions. If this is not the case, you're welcome to reject or amend the edit. Happy hacking! :) Commented Feb 10 at 12:46
  • 1
    For regulars- I would appreciate someone taking a look at the tags please? I am not sure the elisp tag is warranted in light of its wiki usage guidance, but I defer to older and wiser heads. Cheers! Commented Feb 10 at 12:50
  • You are right about the elisp tag: it is often misused (as in this case), so feel free to delete it. I would do it but (I'm guessing) I cannot while your edit request is still pending (I approved but it needs one more vote before it gets applied). Commented Feb 10 at 13:51
  • 1
    @NickD thanks for confirming, I have edited the proposed edit (TIL that a user could do that!) Commented Feb 10 at 14:01
  • Thank you both for improving my post and for helping with it. Commented Feb 10 at 22:32

3 Answers 3

3

If you're attempting your first config, I would suggest keeping it simple and just using org-babel-load-file:

I would suggest renaming the org file to something like config.org and have an init.el that contains only

;; init.el (org-babel-load-file (concat user-emacs-directory "config.org")) 

This creates a file config.el by tangling config.org and loads it. My real config is in config.org. I chose that name simply because it avoids confusion between the init.el that you wrote and the one generated by tangling init.org.

You can version-control config.org and put config.el in your gitignore.

In your config.org (or any other name that isn't init.org) you can also put this

(setq custom-file (concat user-emacs-directory "custom-file.el")) (unless (file-exists-p custom-file) (write-region "" nil custom-file)) (load custom-file) 

and gitignore custom-file.el (or your choice of filename).

If you do that, emacs will not change your init.el meaning that you can version control it too and you don't have to do git update-index --assume-unchanged init.el which has drawbacks.

This is missing her tangle-init that runs automatically tangles the file when you save it but it's going to get tangled anyway when you startup Emacs.

Also I'm guessing the tangle-init that runs every time you save is meant to save time when you're working on your config but Emacs is a running interpreter. In your org file, you can do C-c C-c on an SRC block to evaluate just that block, and you can do C-x C-e to evaluate the s-exp before your cursor (your cursor after the closing parenthesis or on it if you are using evil mode).

I usually apply changes to my configuration that way and before I make a commit, I might do a restart of Emacs just to make sure or if it makes sense intuitively (like if you delete a line that does (setq x y) from an SRC block and you evaluate that block with C-c C-c, x doesn't go away. But if you change it to (setq x z) you can just C-x C-e that expression without needing to restart.

2
  • Good points all and food for thought for a second config. The first config should be much simpler and much more manual - IMO. Commented Feb 10 at 4:54
  • Thank you very much. Your solution worked and your tips were precious. I truly appreciate that. I will now dissect and look into the configuration more without going any further. I'm happy I could preserve the Org file as both configuration and documentation. Commented Feb 10 at 23:05
3

The init.el file is a bootstrap (and a buggy bootstrap at that). It's supposed to replace itself with the tangled file obtained from init.org the first time that you run emacs - but it does not: it just produces an early-init.el file and that's all. It then reloads itself recursively as @phils has explained in his answer

The bug is that org-babel-tangle should be called like this:

... (org-babel-tangle nil "init.el") ... 

Do C-h f org-babel-tangle for the details, but briefly, that makes init.el be the default target of all source blocks that don't specify a target (i.e. all source blocks in init.org except for the early-init one).

Note that the same change has to be made to tangle-init, otherwise the tangling and byte-compilation that are supposed to happen after you change init.org will fail as well, leaving the (tangled-on-first-invocation) init.el unchanged, even though init.org is modified.

Another possibility is to add a property drawer at the top of the init.org file to specify a default tangle header for all source blocks, which is used by all the source blocks in the file that don't specify one (IOW, all of them except the early-init source block):

:PROPERTIES: :header-args: :tangle init.el :END: 

That will allow you to call org-babel-tangle without arguments.

You should report the issue on Sophie's Github page.


But I think you need to step back and not bite such a big chunk of code to begin with: you say you want to start small, but there is a whole lot of machinery here that you are not familiar with. I would start with just (require 'org) in init.el and a very small init.org file, do the tangling by hand and then look at the tangled file. If you had tried that, you would have seen that the tangling only gives you one file (early-init.el) and not two. You should read the tangling section in the Org mode manual and play around with small examples to figure out how it works. Then maybe you can tackle a literate configuration, but you don't have to have a bootstrap - that's a "clever" thing to do, but it's unnecessary: you can keep an init.org somewhere other than in user-emacs-directory, tangle it by hand, eyeball the produced init.el file to make sure it looks good and then copy it over the init.el in user-emacs-directory (I would actually save the latter before overwriting, to make it easy to recover from disasters).

1
  • 1
    Thank you very much for the help. I know It was probably a bit too much to start with, but I really found helpful the way it looked. I'm new to Emacs as well as Lisps, so it can be a bit confusing to go through much unknown code. And the editor I can use to help with syntax highlighting and whatnot is Emacs itself. So, not many choices. Anyway, Philippe Carphin solution worked and I will try to learn from there before moving on. Commented Feb 10 at 23:10
2

Your init.el file does this:

(load-file (concat user-emacs-directory "init.el")) 

Which is your recursive load (the file is loading itself, which loads itself, which loads itself...)

3
  • Thanks for the reply, phils. That line is also in Sophie's init.el ( github.com/SophieBosio/.emacs.d/blob/main/init.el ) and that makes me believe I'm either missing something or my error resides somewhere else. Commented Feb 9 at 23:59
  • My only suggestions are (1) that her user-emacs-directory is somewhere different to that init.el file; or (2) that (org-babel-tangle) is supposed to replace that small init.el file with a different one, which then gets loaded in its place. I can't tell you anything about writing init files in org-mode. Commented Feb 10 at 1:27
  • 1
    If it's option (2) though, that must be a one-time thing as a kind of bootstrapping technique, so I guess you could do that step in a more manual way and not worry about the bootstrap file. Right now I'd say that the 'tangle' function is not replacing that file. Commented Feb 10 at 1:28

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.