Menjalankan spacemac bersama emacs biasa: bagaimana cara membuat .emacs.d terpisah

32

Saya ingin mencoba ruang angkasa. Tapi saya belum mau beralih dari konfigurasi emacs biasa saya, jadi saya ingin konfigurasi yang saat ini ada di saya .emacs.dberada di satu direktori, dan konfigurasi yang setara untuk spacemac berada di direktori lain. Saya tidak keberatan nama apa yang dimiliki kedua direktori.

Apakah itu mungkin, kekurangan chroots / LD_PRELOAD / tipuan lainnya? Bagaimana saya bisa melakukannya?

Langshan Croad
sumber
2
Lihat juga jawaban Dan untuk pertanyaan serupa yang saya miliki tentang pengaturan penghitung waktu dengan opsi ketika Emacs dimulai: emacs.stackexchange.com/questions/3588/... Saya telah menggunakan sedikit variasi dari jawaban itu sejak saat itu.
lawlist
1
Dalam kategori "tipuan lain", mungkin, Anda bisa membuat symlink yang spacemacsmenunjuk ke emacs yang dapat dieksekusi dan menggunakan nilai (car command-line-args)untuk memutuskan file init mana yang akan dijalankan. Ini dengan asumsi, tentu saja, bahwa Anda menjalankan sistem unix selain OS X. (Cara bundel aplikasi bekerja pada OS X membuat trik ini sulit dilakukan.)
Harald Hanche-Olsen
1
Lihat pendekatan lain di sini: emacs.stackexchange.com/q/4253/780
glucas
2
Saya baru saja kembali untuk mengatakan, sekitar 18 bulan kemudian, ini masih menjadi alasan saya belum belajar ruang angkasa. Saya punya beberapa masalah dengan jawaban yang diterima kemudian, hanya mencoba lagi, masih benar. Setelah menambahkan lapisan org mendapat "Definisi fungsi simbol adalah void: loop" tadi. Saya tidak TAHU ini adalah bagian dari penyebabnya, tetapi justru itulah masalahnya: Untuk proyek "baterai termasuk" yang dipoles, rasanya aneh harus merobohkan sesuatu hanya untuk MULAI saja, lalu bertanya-tanya apakah konfigurasi saya didukung? Mungkin tidak adil tetapi itu membuat saya kehilangan kepercayaan. Mungkin dalam 18 bulan lagi akan diperbaiki ...
Croad Langshan

Jawaban:

20

Salah satu opsi adalah menentukan konfigurasi mana yang ingin Anda muat dalam ~/.emacsfile. Ketika Emacs mulai, itu akan mencari file seperti itu sebelum melihat ~/.emacs.d/. Untuk lebih jelasnya Anda bisa membaca tentang File Init di manual Emacs.

Jadi misalnya Anda dapat membuat ~/.spacemacs.ddan mempertahankan keberadaan Anda ~/.emacs.dapa adanya. Lalu buat a ~/.emacsuntuk memuat mana yang Anda inginkan:

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

Jika mau, Anda dapat menemukan cara untuk beralih konfigurasi tanpa mengubah file .emacs. Misalnya, minta .emacs Anda memeriksa beberapa variabel lingkungan yang Anda atur di shell Anda atau dalam skrip yang Anda gunakan untuk memulai spacemacs:

(setq use-spacemacs (getenv "USE_SPACEMACS"))
glukas
sumber
1
Tentunya, harus ada cara dari dalam elisp untuk mengetahui apakah Anda menjalankan spacemacs atau tidak? Misalnya, dengan memeriksa (dengan fboundp) untuk suatu fungsi atau perintah yang unik untuk spacemacs?
Harald Hanche-Olsen
2
Tentu, tapi itu bukan pertanyaan yang saya mengerti. Spacemacs hanyalah konfigurasi emacs, dan OP ingin tahu cara mempertahankan lebih dari satu konfigurasi emacs independen.
glukas
1
@ HaraldHanche-Olsen yang mengejutkan saya juga ketika saya mengunduhnya, tetapi ketika saya memikirkannya, itu masuk akal. Saya pikir alasan yang kami harapkan adalah bahwa untuk sebagian besar sistem, untuk membuat 'produk' yang dipoles seperti spacemac tampaknya diperlukan, perlu untuk mengeluarkan beberapa bahasa sistem tingkat yang lebih rendah - tetapi di emacs ada banyak kemungkinan diperpanjang (terima kasih elisp) itu tidak perlu.
Croad Langshan
1
Saya menerima ini, tetapi belum benar-benar mencobanya. Sekarang yang saya miliki, itu tidak berfungsi sebagaimana mestinya: Kesalahan file: Tidak dapat membuka memuat file, /home/me/.emacs.d/core/core-load-paths.el - saya perlu melakukannya (setq user-emacs-directory "~/.spacemacs.d/")untuk bekerja (di progncabang ruang angkasa bersyarat Anda). Bisakah Anda menambahkan itu ke jawaban Anda sehingga saya bisa menerimanya lagi?
Croad Langshan
2
@ glucas aku di win10, untuk beberapa alasan HOME ditugaskan untuk c: / users / nate. Menghapus variabel lingkungan dan semuanya bekerja dengan baik.
Nathaniel Saxe
12

