spacemacs icon indicating copy to clipboard operation
spacemacs copied to clipboard

Permit `.spacemacs.d/init.el` to not be user init

Open bryce-carson opened this issue 2 years ago • 10 comments

DOCUMENTATION.org:

  • Add documentation for Chemacs users to the Alternative Dotfile Directory section in DOCUMENTATION.org
  • Add example Chemacs .emacs-profiles.el to aide understading of added documentation

core/core-dotspacemacs.el:

  • Add comment to explain the purpose of the let* form used to define dotspacemacs-directory and dotspacemacs-filepath
  • Add check for optional SPACEMACS_INIT_FILE_NAME environment variable, and fall back to "init.el" if the environment variable is not set
  • Remove unnecessary fall-through (t nil) form in dotspacemacs-directory's cond form: it is unnecessary, and the style of the other usage of cond makes this proposed change more consistent
  • Move the fallback to ~/.spacemacs in the cond for the definition of dotspacemacs-filepath to the end of the cond, so that ~/.spacemacs can be used with or without a dotfile dir, and that dir being either set by the SPACEMACSDIR environment variable or the default location (~/.spacemacs.d)
  • Change from a forced clause in the dotspacemacs-filename–setting cond to just (default-init), for the same reason as the other cond change

bryce-carson avatar Apr 22 '22 09:04 bryce-carson

This is why, basically:

λ  tree -a -d -L 2                                                                                                                                                                                   ~
.
├── .emacs.doom.d    ;; 👀👀👀
├── .emacs.d         ;; Where Chemacs lives
├── .emacs.gnu.d     ;; GNU Emacs
└── .spacemacs.d     ;; Spacemacs' happy little home
    ├── init.el      ;; The normal `init.el`
    └── spacemacs    ;; "`.spacemacs`"

bryce-carson avatar Apr 22 '22 09:04 bryce-carson

question: why do we need to make changes? does chemacs's instructions on Spacemacs stopped working?

lebensterben avatar Apr 22 '22 20:04 lebensterben

have you tried this without chemacs?

lebensterben avatar Apr 22 '22 20:04 lebensterben

question: why do we need to make changes? does chemacs's instructions on Spacemacs stopped working?

See the name of this PR and my second comment in the conversation (with the file tree).

With the current code, users must either use ~/.spacemacs or ~/.spacemacs.d/init.el for their configuration file. This doesn't work if ~/.spacemacs.d is their .emacs.d, and not just a hidden folder containing their user configuration file.

bryce-carson avatar Apr 22 '22 20:04 bryce-carson

have you tried this without chemacs?

I haven't, but Chemacs is not required. Without Chemacs, the environment variable must be set in the user's shell. If the environment variable is not set, the behaviour remains the same as now and init.el will be used as the configuration file if SPACEMACSDIR is set and ~/.spacemacs does not exist, or if ~/.spacemacs does not exist and ~/.spacemacs.d/init.el does exist and user_home_directory is not ~/.spacemacs.d.

This fixes the assumption that ~/.spacemacs.d/init.el is the user's configuration file, as the PR name states.

bryce-carson avatar Apr 22 '22 20:04 bryce-carson

have you tried this without chemacs?

With Spacemacs/Emacs living in ~/.emacs.d, this works:

SPACEMACS_INIT_FILE_NAME="config" emacs

With a symbolic link from ~/.emacs.d to ~/.spacemacs.d, this works:

SPACEMACSDIR="/Users/bryce/.spacemacs.d" SPACEMACS_INIT_FILE_NAME="config" emacs

As I said, Chemacs not required. :)

bryce-carson avatar Apr 22 '22 21:04 bryce-carson

There is a simple way to satisfiy your requirement, the key point is change spacemacs-start-directory.

emacs -q --eval '((lambda (x)
   (setq spacemacs-start-directory (file-name-directory x))
   (load-file x))
 (expand-file-name "~/.spacemacs.d0/init.el"))'

So you can put this logical into your script, or, submit common change to official .spacemacs.d/init.el file.

sunlin7 avatar Jun 07 '22 18:06 sunlin7

I have been using chemacs for a long time so that I can select among several spacemacs variants, doom, scimax, and other startup files when emacs starts. I do have some custom changes of spacemacs on top of develop branch, e.g.,

