Spacemacs neben regulären Emacs ausführen: Separate .emacs.d


32

Ich würde gerne Spacemacs ausprobieren. Ich möchte jedoch noch nicht von meiner regulären Emacs-Konfiguration wechseln, daher möchte ich, dass sich die aktuelle Konfiguration .emacs.din einem Verzeichnis und die entsprechende Konfiguration für Spacemacs in einem anderen Verzeichnis befindet. Es ist mir egal, welchen Namen eines der Verzeichnisse hat.

Ist das möglich, kurz vor chroots / LD_PRELOAD / anderen solchen Tricks? Wie kann ich es tun?


2
Siehe auch Dans Antwort auf eine ähnliche Frage zum Einrichten eines Timers mit Optionen beim Starten von Emacs: emacs.stackexchange.com/questions/3588/… Seitdem verwende ich eine geringfügige Variation dieser Antwort.
Gesetzesliste

1
In der Kategorie "Sonstige Tricks" könnten Sie möglicherweise einen Symlink erstellen spacemacs, der auf die ausführbare (car command-line-args)Datei von emacs verweist, und anhand des Werts von entscheiden, welche Init-Datei ausgeführt werden soll. Dies setzt natürlich
voraus


2
Ich bin gerade zurückgekommen, um zu sagen, dass ich etwa 18 Monate später immer noch keine Spacemacs gelernt habe. Ich hatte ein paar Probleme mit der akzeptierten Antwort, versuchte es einfach noch einmal, immer noch wahr. Nach dem Hinzufügen eines Org-Layers wurde "Symbol's function definition is void: loop" angezeigt. Ich weiß nicht, dass dies ein Teil der Ursache ist, aber genau das ist das Problem: Für ein poliertes Projekt "Batterien enthalten" scheint es seltsam, etwas zusammenzuschustern, nur um es zu starten, und sich dann zu fragen, ob meine Konfiguration unterstützt wird. Vielleicht unfair, aber das lässt mich das Vertrauen verlieren. Vielleicht wird es in weiteren 18 Monaten behoben ...
Croad Langshan

Antworten:


20

Eine Möglichkeit besteht darin, anzugeben, welche Konfiguration Sie in eine ~/.emacsDatei laden möchten . Wenn Emacs gestartet wird, sucht es nach einer solchen Datei, bevor es sie ansieht ~/.emacs.d/. Weitere Informationen zur Init-Datei finden Sie im Emacs-Handbuch.

So können Sie beispielsweise eine erstellen ~/.spacemacs.dund Ihre vorhandene beibehalten, ~/.emacs.dwie sie ist. Dann erstellen Sie ein ~/.emacs, um das zu laden, was Sie verwenden möchten:

(setq use-spacemacs t)   ; or nil 

(when use-spacemacs
  (setq user-emacs-directory "~/.spacemacs.d/"))   ; defaults to ~/.emacs.d/

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

Wenn Sie möchten, haben Sie die Möglichkeit, die Konfiguration zu ändern, ohne die .emacs-Datei zu ändern. Lassen Sie Ihren .emacs beispielsweise nach Umgebungsvariablen suchen, die Sie in Ihrer Shell oder in einem Skript festgelegt haben, mit dem Sie Spacemacs starten:

(setq use-spacemacs (getenv "USE_SPACEMACS"))

1
Sicherlich muss es einen Weg von innen geben, um festzustellen, ob Sie Spacemacs einsetzen oder nicht? Zum Beispiel, indem Sie (mit fboundp) nach einer Funktion oder einem Befehl suchen, die / der für Spacemacs eindeutig ist?
Harald Hanche-Olsen

2
Sicher, aber das war nicht die Frage, wie ich es verstand. Spacemacs ist nur eine Emacs-Konfiguration, und das OP möchte wissen, wie mehr als ein unabhängiges Emacs-Konfigurationsverzeichnis verwaltet wird.
Glucas