Karena ada lebih banyak yang harus dilakukan di init daripada hanya memuat file dan di sisi lain symlinking .emacs.datau mengubah HOMEperubahan lingkungan runtime saya, saya memilih varian dari apa yang telah diusulkan @glucas. Saya menggunakan kode dari startup.eldan menambahkan tambalan dari # 15539 untuk menggunakan variabel lingkungan untuk beralih antara dir init yang berbeda. Jika tidak ada yang diberikan, default digunakan.

Ada satu masalah dengan spacemacs: asynctidak tahu tentang direktori init yang diubah sehingga tidak dapat menemukan beberapa file yang diperlukan. Tapi ini telah diselesaikan di spacemacs baru-baru ini: Kesalahan saat menggunakan direktori config selain .emacs.d · Masalah # 3390

Jadi inilah saya ~/.emacsyang harus berperilaku seperti init-code asli tetapi dengan direktori init yang dapat dikonfigurasi:

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

Ada juga tambahan yang bagus yang membuatnya berfungsi sebagai daemon tanpa usaha ekstra: nama server akan ditetapkan ke nama direktori init. Jadi sekarang Anda dapat memulai daemon emacs kedua dengan vanilla spacemacs

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

dan masih menggunakan emacsclient

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

Penggunaan saya sangat sederhana dan saya heran, bahwa saya adalah satu-satunya: Saya memiliki daemon emacs yang selalu berjalan dan menggunakannya dari gui dan konsol (dengan ssh misalnya). Dalam emacs ini saya menyiapkan semua dokumentasi dan log kerja saya, jadi harus selalu ada di sana. Tetapi kemudian saya ingin mencoba spacemacs atau salah satu paket distribusi lainnya dan bahkan mengkonfigurasinya, hingga saya dapat menghentikan konfigurasi saya saat ini atau menggunakan beberapa ide pintar. Dan seperti yang lain, saya ingin membuat konfigurasi basis sederhana untuk rekan kerja saya - dan mendokumentasikannya dengan mode-org dalam menjalankan contoh saya.

Karena satu-satunya masalah yang saya tahu adalah asyncdan tidak tahu tentang dir init yang diubah, saya berpikir tentang cara terbaik untuk menambahkan beberapa konfigurasi ke asyncyang memiliki variabel yang harus disuntikkan secara default, sehingga tidak perlu menambal semua doa async-startseperti yang dilakukan ruang angkasa.

