Запуск Spacemacs поряд із звичайними emacs: як зберегти окремий .emacs.d


32

Я хотів би спробувати космічні маки. Але я ще не хочу переходити від моєї звичайної конфігурації emacs, тому я хотів би, щоб конфігурація, яка зараз знаходиться в моєму, .emacs.dзнаходилася в одному каталозі, а еквівалентна конфігурація для Spacemacs знаходилася в іншій директорії. Я не заперечую, яке ім’я має жоден каталог.

Чи можливо це, не маючи chroots / LD_PRELOAD / інші подібні хитрощі? Як я можу це зробити?


2
Дивіться також відповідь Дена на аналогічне запитання, яке було у мене щодо налаштування таймера з параметрами, коли Emacs запускається: emacs.stackexchange.com/questions/3588/… я з тих пір використовую незначну варіацію відповіді.
законник

1
У категорії "інші хитрощі", можливо, ви можете створити симпосилання, що spacemacsвказує на виконуваний файл emacs, і скористатися значенням, (car command-line-args)щоб визначити, який файл init працювати. Це, звичайно, припускаючи, що ви працюєте в системі Unix, відмінній від ОС X. (Те, як пакети додатків працюють на OS X, цей трюк важко здійснити.)
Харальд Ханш-Олсен

1
Дивіться інший підхід тут: emacs.stackexchange.com/q/4253/780
glucas

2
Щойно я повернувся сказати, приблизно через 18 місяців, це все-таки причина, чому я не дізнався космонавтів. Тоді у мене було декілька проблем, пов'язаних з прийняттям відповіді, я просто спробував ще раз, як і раніше. Після додавання шару org зараз "Визначення функції Symbol є недійсним: цикл". Я не знаю, що це є причиною, але саме в цьому проблема: для відшліфованого проекту "включені батареї", здається дивним, що потрібно щось обмотати разом, щоб запустити його, а потім цікаво, чи підтримується моя конфігурація? Можливо, несправедливо, але це змушує мене втрачати довіру. Можливо, через 18 місяців це буде виправлено ...
Croad Langshan

Відповіді:


20

Один варіант - вказати, яку конфігурацію ви хочете завантажити у ~/.emacsфайл. Коли Emacs запускається, він шукатиме такий файл, перш ніж шукати ~/.emacs.d/. Детальніше про файл Init можна прочитати в посібнику Emacs.

Так, наприклад, ви можете створити ~/.spacemacs.dта зберегти існуючий ~/.emacs.dтаким, яким він є. Потім створіть, ~/.emacsщоб завантажити той, хто ви настрій користуватися:

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

Якщо ви хочете, ви можете придумати способи перемикання конфігурацій без зміни файлу .emacs. Наприклад, попросіть .emacs перевірити наявність змінної середовища, яку ви встановили в оболонці або в сценарії, який ви використовуєте для запуску пробілів:

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

1
Безумовно, повинен бути шлях зсередини elisp, щоб сказати, ти працюєш з Spacemacs чи ні? Наприклад, перевіривши (з fboundp) функцію чи команду, яка є унікальною для spacemacs?
Харальд Ханш-Олсен

2
Звичайно, але це не питання, як я це зрозумів. Spacemacs - це лише конфігурація emacs, і ОП хоче знати, як підтримувати більше ніж один незалежний dir config emacs.
глюкас

1
@ HaraldHanche-Olsen, який мене теж здивував, коли я його завантажив, але коли я подумав про це, він мав тотальний сенс. Я думаю, що причина, яку ми очікуємо, полягає в тому, що для більшості систем, щоб зробити відполірований "продукт", як Spacemacs, здається, необхідно розв'язати деякі системи систем нижчого рівня - але в emacs є така велика розширюваність (спасибі elisp) що це не потрібно.
Croad Langshan

1
Я прийняв це, але насправді цього не пробував. Тепер, коли я маю, це не зовсім працює як є: Помилка файлу: Неможливо відкрити завантажувальний файл, /home/me/.emacs.d/core/core-load-paths.el - мені (setq user-emacs-directory "~/.spacemacs.d/")це потрібно було робота (у а prognна умовному відгалуженні spacemacs). Чи можете ви додати це до своєї відповіді, щоб я міг прийняти її знову?
Croad Langshan

2
@glucas Я на win10, чомусь HOME був призначений c: / users / nate. Видалено змінну навколишнього середовища і все спрацювало нормально.
Натаніель Сакс

12

Оскільки на init можна зробити більше, ніж просто завантажувати файл, а з іншого боку, поєднуючи .emacs.dабо змінюючи HOMEзміни мого середовища виконання, я обрав варіант, який запропонував @glucas. Я використав код startup.elі додав патч від # 15539, щоб використовувати змінну середовища для переключення між різними init dirs. Якщо нічого не вказано, використовується типова умова.

Була одна проблема з spacemacs: asyncне знає про змінений каталог init і тому не може знайти потрібні файли. Але це було вирішено нещодавно у spacemacs: Помилка під час використання конфігураційного каталогу, відмінного від .emacs.d · Випуск № 3390

Тож ось мій, ~/.emacsякий повинен вести себе як оригінал init-коду, але з налаштованою каталогом init:

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

Існує також приємне доповнення, яке змушує його працювати як демон без зайвих зусиль: ім'я сервера буде встановлено на ім'я каталогу init. Тож тепер ви можете запустити другий демон emacs з ванільним spacemacs

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

і досі використовувати emacsclient

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