1
@ HaraldHanche-Olsen das hat mich auch überrascht, als ich es heruntergeladen habe, aber als ich darüber nachgedacht habe, hat es total Sinn gemacht. Ich denke, der Grund, den wir erwarten, ist, dass für die meisten Systeme, um ein poliertes "Produkt" wie Spacemacs zu erstellen, eine niedrigere Systemsprache ausgeblendet werden muss - aber in Emacs gibt es so viel Erweiterbarkeit (danke Elisp) dass das nicht nötig ist.
Croad Langshan

1
Ich akzeptierte das, hatte es aber nicht ausprobiert. Nun , da ich habe, tut es nicht ganz funktioniert , wie sie ist: Dateifehler: Kann nicht öffnen Datei laden, /home/me/.emacs.d/core/core-load-paths.el - ich brauche , um (setq user-emacs-directory "~/.spacemacs.d/")für sie zu arbeite (in einem prognauf dem spacemacs ast deiner bedingung). Kannst du das zu deiner Antwort hinzufügen, damit ich sie wieder annehmen kann?
Croad Langshan

2
@glucas Ich bin auf win10, aus irgendeinem Grund wurde HOME c: / users / nate zugewiesen. Entfernte die Umgebungsvariable und alles hat gut funktioniert.
Nathaniel Saxe

12

Da es bei init mehr zu tun gibt, als nur eine Datei zu laden und andererseits meine Laufzeitumgebung zu verknüpfen .emacs.doder zu ändern HOME, habe ich mich für eine Variante von @glucas entschieden. Ich habe den Code von verwendet startup.elund den Patch von # 15539 hinzugefügt , um eine Umgebungsvariable zum Wechseln zwischen verschiedenen Init-Verzeichnissen zu verwenden. Wenn keine angegeben ist, wird die Standardeinstellung verwendet.

Es gab ein Problem mit Spacemacs: Sie asyncwissen nichts über das geänderte Init-Verzeichnis und können daher einige erforderliche Dateien nicht finden. Aber dies wurde kürzlich in Spacemacs behoben: Fehler beim Verwenden eines anderen Konfigurationsverzeichnisses als .emacs.d · Problem # 3390

Also hier ist meine ~/.emacs, die sich wie der ursprüngliche Init-Code verhalten sollte, aber mit konfigurierbarem Init-Verzeichnis:

;;; .emacs --- let the user choose the emacs environment to use