Uwe Koloska
sumber
Ini sangat indah dan bekerja dengan indah ... sampai saya perlu menggunakannya async. :-( Karena sudah beberapa bulan sejak Anda diposting, apakah Anda punya solusinya?
Trey
Sayangnya tidak - tetapi untuk spacemacs sudah diperbaiki dan untuk umum async saya tidak begitu yakin apakah harus ada perubahan, karena async-startmemulai emacs tanpa apa-apa dan jika Anda ingin menggunakan beberapa variabel Anda harus meneruskannya. Tapi tentu saja, itu akan bersikap baik dan nyaman, jika async dapat dikonfigurasi dengan daftar variabel, yang akan digunakan pada setiap permintaan async-start.
Uwe Koloska
1
Dengan pendekatan ini, mungkin ada variabel lain yang diinisialisasi dari direktori user-emacs default sebelum .emacs Anda dimuat. Misalnya saya perlu menambahkan di (setq custom-theme-directory user-emacs-directory)sini.
glucas
1
Saya tidak tahu di mana variabel ini diatur, karena ketika saya memeriksanya di dalam testenv minimal, saya mendapatkan: Nilainya "~ / .emacs.d /". Nilai asli adalah "~ / .emacsenv.d / init-test /" Jadi memiliki nilai yang tepat, tetapi ini ditimpa.
Uwe Koloska
1
Saya akhirnya menggunakan jawaban ini, lama setelah saya mengajukan pertanyaan. Saya belum mengubah jawaban yang diterima karena sudah lama dan karena saya belum terlalu memperhatikan implementasi! Namun, jawaban ini sangat berguna bagi saya.
Croad Langshan
5

Dijelaskan di sini , dan ada PR yang sedang berlangsung untuk menambahkannya ke dokumentasi:

mkdir ~/spacemacs
git clone [email protected]:syl20bnr/spacemacs.git ~/spacemacs/.emacs.d
HOME=~/spacemacs emacs```
StreakyCobra
sumber
6
Ya, saya terkadang mengganti HOME untuk mencoba konfigurasi alternatif. Kelemahannya adalah bahwa HOME digunakan untuk hal-hal lain yang Anda pilih untuk tidak memengaruhi.
glukas
3

Sudah dijawab dan diterima, tetapi jika Anda merasa ingin mencoba cara-cara baru dalam melakukan sesuatu dengan cara yang dapat dibalikkan (di luar emacs konfigurasi) saya sarankan Anda menghabiskan setengah jam membiasakan diri dengan GNU Stow. Ini semacam ln -ssteroid, dan mungkin ada beberapa pendekatan untuk menggunakannya. Anda dapat memiliki seluruh pengaturan di bawah satu subdirektori (termasuk konfigurasi offlineimap, konfigurasi emacs dll.) - yang akan menjadi pendekatan berbasis lingkungan - atau memiliki subdirektori terpisah untuk setiap aplikasi yang Anda miliki. Skizofrenia manis.

Misalnya listing terkait emacs dari my ~ / Stow:

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

Ada satu konfigurasi awal yang berhasil saya gunakan, satu konfigurasi 'Saya tetap menggunakan default' dan satu 'saya akan roll sendiri'. Saya hanya bisa menghidupkan dan mematikan masing-masing dan selalu memiliki semuanya. Setiap subdir dapat memiliki seluruh pohon relatif terhadap ~ saya dan cukup mudah untuk mencampur dan mencocokkan.

Roman Grazhdan
sumber
Saya sudah menggunakan stow saat itu terjadi. Tetapi bagaimana Anda menggunakannya untuk ini? Anda hanya 'secara dinamis membatasi' .emacs.d Anda dengan menghubungkan / keluar yang Anda ingin gunakan, menggunakan stow? Apakah Anda pernah menjalankan keduanya secara bersamaan? Jika demikian, saya kira kedua emacses berpikir mereka "memiliki" .emacs.d. Saya bertanya-tanya apakah itu dapat menyebabkan beberapa keanehan dengan hal-hal yang menyelamatkan keadaan di sana, seperti saya tidak tahu mengatakan recentf, savehist, autosave, dll. Terutama ketika dua salinan emacs berjalan dengan konfigurasi yang sangat berbeda?
Croad Langshan
Tidak, saya hanya mengganti konfigurasi sesuai kebutuhan.
Roman Grazhdan
2

Saya memeriksa patch yang digunakan @Uwe Koloska. Itu tidak termasuk dalam cabang utama. Saya agak setuju, saya pikir masalahnya harus diselesaikan di luar emacs menggunakan shell dan meninggalkan emacs tidak tahu apa-apa tentang itu.

Mungkin fitur itu akan lebih logis dari perspektif pengguna, menggunakan bendera akan kurang berbelit-belit untuk beberapa pengguna.

Dalam kasus penggunaan saya, saya ingin menyimpan instalasi Emacs dan Spacemacs saya sehingga variasi saya dari dua solusi di atas berfungsi seperti ini.

skrip shell

Pertama-tama skrip untuk meluncurkan spacemacs:

#!/bin/sh

export EMACS_USER_DIR=~/spacemacs/emacs.d

exec emacs "$@"

Script ini dipanggil spacemacsdan diinstal di /usr/local/binfolder.

File .emacs

Maka saya perlu .emacsfile di folder rumah saya yang akan memperlakukan variabel lingkungan dengan benar 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))

Saya tidak berpengalaman dengan elisp sama sekali jadi saya datang ini, lebih banyak orang yang berpengalaman mungkin bisa datang dengan sesuatu yang lebih baik. Tapi hei, itu berhasil.

Eye-candy

Lalu mengapa tidak menambahkan ikon:

ikon

[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;
Marcs
sumber
3
Script shell Anda harus digunakan exec emacs "$@".
Uwe Koloska
Ya, terima kasih atas tipnya, baru saja diperbaiki.
Marcs