Мій шафа дуже простий, і я здивований, що я єдиний: у мене постійно працює демон emacs і використовую його від gui та через консоль (наприклад, з ssh). У цьому emacs я готую всю свою документацію та журнал роботи, тому він повинен бути там весь час. Але тоді я хочу спробувати spacemacs або один з інших пакетів розповсюдження і навіть налаштувати його, поки я не можу вийти зі своєї поточної конфігурації або використати деякі розумні ідеї. І як інші, я хотів створити просту базову конфігурацію для своїх колег - і документувати її в org-mode в моєму запущеному екземплярі.

Оскільки єдина проблема, про яку я знаю, - це asyncте, що вона не знає про змінений init dir, я думаю, що найкращий спосіб додати певну конфігурацію до asyncзмінних, які слід вводити за замовчуванням, так що не потрібно виправляти всі виклики так async-startсамо, як це робили Spacemacs.


Це дійсно чудово і прекрасно працювало ... поки мені не довелося користуватися async. :-( Оскільки минуло кілька місяців з моменту публікації, чи є у вас спосіб вирішення проблеми?
Трей

На жаль, ні - але для Spacemacs це фіксовано, і для загальної асинхронізації я не дуже впевнений, що там не повинно бути ніяких змін, тому що async-startзапускає emacs без нічого, і якщо ви хочете використовувати якусь змінну, вам доведеться її передати. Але, звичайно, це було б бути приємним і зручним, якщо async можна було налаштувати зі списком змінних, які будуть використовуватися при кожному виклику async-start.
Uwe Koloska

1
При такому підході можуть існувати й інші змінні, які ініціалізуються з каталогу-user-emacs за замовчуванням перед завантаженням .emacs. Наприклад, мені потрібно було додати (setq custom-theme-directory user-emacs-directory)сюди.
глюкас

1
Я не знаю, де встановлена ​​ця змінна, тому що, коли я розглядаю її всередині мінімального testenv, я отримую: її значення "~ / .emacs.d /". Первісне значення було "~ / .emacsenv.d / init-test /" Отже, воно має правильне значення, але це було перезаписано.
Уве Колоська

1
Я фактично закінчився використанням цієї відповіді, довго після того, як я задав це питання. Я не змінив прийняту відповідь, тому що це так довго і тому, що я насправді не приділяв великої уваги реалізації! Ця відповідь була дуже корисною для мене.
Croad Langshan

5

Це пояснюється тут , і існує постійний піар, щоб додати його до документації:

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

6
Так, я іноді змінюю HOME, щоб спробувати альтернативну конфігурацію. Мінусом є те, що HOME використовується для інших речей, на які, можливо, ви не хочете впливати.
глюкас

3

На це вже відповіли і прийнято, але якщо ви хочете спробувати нові способи робити речі зворотним шляхом (крім конфігурацій emacs), я б рекомендував вам витратити півгодини на ознайомлення з GNU Stow. Це на зразок ln -sстероїдів, і для їх використання може бути кілька підходів. Ви можете мати всю установку в одному підкаталозі (включаючи конфігурації offlineimap, конфігурації emacs тощо) - це підхід, заснований на оточенні, - або мати окремий підкаталог для кожної програми, що є у вас. Солодка шизофренія.

Наприклад, список, пов'язаний з emacs, з мого ~ / Stow:

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

Є одна початкова конфігурація, яку мені вдалося зробити корисною, одна конфігурація "Я дотримуюсь значень за замовчуванням" та одна "Я буду прокручувати свою". Я можу просто включати та вимикати кожен із них та завжди мати їх у наявності. Кожен підрозділ може мати ціле дерево відносно мого ~ /, і це дуже зручно змішувати та співставляти.


Я використовую stow вже як це відбувається. Але як ви це використовуєте для цього? Ви просто "динамічно простежуєте" свій .emacs.d, посилаючись на / виходячи з того, який ви хочете використовувати, використовуючи stow? Ви коли-небудь бігаєте обом одночасно? Якщо так, я думаю, обидва emacses вважають, що вони "володіють" .emacs.d. Цікаво, чи це може спричинити якісь дивацтва з речами, які зберігають там стан, як я не знаю, скажімо, у недавньому, сохраненні, автозбереженні тощо, особливо коли дві копії emacs працюють із радикально різними конфігураціями?
Croad Langshan

Ні, я просто перемикаю конфігурації за потребою.
Роман Граждан

2

Я перевірив патч, який використовував @Uwe Koloska. Він не входив до основної галузі. Я дещо згоден, я думаю, що проблему слід вирішити поза emacs, використовуючи оболонку, і залишаючи emacs нічого про це не знати.

Можливо, ця функція буде більш логічною з точки зору користувача, використання прапора було б менш заплутаним для деяких користувачів.

У моєму випадку я хочу зберегти свою установку Emacs та Spacemacs, щоб моя варіація двох вищезазначених рішень працює так.

скрипт оболонки

Перш за все сценарій запуску пробілів:

#!/bin/sh

export EMACS_USER_DIR=~/spacemacs/emacs.d

exec emacs "$@"

Цей скрипт називається spacemacsі встановлюється в /usr/local/binпапку.

файл .emacs

Тоді мені потрібен .emacsфайл у моїй домашній папці, який би правильно ставився до змінної середовища 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))

Я взагалі не відчуваю еліпса, тому я придумав це, більш досвідчені люди, можливо, можуть придумати щось краще. Але ей, це працює.

Eye Candy

Тоді чому б не додати значок:

значок

[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
Ваш сценарій оболонки повинен використовувати exec emacs "$@".
Уве Колоська

Так, спасибі за підказку, щойно виправлено.
Маркс

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.