Chạy spacemacs cùng với emacs thông thường: cách giữ một .emacs.d riêng biệt


32

Tôi muốn thử spacemacs. Nhưng tôi chưa muốn chuyển từ cấu hình emacs thông thường của mình, vì vậy tôi muốn cấu hình hiện .emacs.dcó trong một thư mục và cấu hình tương đương cho các spacemac nằm trong một thư mục khác. Tôi không nhớ tên thư mục này có gì.

Điều đó có thể không, thiếu chroots / LD_PRELOAD / những mánh khóe như vậy? Tôi làm nó như thế nào?


2
Xem thêm câu trả lời của Dan cho một câu hỏi tương tự mà tôi có về việc thiết lập bộ đếm thời gian với các tùy chọn khi Emacs bắt đầu: emacs.stackexchange.com/questions35388/ọ Tôi đã sử dụng một biến thể nhỏ của câu trả lời đó kể từ đó.
luật

1
Trong danh mục của trò lừa đảo khác, có lẽ, bạn có thể tạo một liên kết tượng trưng spacemacscho các emacs thực thi và sử dụng giá trị của (car command-line-args)để quyết định tập tin init nào sẽ chạy. Tất nhiên, điều này là giả sử rằng bạn đang chạy trên một hệ thống unix khác với OS X. (Cách các gói ứng dụng hoạt động trên OS X khiến cho thủ thuật này khó thực hiện.)
Harald Hanche-Olsen 2/2/2016

1
Xem một cách tiếp cận khác tại đây: emacs.stackexchange.com/q/4253/780
glucas

2
Tôi vừa trở lại để nói, khoảng 18 tháng sau, đây vẫn là lý do tôi chưa học spacemacs. Tôi đã có một vài vấn đề rắc rối với câu trả lời được chấp nhận sau đó, chỉ cần thử lại, vẫn đúng. Sau khi thêm lớp org, "Định nghĩa hàm của Symbol là void: loop" ngay bây giờ. Tôi không BIẾT đây là một phần nguyên nhân, nhưng đó chính xác là vấn đề: Đối với một dự án "bao gồm pin" được đánh bóng, có vẻ kỳ quặc khi phải ghép một cái gì đó lại với nhau chỉ để BẮT ĐẦU, sau đó tự hỏi liệu cấu hình của tôi có được hỗ trợ không? Có lẽ không công bằng nhưng điều đó khiến tôi mất niềm tin. Có thể trong 18 tháng nữa, nó sẽ được sửa chữa ...
Croad Langshan

Câu trả lời:


20

Một tùy chọn là chỉ định cấu hình nào bạn muốn tải trong một ~/.emacstệp. Khi Emacs khởi động, nó sẽ tìm một tập tin như vậy trước khi tìm kiếm ~/.emacs.d/. Để biết thêm chi tiết, bạn có thể đọc về Tệp khởi đầu trong hướng dẫn sử dụng Emacs.

Vì vậy, ví dụ bạn có thể tạo một ~/.spacemacs.dvà giữ nguyên ~/.emacs.dnhư hiện tại . Sau đó tạo một ~/.emacsđể tải bất cứ ai bạn đang có tâm trạng sử dụng:

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

Nếu bạn muốn, bạn có thể đưa ra các cách để chuyển cấu hình mà không cần sửa đổi tệp .emacs. Ví dụ: yêu cầu .emacs kiểm tra một số biến môi trường mà bạn đặt trong trình bao hoặc trong tập lệnh mà bạn sử dụng để bắt đầu spacemacs:

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

1
Chắc chắn, phải có một cách từ bên trong elisp để biết bạn có đang chạy spacemacs hay không? Ví dụ, bằng cách kiểm tra (với fboundp) một chức năng hoặc lệnh duy nhất cho spacemacs?
Harald Hanche-Olsen

2
Chắc chắn, nhưng đó không phải là câu hỏi như tôi hiểu. Spacemacs chỉ là một cấu hình emacs và OP muốn biết cách duy trì nhiều hơn một dir cấu hình emacs độc lập.
glucas

1
@ HaraldHanche-Olsen cũng làm tôi ngạc nhiên khi tôi tải xuống, nhưng khi tôi nghĩ về nó, nó hoàn toàn có ý nghĩa. Tôi nghĩ lý do chúng tôi mong đợi là đối với hầu hết các hệ thống, để tạo ra một 'sản phẩm' giống như spacemacs dường như, cần phải xử lý một số ngôn ngữ hệ thống cấp thấp hơn - nhưng trong emacs có rất nhiều khả năng mở rộng (cảm ơn là cần thiết) điều đó không cần thiết
Croad Lang Sơn