;;; Commentary:
;;; This code mimics the behaviour of `startup.el' to let the
;;; usage of the custom init directory behave just like the
;;; one and only "~/.emacs.d".
;;;
;;; By setting the environment variable `EMACS_USER_DIRECTORY'
;;; the user-emacs-directory can be chosen and if there is an
;;; `init.el' the configuration from that directory will be used.
;;; If the environment variable is not set or there is no `init.el'
;;; the default configuration directory `~/.emacs.d/' will be used.
;;;
;;; The variable `server-name' will be set to the name of the directory
;;; chosen as start path.  So if the server will be started, it can be
;;; reached with 'emacsclient -s servername'.
;;;
;;; This now works with a current version of spacemacs but does not
;;; work with `async-start' in general, if the code executed with `async'
;;; uses `user-init-dir' or makes other assumptions about the emacs
;;; start-directory.

;;; Code:
(let* ((user-init-dir-default
    (file-name-as-directory (concat "~" init-file-user "/.emacs.d")))
       (user-init-dir
    (file-name-as-directory (or (getenv "EMACS_USER_DIRECTORY")
                    user-init-dir-default)))
       (user-init-file-1
    (expand-file-name "init" user-init-dir)))
  (setq user-emacs-directory user-init-dir)
  (with-eval-after-load "server"
    (setq server-name
      (let ((server--name (file-name-nondirectory
                   (directory-file-name user-emacs-directory))))
        (if (equal server--name ".emacs.d")
        "server"
          server--name))))
  (setq user-init-file t)
  (load user-init-file-1 t t)
  (when (eq user-init-file t)
    (setq user-emacs-directory user-init-dir-default)
    (load (expand-file-name "init" user-init-dir-default) t t)))

(provide '.emacs)
;;; .emacs ends here

Es gibt auch eine nette Ergänzung, mit der es ohne zusätzlichen Aufwand als Daemon funktioniert: Der Servername wird auf den Namen des Init-Verzeichnisses gesetzt. Jetzt können Sie einen zweiten Emacs-Daemon mit Vanille-Spacemacs starten

EMACS_USER_DIRECTORY=~/.emacsenv.d/spacemacs emacs --daemon

und benutze immer noch emacsclient

emacsclient -s spacemacs -c -e '(message "Hello spacemacs")'

Mein Anwendungsfall ist sehr einfach und ich bin erstaunt, dass ich der einzige bin: Ich habe einen immer laufenden Emacs-Daemon und benutze ihn von der GUI und über die Konsole (zum Beispiel mit SSH). In diesem Emacs bereite ich alle meine Unterlagen und mein Arbeitsprotokoll vor, also muss es die ganze Zeit da sein. Aber dann möchte ich Spacemacs oder eines der anderen Distributionspakete ausprobieren und sogar konfigurieren, bis ich meine aktuelle Konfiguration zurückziehen oder einige der cleveren Ideen verwenden kann. Und wie andere wollte ich eine einfache Basiskonfiguration für meine Mitarbeiter erstellen - und in meiner laufenden Instanz mit org-mode dokumentieren.

Da das einzige mir bekannte Problem darin besteht, asyncdass es nichts über das geänderte Init-Verzeichnis weiß, überlege ich, wie man am besten eine Konfiguration mit asyncVariablen hinzufügt, die standardmäßig eingefügt werden sollten, damit nicht alle gepatcht werden müssen Beschwörungen async-startwie bei Spacemacs.


Das ist wirklich schön und hat wunderbar funktioniert ... bis ich es benutzen musste async. :-( Haben Sie eine Problemumgehung, seitdem Sie einige Monate nichts veröffentlicht haben?
Trey

Leider nicht - aber für Spacemacs ist es fest und für allgemeine Asynchronität bin ich mir nicht sicher, ob es Änderungen geben muss, da async-startEmacs ohne irgendetwas gestartet wird und wenn Sie eine Variable verwenden möchten, müssen Sie sie übergeben Schön und praktisch, wenn async mit einer Liste von Variablen konfiguriert werden kann, die bei jedem Aufruf von verwendet werden async-start.
Uwe Koloska

1
Bei diesem Ansatz werden möglicherweise andere Variablen aus dem Standard-Benutzer-Emacs-Verzeichnis initialisiert, bevor Ihre .emacs geladen werden. Zum Beispiel musste ich (setq custom-theme-directory user-emacs-directory)hier hinzufügen .
Glucas

1
Ich weiß nicht, wo diese Variable gesetzt ist, denn wenn ich sie in einem minimalen testenv untersuche, erhalte ich: Ihr Wert ist "~ / .emacs.d /". Der ursprüngliche Wert war "~ / .emacsenv.d / init-test /". Er hat also den richtigen Wert, wurde jedoch überschrieben.
Uwe Koloska

1
Ich habe diese Antwort tatsächlich verwendet, lange nachdem ich die Frage gestellt hatte. Ich habe die akzeptierte Antwort nicht geändert, weil sie so lang ist und weil ich der Implementierung nicht wirklich viel Aufmerksamkeit geschenkt habe! Diese Antwort hat mir jedoch sehr geholfen.
Croad Langshan

5

Es wird hier erklärt und es gibt eine laufende PR , um es der Dokumentation hinzuzufügen:

mkdir ~/spacemacs
git clone git@github.com:syl20bnr/spacemacs.git ~/spacemacs/.emacs.d
HOME=~/spacemacs emacs```

6
Ja, ich ändere manchmal HOME, um eine alternative Konfiguration auszuprobieren. Der Nachteil ist, dass HOME für andere Dinge verwendet wird, die Sie möglicherweise nicht beeinflussen möchten.
Glucas

3

