Esecuzione di navicelle spaziali insieme a emac regolari: come mantenere un .emacs.d separato


32

Vorrei provare i spacemacs. Ma non voglio ancora passare dalla mia normale configurazione di emacs, quindi vorrei che la configurazione che è attualmente nella mia .emacs.dsia in una directory, e la configurazione equivalente per spacemacs sia in un'altra directory. Non mi importa quale sia il nome di entrambe le directory.

È possibile, a corto di chroot / LD_PRELOAD / altri trucchi del genere? Come posso farlo?


2
Vedi anche la risposta di Dan a una domanda simile che ho avuto riguardo all'impostazione di un timer con opzioni all'avvio di Emacs: emacs.stackexchange.com/questions/3588/… Da allora utilizzo una leggera variazione di quella risposta.
elenco delle leggi del

1
Nella categoria di "altri trucchi", forse, potresti creare un link simbolico che spacemacspunta all'eseguibile di emacs e usare il valore di (car command-line-args)per decidere quale file init eseguire. Ciò presuppone, ovviamente, che tu stia eseguendo un sistema unix diverso da OS X. (Il modo in cui i bundle di app funziona su OS X rende difficile eseguire questo trucco.)
Harald Hanche-Olsen

1
Guarda un altro approccio qui: emacs.stackexchange.com/q/4253/780
glucas,

2
Sono appena tornato per dire, circa 18 mesi dopo, questo è ancora il motivo per cui non ho imparato i veicoli spaziali. Ho avuto alcuni problemi fastidiosi con la risposta accettata, quindi, ho appena provato di nuovo, ancora vero. Dopo aver aggiunto il livello organizzativo ottenuto "La definizione della funzione del simbolo è nulla: loop" proprio ora. Non so che questo è parte della causa, ma questo è esattamente il problema: per un progetto lucido "batterie incluse", sembra strano dover mettere insieme qualcosa per avviarlo, quindi chiedersi se la mia configurazione è supportata? Forse ingiusto, ma questo mi fa perdere la fiducia. Forse tra altri 18 mesi verrà risolto ...
Croad Langshan il

Risposte:


20

Un'opzione è specificare quale configurazione si desidera caricare in un ~/.emacsfile. All'avvio di Emacs cercherà tale file prima di cercare ~/.emacs.d/. Per maggiori dettagli puoi leggere sull'Init File nel manuale di Emacs.

Quindi, ad esempio, potresti creare un ~/.spacemacs.de mantenere il tuo esistente ~/.emacs.dcosì com'è. Quindi crea un ~/.emacsper caricare quello che ti va di usare:

(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))

Se lo desideri, puoi trovare modi per cambiare configurazione senza modificare il file .emacs. Ad esempio, fai controllare a .emacs alcune variabili d'ambiente che hai impostato nella tua shell o in uno script che usi per avviare spacemacs:

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

1
Sicuramente, ci deve essere un modo dall'interno di elisp per dire se stai gestendo navicelle spaziali o no? Ad esempio, controllando (con fboundp) una funzione o un comando univoco per i veicoli spaziali?
Harald Hanche-Olsen,

2
Certo, ma non era questa la domanda per come l'ho capito. Spacemacs è solo una configurazione di emacs e l'OP vuole sapere come mantenere più di una directory di configurazione di emacs indipendente.
Glucas,

1
@ HaraldHanche-Olsen che mi ha sorpreso anche quando l'ho scaricato, ma quando ci ho pensato aveva perfettamente senso. Penso che il motivo per cui ci aspettiamo che sia che per la maggior parte dei sistemi, per rendere un 'prodotto' raffinato come le navicelle spaziali sembra essere necessario, è necessario estrarre un linguaggio di sistema di livello inferiore - ma in emacs c'è tanta estensibilità (grazie elisp) quello non è necessario.
Croad Langshan,

1
Ho accettato questo, ma in realtà non l'ho provato. Ora che ho, lo fa non proprio lavoro così come sono: Errore File: Impossibile archiviare carico aperto, /home/me/.emacs.d/core/core-load-paths.el - avevo bisogno di (setq user-emacs-directory "~/.spacemacs.d/")per la sua lavoro (in a prognsul ramo di spacemacs del tuo condizionale). Puoi aggiungerlo alla tua risposta in modo che io possa accettarla di nuovo?
Croad Langshan,

2
@glucas Sono su win10, per qualche ragione HOME è stata assegnata a c: / users / nate. Rimossa la variabile ambientale e tutto ha funzionato bene.
Nathaniel Saxe,

12

Dato che c'è molto altro da fare su init oltre al semplice caricamento di un file e d'altra parte il collegamento simbolico .emacs.do la modifica dei HOMEcambiamenti nel mio ambiente di runtime, ho optato per una variante di quanto proposto da @glucas. Ho usato il codice da startup.ele ho aggiunto la patch da # 15539 per usare una variabile d'ambiente per passare da una directory di init all'altra. Se non ne viene fornito nessuno, viene utilizzato il valore predefinito.

C'è stato un problema con spacemacs: asyncnon conosce la directory init cambiata e quindi non riesce a trovare alcuni file necessari. Ma questo è stato risolto di recente in spacemacs: errore durante l'utilizzo di una directory di configurazione diversa da .emacs.d · Problema # 3390

Quindi ecco il mio ~/.emacsche dovrebbe comportarsi come il codice di inizializzazione originale ma con la directory init configurabile:

;;; .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

C'è anche una bella aggiunta che lo fa funzionare come demone senza ulteriore sforzo: il nome del server verrà impostato sul nome della directory init. Quindi ora puoi avviare un secondo demone emacs con un spacemacs alla vaniglia

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

e usa ancora emacsclient

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