1
Tôi đã chấp nhận điều này, nhưng thực sự đã không thử nó. Bây giờ tôi có, nó không hoạt động hoàn toàn như: Lỗi tệp: Không thể mở tệp tải, /home/me/.emacs.d/core/core-load-paths.el - Tôi cần để (setq user-emacs-directory "~/.spacemacs.d/")nó làm việc (trong một prognnhánh spacemacs của điều kiện của bạn). Bạn có thể thêm nó vào câu trả lời của bạn để tôi có thể chấp nhận nó một lần nữa không?
Croad Lang Sơn

2
@glucas Tôi đang dùng win10, vì một số lý do HOME được gán cho c: / users / nate. Loại bỏ các biến môi trường và mọi thứ hoạt động tốt.
Nathaniel Saxe

12

Vì có nhiều việc phải làm trên init hơn là chỉ tải một tệp và mặt khác là liên kết .emacs.dhoặc thay đổi thay HOMEđổi môi trường thời gian chạy của tôi, tôi đã chọn một biến thể của những gì @glucas đã đề xuất. Tôi đã sử dụng mã từ startup.elvà thêm bản vá từ # 15539 để sử dụng biến môi trường để chuyển đổi giữa các thư mục init khác nhau. Nếu không được đưa ra, mặc định được sử dụng.

Có một vấn đề với spacemacs: asynckhông biết về thư mục init đã thay đổi và vì vậy không thể tìm thấy một số tệp cần thiết. Nhưng điều này đã được giải quyết trong spacemacs gần đây: Lỗi khi sử dụng thư mục cấu hình khác với .emacs.d · Vấn đề # 3390

Vì vậy, đây là của tôi ~/.emacsnên hoạt động như mã init ban đầu nhưng với thư mục init có thể cấu hình:

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

Ngoài ra còn có một bổ sung thú vị làm cho nó hoạt động như một daemon mà không cần nỗ lực thêm: tên máy chủ sẽ được đặt thành tên của thư mục init. Vì vậy, bây giờ bạn có thể bắt đầu một daemon thứ hai với một spacemacs vani

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

và vẫn sử dụng emacsclient

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

Usecase của tôi rất đơn giản và tôi rất ngạc nhiên, tôi là người duy nhất: Tôi có một trình nền emacs luôn chạy và sử dụng nó từ gui và trên bảng điều khiển (ví dụ với ssh). Trong emacs này, tôi chuẩn bị tất cả tài liệu và nhật ký công việc của mình, vì vậy nó phải ở đó mọi lúc. Nhưng sau đó tôi muốn dùng thử spacemacs hoặc một trong các gói phân phối khác và thậm chí định cấu hình nó, cho đến khi tôi có thể rút lại cấu hình hiện tại của mình hoặc sử dụng một số ý tưởng thông minh. Và như những người khác, tôi muốn tạo một cấu hình cơ bản đơn giản cho đồng nghiệp của mình - và ghi lại nó với chế độ org trong ví dụ chạy của tôi.

Vì vấn đề duy nhất tôi biết là asyncvà nó không biết về init dir đã thay đổi, tôi nghĩ về cách tốt nhất để thêm một số cấu hình vào asyncđó có các biến nên được chèn theo mặc định, do đó không cần thiết phải vá tất cả yêu cầu của async-startspacemacs đã làm.