diff --git a/init.el b/init.el
index 2ce6f5bf6..db7f8ff4e 100644
--- a/init.el
+++ b/init.el
@@ -27,6 +27,11 @@
 ;; Avoid garbage collection during startup.
 ;; see `SPC h . dotspacemacs-gc-cons' for more info
 (defconst emacs-start-time (current-time))
+(setq spacemacs-start-directory (file-name-directory load-file-name))
+
+;; Load following rather than ~/.spacemacs.
+(setq dotspacemacs-filepath (expand-file-name "core/templates/.spacemacs.template" spacemacs-start-directory))
+
 (setq gc-cons-threshold 402653184 gc-cons-percentage 0.6)
 (load (concat (file-name-directory load-file-name)
               "core/core-versions")

It has been too long since I made my custom changes, so I don't remember which of my changes were made to allow chemacs to work. I don't have or need ~/.spacemacs since above change uses .spacemacs.template instead. If you are curious, all my changes can be found in https://github.com/emacs18/spacemacs/commits/sm-my branch which comes off of develop branch. Some of the changes are to allow use of straight.el instead of package.el.

emacs18 avatar Jul 03 '22 04:07 emacs18

Emacs 29 now support --init-directory option which makes chemacs no longer necessary. See https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=8eaf04de83 Given this is this PR still relevant?

emacs18 avatar Jul 09 '22 20:07 emacs18

Emacs 29 now support --init-directory option which makes chemacs no longer necessary. See https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=8eaf04de83 Given this is this PR still relevant?

As explained, the presence of documentation changes related to Chemacs in this PR is secondary, and not necessarily related to the proposed code changes.

Regardless of Emacs 29 and Chemacs, this PR was converted to draft for the security reason that Lucius noted.

bryce-carson avatar Jul 09 '22 22:07 bryce-carson

I have just followed up the conversation, and I understand the need to have spacemacs being flexible when it comes to user specific file organisation.

However given that emacs 29 is kind of solving the issue for us I wonder if this is really worth the time.

I am still going to have a look at the changes @emacs18 has done on his develop and see if I can integrate parts of this into the trunk, especially as I am really interested in straight.el myself, but no promises.

smile13241324 avatar Apr 14 '23 09:04 smile13241324

btw I've installed chemacs 2 and there's no need to do any configuration on Spacemacs's side.

lebensterben avatar Apr 15 '23 17:04 lebensterben

How would you setup multiple spacemacs configurations? For example vanilla develop branch of spacemacs as well as spacemacs with personal setup added to it? For me the issue is ~/.spacemacs file. I need two different versions of this. Hence my solution is to launch emacs like this:

#!/bin/bash

export SPACEMACSDIR=${HOME}/.emacs.d/$1/.spacemacs

exec emacs29 --init-directory ${HOME}/.emacs.d/$1 --debug-init &

and setup each config directory to use its own copy of the spacemacs init file like this:


$ file ~/.emacs.d/sm-ms/.spacemacs/*
/home/me/.emacs.d/sm-ms/.spacemacs/init.el: symbolic link to ../core/templates/.spacemacs.template
$ 

emacs18 avatar Apr 15 '23 19:04 emacs18

How would you setup multiple spacemacs configurations?

good question. i ignored this use case.

lebensterben avatar Apr 15 '23 19:04 lebensterben

@emacs18

but that sounds like an edge case.

most users should not need to have two separate .spacemacs.

lebensterben avatar Apr 15 '23 19:04 lebensterben

How would you setup multiple spacemacs configurations? For example vanilla develop branch of spacemacs as well as spacemacs with personal setup added to it? For me the issue is ~/.spacemacs file. I need two different versions of this. Hence my solution is to launch emacs like this:

#!/bin/bash

export SPACEMACSDIR=${HOME}/.emacs.d/$1/.spacemacs

exec emacs29 --init-directory ${HOME}/.emacs.d/$1 --debug-init &

and setup each config directory to use its own copy of the spacemacs init file like this:


$ file ~/.emacs.d/sm-ms/.spacemacs/*
/home/me/.emacs.d/sm-ms/.spacemacs/init.el: symbolic link to ../core/templates/.spacemacs.template
$ 

I maintained two separate configurations of Spacemacs using Chemacs2. It was convenient due to the single flag and a simple elsip config file to define profiles.

I used the same .spacemacs in my home directory, however.

@lebensterben , what about documenting the ability to predefine the dotspavemacs file used in early-init?, which overrides any searching logic for the .spacemacs file?

That'd do several things:

  1. Permit .spacemacs.d/init.el to not be .spacemacs when early init is specifying an alternate path (the assumption is not made any more, and the init.el takes on its usual meaning)
  2. Allow multiple .dotspacemacs for emacs18, and
  3. Retain current behaviour if the user does not predefine the dotspacemacs-filepath constant in their early init.

It also avoids introducing another envvar, and is a simple implementation, simply wrap the current form defining the constant with an unless!

(unless dotspacemacs-filepath
  (defconst dotspacemacs-filepath
    ;; ... the rest of the definition, including the INITVALUE argument
))

It's been some time since I have thought about this, however.

bryce-carson avatar Apr 15 '23 21:04 bryce-carson

that's over engineering.

users should not have multiple configurations.

if users still want multiple configs, they should manually hack it.

lebensterben avatar Apr 15 '23 21:04 lebensterben

one way to hack .spacmeacs is to realize that this is a normal elisp file.

for example, you have two configurations for two systems, the pseudo code should look like:

(if (SOME-KIND-OF-TESTS) 
    (load DOTSPACEMACS-ONE)
  (load DOTSPACEMACS-OTHER))

lebensterben avatar Apr 15 '23 22:04 lebensterben

I actually have more than two spacemacs configuration.

  • one I use daily using my own customizations using straight.el and using vim style
  • same one using packge.el
  • one using emacs style rather than vim style
  • vanilla spacemacs without any customizations

I of course use the first one most of the time, but I do sometimes use other ones for testing purposes.

emacs18 avatar Apr 15 '23 22:04 emacs18

that's over engineering.

users should not have multiple configurations.

if users still want multiple configs, they should manually hack it.

A single when form is over-engineering Spacemacs?

The point is not to have multiple .spacemacs for a single Emacs process with the Spacemacs framework, but to ensure a given Spacemacs is running with the correct file.

It is a sane thing to do when you're hacking on Spacemacs to keep your hacks in a separate clone and using either the template dotspacemacs, the same as usual, or a different one from how you nornally configure develop.

While I was hacking on it, reading every core file (Spacemacs' core is a tidy ~20,000 lines), I needed to keep a separate clone and use my normal for writing the hacks.

I don't think providing the option, with a couple lines of new comments in early-init is bad, except if there is some other part of the loading procrss impacted and the assumptions made in the earlier design were intentional.

I suppose a look at the history of ~/.spacemacs vs ~/.spacemacs.d/init.el might give us insight.

I'm guessing a few users wanted a directory to house several elisp files and load them from their dotspacemacs rather than have a monolithic configuration file, given ~/.spacemacs.d/ cannot house Spacemacs itself.

bryce-carson avatar Apr 15 '23 23:04 bryce-carson

A single when form is over-engineering Spacemacs?

what is the single when form?

lebensterben avatar Apr 15 '23 23:04 lebensterben

A single when form is over-engineering Spacemacs?

what is the single when form?

I mentioned it in my previous response.

Surrounding the current constant definition of dotspacemacs-filepath in core-dotspacemacs.el (line 50) with a when form to check if it has already been defined (which would be the case if you predefine it in early init yourself).

Like so (sorry for screenshotting it, I'm on mobile and this will preserve the indentation)

...pardon me, I meant an unless

Screenshot_20230415-181748_Termux.jpg

bryce-carson avatar Apr 16 '23 00:04 bryce-carson

Currently the return value of the defconst form is unused, so wrapping it and changing the overall return value shouldn't have any ill effects.

bryce-carson avatar Apr 16 '23 00:04 bryce-carson

Correction

(unless (boundp 'dotspacemacs-filepath)
    (defconst dotspacemacs-filepath ...))

bryce-carson avatar Apr 16 '23 00:04 bryce-carson

replace defconst by defcustom should suffice.

lebensterben avatar Apr 16 '23 00:04 lebensterben

replace defconst by defcustom should suffice.

An interesting alternative. I'll leave a PR for it up to someone else, but after a quick test I don't see any issues with allowing this.

It worked fine in my test.

@emacs18 what do you think?

bryce-carson avatar Apr 16 '23 00:04 bryce-carson

It appears that the point of the proposed change is to allow users to set dotspacemacs-filepath early on to over-ride the default value, right? So this would be an alternate method which avoids messing with SPACEMACSDIR environment variable.

What is the advantage of using

(setq dotspacemacs-filepath my-path)

verses

(setenv "SPACEMACSDIR" my-path)

Wouldn't these two be equivalent?

Also I see

(defconst dotspacemacs-directory
  (let* ((spacemacs-dir-env (getenv "SPACEMACSDIR"))
  ...

Thus if you don't set SPACEMACSDIR, then don't you need to set not only dotspacemacs-filepath, but also dotspacemacs-directory?

emacs18 avatar Apr 16 '23 16:04 emacs18

environment variable can be set by

  • any shell startup script
  • any scripts sourced by the shell startup script
  • your scripts source by your desktop environment or VM/container
  • the process that starts your emacs instance
  • user overrides in the terminal
  • user overrides in emacs initialization files

it's a total mess and cryptic.

lebensterben avatar Apr 16 '23 16:04 lebensterben

You seem to think the many ways in which environment variables can be set is a disadvantage. I've heard some say the exact opposite arguing that the flexibility is an advantage. However I think this is off topic, because we are not discussing getting rid of SPACEMACSDIR.

The use of SPACEMACSDIR environment variable has been around many years. I doubt that anyone would consider getting rid of it, because some do not like using environment variables in general.

Assuming that SPACEMACSDIR will continue to exist, what is the advantage of making changes to spacemacs to allow use of

    (setq dotspacemacs-directory some-path)
    (setq dotspacemacs-filepath (expand-file-name "init.el" dotspacemacs-directory))

verses the following

    (setenv "SPACEMACSDIR" some-path)

Even if former was doable today, why would you use that verses the much simpler latter?

emacs18 avatar Apr 16 '23 17:04 emacs18

I doubt that anyone would consider getting rid of it

Me.

lebensterben avatar Apr 16 '23 17:04 lebensterben