Il mio caso d'uso è molto semplice e mi stupisco di essere l'unico: ho un demone emacs sempre in esecuzione e lo uso dalla GUI e dalla console (con ssh per esempio). In questo emacs preparo tutta la mia documentazione e il registro di lavoro, quindi deve essere sempre presente. Ma poi voglio provare spacemacs o uno degli altri pacchetti di distribuzione e persino configurarlo, fino a quando posso ritirare la mia configurazione attuale o usare alcune delle idee intelligenti. E come altri, volevo creare una semplice configurazione di base per i miei colleghi e documentarla con la modalità org nella mia istanza corrente.

Poiché l'unico problema che conosco è asynce che non è a conoscenza della directory init cambiata, penso al modo migliore per aggiungere una configurazione a asynccui sono presenti variabili che dovrebbero essere iniettate per impostazione predefinita, quindi non è necessario applicare patch a tutto invocazioni async-startproprio come avevano fatto i veicoli spaziali.


Questo è davvero adorabile e ha funzionato magnificamente ... fino a quando non ho dovuto usarlo async. :-( Dato che sono passati alcuni mesi da quando hai pubblicato, hai una soluzione alternativa?
Trey

Sfortunatamente no - ma per i spacemac è riparato e per il generale asincrono non sono davvero sicuro che ci debba essere qualche cambiamento, perché async-startavvia emacs senza nulla e se vuoi usare qualche variabile devi passarla. essere gentile e conveniente, se asincrono potrebbe essere configurato con un elenco di variabili, che verranno utilizzate su ogni invocazione di async-start.
Uwe Koloska,

1
Con questo approccio, potrebbero esserci altre variabili che vengono inizializzate dalla directory user-emacs predefinita prima che il tuo .emacs venga caricato. Ad esempio, dovevo aggiungere (setq custom-theme-directory user-emacs-directory)qui.
glucas,

1
Non so dove sia impostata questa variabile, perché quando la esamino in un testenv minimo, ottengo: Il suo valore è "~ / .emacs.d /". Il valore originale era "~ / .emacsenv.d / init-test /" Quindi ha il valore giusto, ma questo è stato sovrascritto.
Uwe Koloska,

1
In realtà ho finito per usare questa risposta, molto tempo dopo aver posto la domanda. Non ho cambiato la risposta accettata perché è così lunga e perché non ho prestato molta attenzione all'implementazione! Questa risposta mi è stata molto utile, comunque.
Croad Langshan,

5

È spiegato qui e c'è un PR in corso per aggiungerlo alla documentazione:

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

6
Sì, a volte cambio HOME per provare una configurazione alternativa. Il rovescio della medaglia è che HOME viene utilizzato per altre cose che potresti preferire non influenzare.
glucas,

3

Ha già ricevuto risposta e accettato, ma se hai voglia di provare nuovi modi di fare le cose in modo reversibile (al di là di emacs configs) ti consiglio di passare mezz'ora a familiarizzare con GNU Stow. È una specie di ln -ssteroidi e potrebbero esserci diversi approcci per usarlo. Puoi avere l'intero setup in una sottodirectory (incluse le configurazioni offlineimap, emacs configs ecc.) - che sarebbe un approccio basato sull'ambiente - o avere una sottodirectory separata per ogni applicazione che hai. Schizofrenia dolce

Ad esempio un elenco relativo a emacs dal mio ~ / Stow:

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

C'è una configurazione iniziale che sono riuscito a rendere utilizzabile, una "Configura con le impostazioni predefinite" e una "Sto andando a fare il mio". Posso solo accendere e spegnere ciascuno di questi e averli sempre disponibili. Ogni sottodireato può avere un intero albero rispetto al mio ~ / ed è abbastanza utile da mescolare e abbinare.


Uso lo stow già come succede. Ma come lo usi per questo? Stai semplicemente 'scoping dinamicamente' il tuo .emacs.d collegando in / out quello che vuoi usare, usando stow? Hai mai corso entrambi contemporaneamente? Se è così, immagino che entrambe le emacse pensino di "possedere" .emacs.d. Mi chiedo se ciò potrebbe causare alcune stranezze con cose che salvano lo stato lì, come non so dire recentf, savehist, autosave, ecc. Specialmente quando le due copie di emacs sono in esecuzione con configurazioni radicalmente diverse?
Croad Langshan,

No, cambio semplicemente le configurazioni secondo necessità.
Roman Grazhdan,

2

Ho verificato la patch utilizzata da @Uwe Koloska. Non è stato incluso nel ramo principale. Sono un po 'd'accordo, penso che il problema dovrebbe essere risolto al di fuori di emacs usando la shell e lasciando che emacs non ne sappia nulla.

Forse quella caratteristica sarebbe più logica dal punto di vista dell'utente, l'uso di un flag sarebbe meno contorto per alcuni utenti.

Nel mio caso d'uso voglio mantenere l'installazione di Emacs e Spacemacs modo che la mia variazione delle due soluzioni sopra questo modo.

script di shell

Prima di tutto la sceneggiatura per il lancio di spacemacs:

#!/bin/sh

export EMACS_USER_DIR=~/spacemacs/emacs.d

exec emacs "$@"

Questo script viene chiamato spacemacsed è installato in/usr/local/bin cartella.

.emacs file

Quindi ho bisogno di un .emacsfile nella mia cartella home che tratterà correttamente la variabile di ambiente 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))

Non ho alcuna esperienza con gli elis, quindi ho pensato a questo, le persone più esperte potrebbero probabilmente trovare qualcosa di meglio. Ma hey, funziona.

Eye-candy

Quindi perché non aggiungere un'icona:

icona

[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
Lo script della shell dovrebbe usare exec emacs "$@".
Uwe Koloska,

Sì, grazie per il suggerimento, appena risolto.
March

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.