Es ist bereits beantwortet und akzeptiert, aber wenn Sie Lust haben, neue Wege zu gehen, um Dinge umzukehren (jenseits von emacs configs), empfehle ich Ihnen, eine halbe Stunde damit zu verbringen, sich mit GNU Stow vertraut zu machen. Es ist eine Art ln -sauf Steroiden, und es könnte verschiedene Ansätze geben, um es zu verwenden. Sie können das gesamte Setup in einem Unterverzeichnis (einschließlich Offlineimap-Konfigurationen, Emacs-Konfigurationen usw.) haben - das wäre ein auf der Umgebung basierender Ansatz - oder Sie haben ein separates Unterverzeichnis für jede Anwendung, die Sie haben. Süße Schizophrenie.

ZB Emacs-bezogene Auflistung von meinem ~ / Stow:

-> % ls ~/Stow | grep emacs
emacs 
emacs_from_scratch
spacemacs
hoodoo@T450s 2:46 [~]

Es gibt eine anfängliche Konfiguration, die ich brauchbar gemacht habe, eine "Ich bleibe bei den Standardeinstellungen" -Konfiguration und eine "Ich werde meine eigene rollen". Ich kann einfach jede dieser Funktionen ein- und ausschalten und habe immer alle zur Verfügung. Jedes Unterverzeichnis kann einen ganzen Baum relativ zu meinem ~ / haben, und es ist ziemlich praktisch zu mischen und abzugleichen.


Ich benutze Stow schon, wenn es passiert. Aber wie benutzt man es dafür? Sie können Ihre .emacs.d-Dateien nur dynamisch "scopen", indem Sie die gewünschte Datei mit stow ein- / auskoppeln. Laufen Sie jemals beide gleichzeitig? Wenn ja, denke ich, dass beide Emacs "besitzen" .emacs.d. Ich frage mich, ob das bei Dingen, die den Zustand dort speichern, einige Merkwürdigkeiten hervorrufen könnte, wie ich beispielsweise recentf, savehist, autosave usw. nicht kenne, besonders wenn die beiden Kopien von Emacs mit radikal unterschiedlichen Konfigurationen ausgeführt werden.
Croad Langshan

Nein, ich ändere nur die Konfigurationen nach Bedarf.
Roman Grazhdan

2

Ich habe mir den Patch angesehen, den @Uwe Koloska verwendet hat. Es war nicht in der Hauptniederlassung enthalten. Ich stimme einigermaßen zu, ich denke, dass das Problem außerhalb von Emacs mit der Shell gelöst werden sollte und dass Emacs nichts davon wissen.

Vielleicht wäre diese Funktion aus Benutzersicht logischer, und die Verwendung eines Flags wäre für einige Benutzer weniger kompliziert.

In meinem Anwendungsfall möchte ich meine Emacs-Installation und Spacemacs beibehalten, damit meine Variation der beiden obigen Lösungen so funktioniert.

Shell-Skript

Zunächst das Skript zum Starten von Spacemacs:

#!/bin/sh

export EMACS_USER_DIR=~/spacemacs/emacs.d

exec emacs "$@"

Dieses Skript wird aufgerufen spacemacsund im /usr/local/binOrdner installiert .

.emacs Datei

Dann brauche ich eine .emacsDatei in meinem Home-Ordner, die die Umgebungsvariable richtig behandelt EMACS_USER_DIR.

(defvar user-custom-dir (getenv "EMACS_USER_DIR"))

(when (/= (length user-custom-dir) 0)
  (setq user-emacs-directory (file-name-as-directory user-custom-dir)))

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

Ich habe überhaupt keine Erfahrung mit Elisp, also bin ich auf dieses Thema gekommen. Erfahrene Leute könnten sich wahrscheinlich etwas Besseres einfallen lassen. Aber hey, es funktioniert.

Blickfang

Dann fügen Sie doch ein Icon hinzu:

Symbol

[Desktop Entry]
Name=Spacemacs
GenericName=Text Editor
Comment=Edit text
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
Exec=spacemacs %F
Icon=/home/marcs/.icons/spacemacs.svg
Type=Application
Terminal=false
Categories=Development;TextEditor;
StartupWMClass=Emacs
Keywords=Text;Editor;

3
Ihr Shell-Skript sollte verwenden exec emacs "$@".
Uwe Koloska

Ja, danke für den Tipp, nur behoben.
Marcs

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.