Điều này thực sự đáng yêu và hoạt động rất đẹp ... cho đến khi tôi cần sử dụng async. :-( Vì đã được vài tháng kể từ khi bạn đăng bài, bạn có cách giải quyết không?
Trey

Thật không may là không - nhưng đối với spacemacs thì nó đã được sửa và đối với async nói chung, tôi không thực sự chắc chắn rằng phải có bất kỳ thay đổi nào, bởi vì async-startbắt đầu emacs mà không có gì và nếu bạn muốn sử dụng một số biến bạn phải chuyển nó vào. Nhưng chắc chắn, nó sẽ thật hay và tiện lợi, nếu async có thể được cấu hình với một danh sách các biến, nó sẽ được sử dụng cho mỗi lần gọi async-start.
Uwe Koloska

1
Với cách tiếp cận này, có thể có các biến khác được khởi tạo từ thư mục người dùng mặc định trước khi .emacs của bạn được tải. Ví dụ tôi cần thêm (setq custom-theme-directory user-emacs-directory)vào đây.
glucas

1
Tôi không biết biến này được đặt ở đâu, bởi vì khi tôi kiểm tra nó trong một testenv tối thiểu, tôi nhận được: Giá trị của nó là "~ / .emacs.d /". Giá trị ban đầu là "~ / .emacsenv.d / init-test /" Vì vậy, nó có giá trị đúng, nhưng điều này đã bị ghi đè.
Uwe Koloska

1
Tôi thực sự đã kết thúc bằng cách sử dụng câu trả lời này, rất lâu sau khi tôi đặt câu hỏi. Tôi đã không thay đổi câu trả lời được chấp nhận vì nó quá dài và vì tôi thực sự không chú ý đến việc thực hiện! Câu trả lời này rất hữu ích với tôi.
Croad Lang Sơn

5

Nó được giải thích ở đây và có một PR liên tục để thêm nó vào tài liệu:

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

6
Có, đôi khi tôi thay đổi HOME để thử cấu hình thay thế. Nhược điểm là HOME được sử dụng cho những thứ khác mà bạn có thể không muốn ảnh hưởng.
glucas

3

Nó đã được trả lời và chấp nhận, nhưng nếu bạn muốn thử những cách mới để thực hiện mọi thứ theo cách có thể đảo ngược (ngoài cấu hình emacs), tôi khuyên bạn nên dành nửa giờ để làm quen với GNU Stow. Đó là loại ln -ssteroid, và có thể có một số cách tiếp cận để sử dụng nó. Bạn có thể có toàn bộ thiết lập trong một thư mục con (bao gồm cấu hình offlineimap, cấu hình emacs, v.v.) - đó là cách tiếp cận dựa trên môi trường - hoặc có một thư mục con riêng cho mọi ứng dụng bạn có. Tâm thần phân liệt ngọt ngào.

Ví dụ: danh sách liên quan đến emacs từ my ~ / Stow:

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

Có một cấu hình ban đầu tôi đã quản lý để có thể sử dụng được, một cấu hình 'Tôi gắn bó với cấu hình mặc định' và một cấu hình 'Tôi sẽ tự lăn'. Tôi chỉ có thể bật và tắt từng cái trong số này và luôn có sẵn tất cả chúng. Mỗi thư mục con có thể có toàn bộ cây tương ứng với ~ / và nó rất tiện để trộn và kết hợp.


Tôi đã sử dụng stow đã như nó xảy ra. Nhưng làm thế nào để bạn sử dụng nó cho việc này? Bạn chỉ đang 'tự động phân tích' .emacs.d của mình bằng cách liên kết vào / ra cái bạn muốn sử dụng, sử dụng stow? Bạn có bao giờ chạy cả hai cùng một lúc? Nếu vậy, tôi đoán cả hai emacodes nghĩ rằng chúng "sở hữu" .emacs.d. Tôi tự hỏi nếu điều đó có thể gây ra một số điều kỳ lạ với những thứ lưu trạng thái ở đó, như tôi không biết nói gần đây, lưu trữ, tự động, v.v. đặc biệt là khi hai bản sao của emacs đang chạy với cấu hình hoàn toàn khác nhau?
Croad Lang Sơn

Không, tôi chỉ chuyển đổi cấu hình khi cần thiết.
Roman Grazhdan

2

Tôi đã kiểm tra bản vá mà @Uwe Koloska đã sử dụng. Nó không được bao gồm trong chi nhánh chính. Tôi phần nào đồng ý, tôi nghĩ rằng vấn đề nên được giải quyết bên ngoài emacs bằng cách sử dụng shell và để lại emacs không biết gì về nó.

Có thể tính năng đó sẽ hợp lý hơn từ góc độ người dùng, sử dụng cờ sẽ ít gây khó chịu hơn đối với một số người dùng.

Trong trường hợp sử dụng của tôi, tôi muốn giữ cài đặt Emacs và Spacemac của mình để biến thể của hai giải pháp trên hoạt động như thế này.

kịch bản shell

Trước hết, kịch bản để khởi chạy spacemacs:

#!/bin/sh

export EMACS_USER_DIR=~/spacemacs/emacs.d

exec emacs "$@"

Kịch bản này được gọi spacemacsvà được cài đặt trong /usr/local/binthư mục.

tập tin .emacs

Sau đó, tôi cần một .emacstập tin trong thư mục nhà của tôi sẽ xử lý đúng biến môi trường 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))

Tôi hoàn toàn không có kinh nghiệm với elisp vì vậy tôi đã nghĩ ra điều này, những người có kinh nghiệm hơn có thể nghĩ ra thứ gì đó tốt hơn. Nhưng này, nó hoạt động.

Mắt ngọt ngào

Vậy thì tại sao không thêm một biểu tượng:

biểu tượng

[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
Kịch bản shell của bạn nên sử dụng exec emacs "$@".
Uwe Koloska

Vâng, cảm ơn vì tiền boa, chỉ cần sửa.
Marcs

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.